valtech-components 2.0.713 → 2.0.714
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/organisms/cards-carousel/cards-carousel.component.mjs +63 -16
- package/esm2022/lib/components/organisms/cards-carousel/types.mjs +1 -1
- package/esm2022/lib/components/templates/simple/simple.component.mjs +7 -9
- package/esm2022/lib/services/auth/auth.service.mjs +33 -17
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +1 -12
- package/fesm2022/valtech-components.mjs +100 -1995
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/bottom-nav/bottom-nav.component.d.ts +1 -1
- package/lib/components/organisms/cards-carousel/cards-carousel.component.d.ts +12 -6
- package/lib/components/organisms/cards-carousel/types.d.ts +32 -3
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +0 -11
- package/esm2022/lib/components/molecules/participant-card/participant-card.component.mjs +0 -514
- package/esm2022/lib/components/molecules/participant-card/types.mjs +0 -21
- package/esm2022/lib/components/molecules/raffle-status-card/raffle-status-card.component.mjs +0 -476
- package/esm2022/lib/components/molecules/raffle-status-card/types.mjs +0 -23
- package/esm2022/lib/components/molecules/recap-card/recap-card.component.mjs +0 -78
- package/esm2022/lib/components/molecules/recap-card/types.mjs +0 -2
- package/esm2022/lib/components/molecules/ticket-grid/ticket-grid.component.mjs +0 -489
- package/esm2022/lib/components/molecules/ticket-grid/types.mjs +0 -11
- package/esm2022/lib/components/molecules/winner-display/types.mjs +0 -9
- package/esm2022/lib/components/molecules/winner-display/winner-display.component.mjs +0 -359
- package/esm2022/lib/components/templates/layout/layout.component.mjs +0 -19
- package/lib/components/molecules/participant-card/participant-card.component.d.ts +0 -34
- package/lib/components/molecules/participant-card/types.d.ts +0 -132
- package/lib/components/molecules/raffle-status-card/raffle-status-card.component.d.ts +0 -21
- package/lib/components/molecules/raffle-status-card/types.d.ts +0 -108
- package/lib/components/molecules/recap-card/recap-card.component.d.ts +0 -36
- package/lib/components/molecules/recap-card/types.d.ts +0 -30
- package/lib/components/molecules/ticket-grid/ticket-grid.component.d.ts +0 -40
- package/lib/components/molecules/ticket-grid/types.d.ts +0 -122
- package/lib/components/molecules/winner-display/types.d.ts +0 -103
- package/lib/components/molecules/winner-display/winner-display.component.d.ts +0 -36
- package/lib/components/templates/layout/layout.component.d.ts +0 -5
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, Injectable, makeEnvironmentProviders, APP_INITIALIZER, inject, EventEmitter, Component, Input, Output, computed, HostListener, Pipe, input, ChangeDetectionStrategy, ViewChild, ChangeDetectorRef,
|
|
2
|
+
import { signal, Injectable, makeEnvironmentProviders, APP_INITIALIZER, inject, EventEmitter, Component, Input, Output, computed, HostListener, Pipe, input, ChangeDetectionStrategy, ViewChild, ChangeDetectorRef, ContentChild, PLATFORM_ID, Inject, ErrorHandler, DestroyRef, InjectionToken, runInInjectionContext, effect, Optional, TemplateRef, ViewContainerRef, isSignal, Directive, ElementRef, ViewEncapsulation } from '@angular/core';
|
|
3
3
|
import * as i2$1 from '@ionic/angular/standalone';
|
|
4
4
|
import { IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonRadioGroup, IonRadio, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, ToastController as ToastController$1, IonCol, IonRow, IonRefresher, IonRefresherContent, IonRippleEffect, AlertController, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, IonSplitPane } from '@ionic/angular/standalone';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
6
6
|
import { CommonModule, NgStyle, NgFor, isPlatformBrowser, NgClass } from '@angular/common';
|
|
7
7
|
import { addIcons } from 'ionicons';
|
|
8
|
-
import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, settings, settingsOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notifications, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, home, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, logoGoogle, createOutline, trashOutline, playOutline, refreshOutline, documentTextOutline, lockClosedOutline, informationCircleOutline, logoNpm, removeOutline, add, close, share, create, trash, star, camera, mic, send, downloadOutline, chevronDown, language, globeOutline, checkmark, list, grid, apps, menu, search, person, helpCircle, informationCircle, documentText, mail, calendar, folder, chevronForward, ellipsisHorizontal, chevronBack, playBack, playForward, ellipse, starOutline, starHalf, heartHalf, checkmarkCircle, timeOutline, flag, trendingUp, trendingDown, remove, analytics, people, cash, cart, eye, chatbubbleOutline, thumbsUpOutline, thumbsUp, happyOutline, happy, sadOutline, sad, chevronUp, pin, pencil, callOutline,
|
|
8
|
+
import { addOutline, addCircleOutline, alertOutline, alertCircleOutline, arrowBackOutline, arrowForwardOutline, arrowDownOutline, settings, settingsOutline, checkmarkCircleOutline, ellipsisHorizontalOutline, notifications, notificationsOutline, openOutline, closeOutline, chatbubblesOutline, shareOutline, heart, heartOutline, home, homeOutline, eyeOffOutline, eyeOutline, scanOutline, chevronDownOutline, chevronForwardOutline, checkmarkOutline, clipboardOutline, copyOutline, filterOutline, locationOutline, calendarOutline, businessOutline, logoTwitter, logoInstagram, logoLinkedin, logoYoutube, logoTiktok, logoFacebook, logoGoogle, createOutline, trashOutline, playOutline, refreshOutline, documentTextOutline, lockClosedOutline, informationCircleOutline, logoNpm, removeOutline, add, close, share, create, trash, star, camera, mic, send, downloadOutline, chevronDown, language, globeOutline, checkmark, list, grid, apps, menu, search, person, helpCircle, informationCircle, documentText, mail, calendar, folder, chevronForward, ellipsisHorizontal, chevronBack, playBack, playForward, ellipse, starOutline, starHalf, heartHalf, checkmarkCircle, timeOutline, flag, trendingUp, trendingDown, remove, analytics, people, cash, cart, eye, chatbubbleOutline, thumbsUpOutline, thumbsUp, happyOutline, happy, sadOutline, sad, chevronUp, pin, pencil, callOutline, logoWhatsapp, paperPlaneOutline, mailOutline, closeCircle, alertCircle, logoApple, logoMicrosoft, linkOutline, unlinkOutline, chevronBackOutline, sendOutline, chatbubbleEllipsesOutline, swapVerticalOutline, chevronUpOutline, documentOutline, searchOutline, personOutline, cartOutline, chatbubble, compass, compassOutline, gridOutline, listOutline, folderOutline, documents, documentsOutline, statsChart, statsChartOutline, cameraOutline, bugOutline, bulbOutline, closeCircleOutline, menuOutline } from 'ionicons/icons';
|
|
9
9
|
import * as i1$1 from '@angular/router';
|
|
10
10
|
import { Router, NavigationEnd, RouterLink, RouterOutlet, RouterModule } from '@angular/router';
|
|
11
11
|
import { Browser } from '@capacitor/browser';
|
|
@@ -50,7 +50,7 @@ import 'prismjs/components/prism-json';
|
|
|
50
50
|
* Current version of valtech-components.
|
|
51
51
|
* This is automatically updated during the publish process.
|
|
52
52
|
*/
|
|
53
|
-
const VERSION = '2.0.
|
|
53
|
+
const VERSION = '2.0.714';
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Servicio para gestionar presets de componentes.
|
|
@@ -14442,498 +14442,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
14442
14442
|
type: Output
|
|
14443
14443
|
}] } });
|
|
14444
14444
|
|
|
14445
|
-
/**
|
|
14446
|
-
* Default legend labels in Spanish.
|
|
14447
|
-
*/
|
|
14448
|
-
const DEFAULT_LEGEND_LABELS = {
|
|
14449
|
-
available: 'Disponible',
|
|
14450
|
-
sold: 'Vendido',
|
|
14451
|
-
reserved: 'Reservado',
|
|
14452
|
-
selected: 'Seleccionado',
|
|
14453
|
-
disabled: 'No disponible',
|
|
14454
|
-
};
|
|
14455
|
-
|
|
14456
|
-
addIcons({ shuffleOutline });
|
|
14457
|
-
/**
|
|
14458
|
-
* val-ticket-grid
|
|
14459
|
-
*
|
|
14460
|
-
* A grid for selecting ticket numbers, commonly used in raffles and lotteries.
|
|
14461
|
-
*
|
|
14462
|
-
* @example Basic usage
|
|
14463
|
-
* ```html
|
|
14464
|
-
* <val-ticket-grid
|
|
14465
|
-
* [props]="{
|
|
14466
|
-
* totalTickets: 100,
|
|
14467
|
-
* soldTickets: [1, 5, 12, 23],
|
|
14468
|
-
* selectionMode: 'multiple',
|
|
14469
|
-
* maxSelection: 10
|
|
14470
|
-
* }"
|
|
14471
|
-
* (selectionChange)="onSelectionChange($event)"
|
|
14472
|
-
* ></val-ticket-grid>
|
|
14473
|
-
* ```
|
|
14474
|
-
*
|
|
14475
|
-
* @example With legend and search
|
|
14476
|
-
* ```html
|
|
14477
|
-
* <val-ticket-grid
|
|
14478
|
-
* [props]="{
|
|
14479
|
-
* totalTickets: 500,
|
|
14480
|
-
* soldTickets: soldNumbers,
|
|
14481
|
-
* reservedTickets: reservedNumbers,
|
|
14482
|
-
* columns: 20,
|
|
14483
|
-
* showLegend: true,
|
|
14484
|
-
* showSearch: true,
|
|
14485
|
-
* showRandomSelect: true,
|
|
14486
|
-
* randomSelectCount: 5,
|
|
14487
|
-
* maxSelection: 10
|
|
14488
|
-
* }"
|
|
14489
|
-
* ></val-ticket-grid>
|
|
14490
|
-
* ```
|
|
14491
|
-
*/
|
|
14492
|
-
class TicketGridComponent {
|
|
14493
|
-
constructor() {
|
|
14494
|
-
this.selectionChange = new EventEmitter();
|
|
14495
|
-
this.ticketClick = new EventEmitter();
|
|
14496
|
-
this.tickets = [];
|
|
14497
|
-
this.displayedTickets = [];
|
|
14498
|
-
this.selectedTickets = [];
|
|
14499
|
-
this.searchTerm = '';
|
|
14500
|
-
this.highlightedNumbers = [];
|
|
14501
|
-
}
|
|
14502
|
-
ngOnInit() {
|
|
14503
|
-
this.buildTickets();
|
|
14504
|
-
}
|
|
14505
|
-
ngOnChanges(changes) {
|
|
14506
|
-
if (changes['props']) {
|
|
14507
|
-
this.buildTickets();
|
|
14508
|
-
}
|
|
14509
|
-
}
|
|
14510
|
-
buildTickets() {
|
|
14511
|
-
const start = this.props.startNumber ?? 1;
|
|
14512
|
-
const total = this.props.totalTickets;
|
|
14513
|
-
const soldSet = new Set(this.props.soldTickets || []);
|
|
14514
|
-
const reservedSet = new Set(this.props.reservedTickets || []);
|
|
14515
|
-
const disabledSet = new Set(this.props.disabledTickets || []);
|
|
14516
|
-
const selectedSet = new Set(this.props.selectedTickets || []);
|
|
14517
|
-
// Initialize selected tickets from props
|
|
14518
|
-
this.selectedTickets = [...(this.props.selectedTickets || [])];
|
|
14519
|
-
// Build ticket array
|
|
14520
|
-
if (this.props.ticketData?.length) {
|
|
14521
|
-
// Use custom ticket data
|
|
14522
|
-
this.tickets = [...this.props.ticketData];
|
|
14523
|
-
}
|
|
14524
|
-
else {
|
|
14525
|
-
// Generate from numbers
|
|
14526
|
-
this.tickets = [];
|
|
14527
|
-
for (let i = start; i < start + total; i++) {
|
|
14528
|
-
let status = 'available';
|
|
14529
|
-
if (disabledSet.has(i)) {
|
|
14530
|
-
status = 'disabled';
|
|
14531
|
-
}
|
|
14532
|
-
else if (soldSet.has(i)) {
|
|
14533
|
-
status = 'sold';
|
|
14534
|
-
}
|
|
14535
|
-
else if (reservedSet.has(i)) {
|
|
14536
|
-
status = 'reserved';
|
|
14537
|
-
}
|
|
14538
|
-
else if (selectedSet.has(i)) {
|
|
14539
|
-
status = 'selected';
|
|
14540
|
-
}
|
|
14541
|
-
this.tickets.push({ number: i, status });
|
|
14542
|
-
}
|
|
14543
|
-
}
|
|
14544
|
-
this.applySearch();
|
|
14545
|
-
}
|
|
14546
|
-
applySearch() {
|
|
14547
|
-
if (!this.searchTerm) {
|
|
14548
|
-
this.displayedTickets = [...this.tickets];
|
|
14549
|
-
this.highlightedNumbers = [];
|
|
14550
|
-
}
|
|
14551
|
-
else {
|
|
14552
|
-
// Filter/highlight tickets matching search
|
|
14553
|
-
const term = this.searchTerm.trim();
|
|
14554
|
-
this.highlightedNumbers = this.tickets
|
|
14555
|
-
.filter(t => this.formatNumber(t.number).includes(term))
|
|
14556
|
-
.map(t => t.number);
|
|
14557
|
-
this.displayedTickets = [...this.tickets];
|
|
14558
|
-
}
|
|
14559
|
-
}
|
|
14560
|
-
onSearch(event) {
|
|
14561
|
-
this.searchTerm = event.detail.value || '';
|
|
14562
|
-
this.applySearch();
|
|
14563
|
-
}
|
|
14564
|
-
isHighlighted(number) {
|
|
14565
|
-
return this.highlightedNumbers.includes(number);
|
|
14566
|
-
}
|
|
14567
|
-
isSelectable(ticket) {
|
|
14568
|
-
if (this.props.selectionMode === 'none')
|
|
14569
|
-
return false;
|
|
14570
|
-
// Check if sold/reserved and admin override
|
|
14571
|
-
if (ticket.status === 'sold' || ticket.status === 'reserved') {
|
|
14572
|
-
return this.props.allowSelectSold === true;
|
|
14573
|
-
}
|
|
14574
|
-
if (ticket.status === 'disabled')
|
|
14575
|
-
return false;
|
|
14576
|
-
// Check max selection
|
|
14577
|
-
if (ticket.status !== 'selected' &&
|
|
14578
|
-
this.props.maxSelection &&
|
|
14579
|
-
this.selectedTickets.length >= this.props.maxSelection) {
|
|
14580
|
-
return false;
|
|
14581
|
-
}
|
|
14582
|
-
return true;
|
|
14583
|
-
}
|
|
14584
|
-
onTicketClick(ticket) {
|
|
14585
|
-
const isSelected = this.selectedTickets.includes(ticket.number);
|
|
14586
|
-
// Emit click event regardless
|
|
14587
|
-
this.ticketClick.emit({
|
|
14588
|
-
number: ticket.number,
|
|
14589
|
-
status: ticket.status,
|
|
14590
|
-
selected: this.isSelectable(ticket) ? !isSelected : null,
|
|
14591
|
-
});
|
|
14592
|
-
if (!this.isSelectable(ticket) && ticket.status !== 'selected') {
|
|
14593
|
-
return;
|
|
14594
|
-
}
|
|
14595
|
-
// Handle selection
|
|
14596
|
-
if (isSelected) {
|
|
14597
|
-
// Deselect
|
|
14598
|
-
this.selectedTickets = this.selectedTickets.filter(n => n !== ticket.number);
|
|
14599
|
-
ticket.status = 'available';
|
|
14600
|
-
this.selectionChange.emit({
|
|
14601
|
-
selectedTickets: [...this.selectedTickets],
|
|
14602
|
-
changedTicket: ticket.number,
|
|
14603
|
-
action: 'deselect',
|
|
14604
|
-
count: this.selectedTickets.length,
|
|
14605
|
-
maxReached: false,
|
|
14606
|
-
});
|
|
14607
|
-
}
|
|
14608
|
-
else {
|
|
14609
|
-
// Select
|
|
14610
|
-
if (this.props.selectionMode === 'single') {
|
|
14611
|
-
// Deselect previous
|
|
14612
|
-
this.selectedTickets.forEach(num => {
|
|
14613
|
-
const t = this.tickets.find(x => x.number === num);
|
|
14614
|
-
if (t)
|
|
14615
|
-
t.status = 'available';
|
|
14616
|
-
});
|
|
14617
|
-
this.selectedTickets = [ticket.number];
|
|
14618
|
-
}
|
|
14619
|
-
else {
|
|
14620
|
-
this.selectedTickets.push(ticket.number);
|
|
14621
|
-
}
|
|
14622
|
-
ticket.status = 'selected';
|
|
14623
|
-
this.selectionChange.emit({
|
|
14624
|
-
selectedTickets: [...this.selectedTickets],
|
|
14625
|
-
changedTicket: ticket.number,
|
|
14626
|
-
action: 'select',
|
|
14627
|
-
count: this.selectedTickets.length,
|
|
14628
|
-
maxReached: this.props.maxSelection
|
|
14629
|
-
? this.selectedTickets.length >= this.props.maxSelection
|
|
14630
|
-
: false,
|
|
14631
|
-
});
|
|
14632
|
-
}
|
|
14633
|
-
}
|
|
14634
|
-
selectRandom() {
|
|
14635
|
-
const count = this.props.randomSelectCount || 1;
|
|
14636
|
-
const available = this.tickets.filter(t => t.status === 'available' && !this.selectedTickets.includes(t.number));
|
|
14637
|
-
// Determine how many we can select
|
|
14638
|
-
const maxCanSelect = this.props.maxSelection
|
|
14639
|
-
? Math.min(count, this.props.maxSelection - this.selectedTickets.length)
|
|
14640
|
-
: count;
|
|
14641
|
-
if (available.length === 0 || maxCanSelect <= 0)
|
|
14642
|
-
return;
|
|
14643
|
-
// Random shuffle and pick
|
|
14644
|
-
const shuffled = [...available].sort(() => Math.random() - 0.5);
|
|
14645
|
-
const toSelect = shuffled.slice(0, Math.min(maxCanSelect, available.length));
|
|
14646
|
-
toSelect.forEach(ticket => {
|
|
14647
|
-
ticket.status = 'selected';
|
|
14648
|
-
this.selectedTickets.push(ticket.number);
|
|
14649
|
-
});
|
|
14650
|
-
this.selectionChange.emit({
|
|
14651
|
-
selectedTickets: [...this.selectedTickets],
|
|
14652
|
-
changedTicket: toSelect[toSelect.length - 1].number,
|
|
14653
|
-
action: 'select',
|
|
14654
|
-
count: this.selectedTickets.length,
|
|
14655
|
-
maxReached: this.props.maxSelection
|
|
14656
|
-
? this.selectedTickets.length >= this.props.maxSelection
|
|
14657
|
-
: false,
|
|
14658
|
-
});
|
|
14659
|
-
}
|
|
14660
|
-
/**
|
|
14661
|
-
* Clear all selections.
|
|
14662
|
-
*/
|
|
14663
|
-
clearSelection() {
|
|
14664
|
-
this.selectedTickets.forEach(num => {
|
|
14665
|
-
const ticket = this.tickets.find(t => t.number === num);
|
|
14666
|
-
if (ticket)
|
|
14667
|
-
ticket.status = 'available';
|
|
14668
|
-
});
|
|
14669
|
-
this.selectedTickets = [];
|
|
14670
|
-
}
|
|
14671
|
-
/**
|
|
14672
|
-
* Get selected ticket numbers.
|
|
14673
|
-
*/
|
|
14674
|
-
getSelectedTickets() {
|
|
14675
|
-
return [...this.selectedTickets];
|
|
14676
|
-
}
|
|
14677
|
-
get availableCount() {
|
|
14678
|
-
return this.tickets.filter(t => t.status === 'available').length;
|
|
14679
|
-
}
|
|
14680
|
-
get soldCount() {
|
|
14681
|
-
return this.tickets.filter(t => t.status === 'sold').length;
|
|
14682
|
-
}
|
|
14683
|
-
getLegendItems() {
|
|
14684
|
-
if (this.props.legendItems) {
|
|
14685
|
-
return this.props.legendItems;
|
|
14686
|
-
}
|
|
14687
|
-
const items = [
|
|
14688
|
-
{ status: 'available', label: DEFAULT_LEGEND_LABELS.available, count: this.availableCount },
|
|
14689
|
-
{ status: 'selected', label: DEFAULT_LEGEND_LABELS.selected, count: this.selectedTickets.length },
|
|
14690
|
-
];
|
|
14691
|
-
if (this.props.soldTickets?.length) {
|
|
14692
|
-
items.push({ status: 'sold', label: DEFAULT_LEGEND_LABELS.sold, count: this.soldCount });
|
|
14693
|
-
}
|
|
14694
|
-
if (this.props.reservedTickets?.length) {
|
|
14695
|
-
items.push({
|
|
14696
|
-
status: 'reserved',
|
|
14697
|
-
label: DEFAULT_LEGEND_LABELS.reserved,
|
|
14698
|
-
count: this.props.reservedTickets.length,
|
|
14699
|
-
});
|
|
14700
|
-
}
|
|
14701
|
-
return items;
|
|
14702
|
-
}
|
|
14703
|
-
formatNumber(num) {
|
|
14704
|
-
if (this.props.numberPadding) {
|
|
14705
|
-
return String(num).padStart(this.props.numberPadding, '0');
|
|
14706
|
-
}
|
|
14707
|
-
return String(num);
|
|
14708
|
-
}
|
|
14709
|
-
getTicketAriaLabel(ticket) {
|
|
14710
|
-
const statusLabel = DEFAULT_LEGEND_LABELS[ticket.status];
|
|
14711
|
-
return `Boleto ${this.formatNumber(ticket.number)}, ${statusLabel}`;
|
|
14712
|
-
}
|
|
14713
|
-
getSearchPlaceholder() {
|
|
14714
|
-
return this.props.searchPlaceholder || 'Buscar número...';
|
|
14715
|
-
}
|
|
14716
|
-
getRandomSelectLabel() {
|
|
14717
|
-
return this.props.randomSelectLabel || 'Aleatorio';
|
|
14718
|
-
}
|
|
14719
|
-
getColor() {
|
|
14720
|
-
if (this.props.color) {
|
|
14721
|
-
return `var(--ion-color-${this.props.color})`;
|
|
14722
|
-
}
|
|
14723
|
-
return 'var(--ion-color-primary)';
|
|
14724
|
-
}
|
|
14725
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TicketGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
14726
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: TicketGridComponent, isStandalone: true, selector: "val-ticket-grid", inputs: { props: "props" }, outputs: { selectionChange: "selectionChange", ticketClick: "ticketClick" }, usesOnChanges: true, ngImport: i0, template: `
|
|
14727
|
-
<div
|
|
14728
|
-
class="ticket-grid-container"
|
|
14729
|
-
[class]="props.cssClass"
|
|
14730
|
-
[class.size-small]="props.ticketSize === 'small'"
|
|
14731
|
-
[class.size-medium]="props.ticketSize === 'medium' || !props.ticketSize"
|
|
14732
|
-
[class.size-large]="props.ticketSize === 'large'"
|
|
14733
|
-
[style.--grid-columns]="props.columns || 10"
|
|
14734
|
-
[style.--grid-gap]="(props.gap || 4) + 'px'"
|
|
14735
|
-
[style.--selected-color]="getColor()"
|
|
14736
|
-
>
|
|
14737
|
-
<!-- Search and controls -->
|
|
14738
|
-
@if (props.showSearch || props.showRandomSelect) {
|
|
14739
|
-
<div class="grid-controls">
|
|
14740
|
-
@if (props.showSearch) {
|
|
14741
|
-
<ion-searchbar
|
|
14742
|
-
[placeholder]="getSearchPlaceholder()"
|
|
14743
|
-
[debounce]="300"
|
|
14744
|
-
(ionInput)="onSearch($event)"
|
|
14745
|
-
class="ticket-search"
|
|
14746
|
-
></ion-searchbar>
|
|
14747
|
-
}
|
|
14748
|
-
|
|
14749
|
-
@if (props.showRandomSelect && props.selectionMode !== 'none') {
|
|
14750
|
-
<ion-button
|
|
14751
|
-
fill="outline"
|
|
14752
|
-
[color]="props.color || 'primary'"
|
|
14753
|
-
(click)="selectRandom()"
|
|
14754
|
-
[disabled]="availableCount < (props.randomSelectCount || 1)"
|
|
14755
|
-
>
|
|
14756
|
-
<ion-icon slot="start" name="shuffle-outline"></ion-icon>
|
|
14757
|
-
{{ getRandomSelectLabel() }}
|
|
14758
|
-
</ion-button>
|
|
14759
|
-
}
|
|
14760
|
-
</div>
|
|
14761
|
-
}
|
|
14762
|
-
|
|
14763
|
-
<!-- Legend (top) -->
|
|
14764
|
-
@if (props.showLegend && props.legendPosition !== 'bottom') {
|
|
14765
|
-
<div class="ticket-legend">
|
|
14766
|
-
@for (item of getLegendItems(); track item.status) {
|
|
14767
|
-
<div class="legend-item">
|
|
14768
|
-
<span class="legend-color" [class]="'status-' + item.status"></span>
|
|
14769
|
-
<span class="legend-label">{{ item.label }}</span>
|
|
14770
|
-
@if (item.count !== undefined) {
|
|
14771
|
-
<span class="legend-count">({{ item.count }})</span>
|
|
14772
|
-
}
|
|
14773
|
-
</div>
|
|
14774
|
-
}
|
|
14775
|
-
</div>
|
|
14776
|
-
}
|
|
14777
|
-
|
|
14778
|
-
<!-- Summary -->
|
|
14779
|
-
@if (props.showSummary) {
|
|
14780
|
-
<div class="ticket-summary">
|
|
14781
|
-
<span class="summary-item">
|
|
14782
|
-
<strong>{{ selectedTickets.length }}</strong> seleccionado{{ selectedTickets.length !== 1 ? 's' : '' }}
|
|
14783
|
-
</span>
|
|
14784
|
-
@if (props.maxSelection) {
|
|
14785
|
-
<span class="summary-item">
|
|
14786
|
-
(máx: {{ props.maxSelection }})
|
|
14787
|
-
</span>
|
|
14788
|
-
}
|
|
14789
|
-
</div>
|
|
14790
|
-
}
|
|
14791
|
-
|
|
14792
|
-
<!-- Grid -->
|
|
14793
|
-
<div class="ticket-grid" role="grid">
|
|
14794
|
-
@for (ticket of displayedTickets; track ticket.number) {
|
|
14795
|
-
<button
|
|
14796
|
-
type="button"
|
|
14797
|
-
class="ticket-cell"
|
|
14798
|
-
[class]="'status-' + ticket.status"
|
|
14799
|
-
[class.highlighted]="isHighlighted(ticket.number)"
|
|
14800
|
-
[disabled]="!isSelectable(ticket)"
|
|
14801
|
-
[attr.aria-label]="getTicketAriaLabel(ticket)"
|
|
14802
|
-
[attr.aria-pressed]="ticket.status === 'selected'"
|
|
14803
|
-
(click)="onTicketClick(ticket)"
|
|
14804
|
-
>
|
|
14805
|
-
{{ formatNumber(ticket.number) }}
|
|
14806
|
-
</button>
|
|
14807
|
-
}
|
|
14808
|
-
</div>
|
|
14809
|
-
|
|
14810
|
-
<!-- Legend (bottom) -->
|
|
14811
|
-
@if (props.showLegend && props.legendPosition === 'bottom') {
|
|
14812
|
-
<div class="ticket-legend bottom">
|
|
14813
|
-
@for (item of getLegendItems(); track item.status) {
|
|
14814
|
-
<div class="legend-item">
|
|
14815
|
-
<span class="legend-color" [class]="'status-' + item.status"></span>
|
|
14816
|
-
<span class="legend-label">{{ item.label }}</span>
|
|
14817
|
-
@if (item.count !== undefined) {
|
|
14818
|
-
<span class="legend-count">({{ item.count }})</span>
|
|
14819
|
-
}
|
|
14820
|
-
</div>
|
|
14821
|
-
}
|
|
14822
|
-
</div>
|
|
14823
|
-
}
|
|
14824
|
-
</div>
|
|
14825
|
-
`, isInline: true, styles: ["@charset \"UTF-8\";:host{display:block}.ticket-grid-container{--grid-columns: 10;--grid-gap: 4px;--selected-color: var(--ion-color-primary);display:flex;flex-direction:column;gap:16px}.grid-controls{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}.ticket-search{flex:1;min-width:200px;max-width:300px;--border-radius: 8px}.ticket-legend{display:flex;flex-wrap:wrap;gap:16px;padding:8px 0}.ticket-legend.bottom{border-top:1px solid var(--ion-color-light-shade);padding-top:12px;margin-top:8px}.legend-item{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--ion-color-medium-shade)}.legend-color{width:16px;height:16px;border-radius:4px;border:1px solid var(--ion-color-medium)}.legend-color.status-available{background:var(--ion-color-light);border-color:var(--ion-color-medium)}.legend-color.status-selected{background:var(--selected-color);border-color:var(--selected-color)}.legend-color.status-sold{background:var(--ion-color-medium);border-color:var(--ion-color-medium-shade)}.legend-color.status-reserved{background:var(--ion-color-warning-tint);border-color:var(--ion-color-warning)}.legend-color.status-disabled{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium);opacity:.5}.legend-count{color:var(--ion-color-medium);font-size:11px}.ticket-summary{display:flex;gap:8px;align-items:center;font-size:14px;color:var(--ion-color-dark);padding:8px 12px;background:var(--ion-color-light);border-radius:8px}.summary-item:not(:last-child):after{content:\"\\2022\";margin-left:8px;color:var(--ion-color-medium)}.ticket-grid{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);gap:var(--grid-gap)}.ticket-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:1px solid var(--ion-color-medium);border-radius:4px;background:var(--ion-color-light);font-size:12px;font-weight:500;color:var(--ion-color-dark);cursor:pointer;transition:all .15s ease;padding:0;font-family:inherit}.ticket-cell:hover:not(:disabled){border-color:var(--selected-color);transform:scale(1.05);z-index:1}.ticket-cell:focus{outline:2px solid var(--selected-color);outline-offset:1px}.ticket-cell.status-available{background:var(--ion-color-light);border-color:var(--ion-color-medium)}.ticket-cell.status-available:hover:not(:disabled){background:var(--ion-color-light-shade)}.ticket-cell.status-selected{background:var(--selected-color);border-color:var(--selected-color);color:#fff;font-weight:600}.ticket-cell.status-sold{background:var(--ion-color-medium);border-color:var(--ion-color-medium-shade);color:var(--ion-color-medium-contrast);cursor:not-allowed;opacity:.7}.ticket-cell.status-reserved{background:var(--ion-color-warning-tint);border-color:var(--ion-color-warning);color:var(--ion-color-warning-shade);cursor:not-allowed}.ticket-cell.status-disabled{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium);color:var(--ion-color-medium);cursor:not-allowed;opacity:.5}.ticket-cell.highlighted{box-shadow:0 0 0 2px var(--ion-color-tertiary);z-index:2}.ticket-cell:disabled{cursor:not-allowed}.size-small .ticket-grid{--grid-gap: 2px}.size-small .ticket-cell{font-size:10px;border-radius:2px}.size-small .ticket-legend{gap:12px}.size-small .legend-color{width:12px;height:12px}.size-small .legend-item{font-size:11px}.size-large .ticket-grid{--grid-gap: 6px}.size-large .ticket-cell{font-size:14px;border-radius:6px;font-weight:600}.size-large .ticket-legend{gap:20px}.size-large .legend-color{width:20px;height:20px}.size-large .legend-item{font-size:14px}@media (max-width: 576px){.grid-controls{flex-direction:column;align-items:stretch}.ticket-search{max-width:100%}.ticket-legend{justify-content:center}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }] }); }
|
|
14826
|
-
}
|
|
14827
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TicketGridComponent, decorators: [{
|
|
14828
|
-
type: Component,
|
|
14829
|
-
args: [{ selector: 'val-ticket-grid', standalone: true, imports: [CommonModule, FormsModule, IonButton, IonIcon, IonSearchbar], template: `
|
|
14830
|
-
<div
|
|
14831
|
-
class="ticket-grid-container"
|
|
14832
|
-
[class]="props.cssClass"
|
|
14833
|
-
[class.size-small]="props.ticketSize === 'small'"
|
|
14834
|
-
[class.size-medium]="props.ticketSize === 'medium' || !props.ticketSize"
|
|
14835
|
-
[class.size-large]="props.ticketSize === 'large'"
|
|
14836
|
-
[style.--grid-columns]="props.columns || 10"
|
|
14837
|
-
[style.--grid-gap]="(props.gap || 4) + 'px'"
|
|
14838
|
-
[style.--selected-color]="getColor()"
|
|
14839
|
-
>
|
|
14840
|
-
<!-- Search and controls -->
|
|
14841
|
-
@if (props.showSearch || props.showRandomSelect) {
|
|
14842
|
-
<div class="grid-controls">
|
|
14843
|
-
@if (props.showSearch) {
|
|
14844
|
-
<ion-searchbar
|
|
14845
|
-
[placeholder]="getSearchPlaceholder()"
|
|
14846
|
-
[debounce]="300"
|
|
14847
|
-
(ionInput)="onSearch($event)"
|
|
14848
|
-
class="ticket-search"
|
|
14849
|
-
></ion-searchbar>
|
|
14850
|
-
}
|
|
14851
|
-
|
|
14852
|
-
@if (props.showRandomSelect && props.selectionMode !== 'none') {
|
|
14853
|
-
<ion-button
|
|
14854
|
-
fill="outline"
|
|
14855
|
-
[color]="props.color || 'primary'"
|
|
14856
|
-
(click)="selectRandom()"
|
|
14857
|
-
[disabled]="availableCount < (props.randomSelectCount || 1)"
|
|
14858
|
-
>
|
|
14859
|
-
<ion-icon slot="start" name="shuffle-outline"></ion-icon>
|
|
14860
|
-
{{ getRandomSelectLabel() }}
|
|
14861
|
-
</ion-button>
|
|
14862
|
-
}
|
|
14863
|
-
</div>
|
|
14864
|
-
}
|
|
14865
|
-
|
|
14866
|
-
<!-- Legend (top) -->
|
|
14867
|
-
@if (props.showLegend && props.legendPosition !== 'bottom') {
|
|
14868
|
-
<div class="ticket-legend">
|
|
14869
|
-
@for (item of getLegendItems(); track item.status) {
|
|
14870
|
-
<div class="legend-item">
|
|
14871
|
-
<span class="legend-color" [class]="'status-' + item.status"></span>
|
|
14872
|
-
<span class="legend-label">{{ item.label }}</span>
|
|
14873
|
-
@if (item.count !== undefined) {
|
|
14874
|
-
<span class="legend-count">({{ item.count }})</span>
|
|
14875
|
-
}
|
|
14876
|
-
</div>
|
|
14877
|
-
}
|
|
14878
|
-
</div>
|
|
14879
|
-
}
|
|
14880
|
-
|
|
14881
|
-
<!-- Summary -->
|
|
14882
|
-
@if (props.showSummary) {
|
|
14883
|
-
<div class="ticket-summary">
|
|
14884
|
-
<span class="summary-item">
|
|
14885
|
-
<strong>{{ selectedTickets.length }}</strong> seleccionado{{ selectedTickets.length !== 1 ? 's' : '' }}
|
|
14886
|
-
</span>
|
|
14887
|
-
@if (props.maxSelection) {
|
|
14888
|
-
<span class="summary-item">
|
|
14889
|
-
(máx: {{ props.maxSelection }})
|
|
14890
|
-
</span>
|
|
14891
|
-
}
|
|
14892
|
-
</div>
|
|
14893
|
-
}
|
|
14894
|
-
|
|
14895
|
-
<!-- Grid -->
|
|
14896
|
-
<div class="ticket-grid" role="grid">
|
|
14897
|
-
@for (ticket of displayedTickets; track ticket.number) {
|
|
14898
|
-
<button
|
|
14899
|
-
type="button"
|
|
14900
|
-
class="ticket-cell"
|
|
14901
|
-
[class]="'status-' + ticket.status"
|
|
14902
|
-
[class.highlighted]="isHighlighted(ticket.number)"
|
|
14903
|
-
[disabled]="!isSelectable(ticket)"
|
|
14904
|
-
[attr.aria-label]="getTicketAriaLabel(ticket)"
|
|
14905
|
-
[attr.aria-pressed]="ticket.status === 'selected'"
|
|
14906
|
-
(click)="onTicketClick(ticket)"
|
|
14907
|
-
>
|
|
14908
|
-
{{ formatNumber(ticket.number) }}
|
|
14909
|
-
</button>
|
|
14910
|
-
}
|
|
14911
|
-
</div>
|
|
14912
|
-
|
|
14913
|
-
<!-- Legend (bottom) -->
|
|
14914
|
-
@if (props.showLegend && props.legendPosition === 'bottom') {
|
|
14915
|
-
<div class="ticket-legend bottom">
|
|
14916
|
-
@for (item of getLegendItems(); track item.status) {
|
|
14917
|
-
<div class="legend-item">
|
|
14918
|
-
<span class="legend-color" [class]="'status-' + item.status"></span>
|
|
14919
|
-
<span class="legend-label">{{ item.label }}</span>
|
|
14920
|
-
@if (item.count !== undefined) {
|
|
14921
|
-
<span class="legend-count">({{ item.count }})</span>
|
|
14922
|
-
}
|
|
14923
|
-
</div>
|
|
14924
|
-
}
|
|
14925
|
-
</div>
|
|
14926
|
-
}
|
|
14927
|
-
</div>
|
|
14928
|
-
`, styles: ["@charset \"UTF-8\";:host{display:block}.ticket-grid-container{--grid-columns: 10;--grid-gap: 4px;--selected-color: var(--ion-color-primary);display:flex;flex-direction:column;gap:16px}.grid-controls{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between}.ticket-search{flex:1;min-width:200px;max-width:300px;--border-radius: 8px}.ticket-legend{display:flex;flex-wrap:wrap;gap:16px;padding:8px 0}.ticket-legend.bottom{border-top:1px solid var(--ion-color-light-shade);padding-top:12px;margin-top:8px}.legend-item{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--ion-color-medium-shade)}.legend-color{width:16px;height:16px;border-radius:4px;border:1px solid var(--ion-color-medium)}.legend-color.status-available{background:var(--ion-color-light);border-color:var(--ion-color-medium)}.legend-color.status-selected{background:var(--selected-color);border-color:var(--selected-color)}.legend-color.status-sold{background:var(--ion-color-medium);border-color:var(--ion-color-medium-shade)}.legend-color.status-reserved{background:var(--ion-color-warning-tint);border-color:var(--ion-color-warning)}.legend-color.status-disabled{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium);opacity:.5}.legend-count{color:var(--ion-color-medium);font-size:11px}.ticket-summary{display:flex;gap:8px;align-items:center;font-size:14px;color:var(--ion-color-dark);padding:8px 12px;background:var(--ion-color-light);border-radius:8px}.summary-item:not(:last-child):after{content:\"\\2022\";margin-left:8px;color:var(--ion-color-medium)}.ticket-grid{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);gap:var(--grid-gap)}.ticket-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:1px solid var(--ion-color-medium);border-radius:4px;background:var(--ion-color-light);font-size:12px;font-weight:500;color:var(--ion-color-dark);cursor:pointer;transition:all .15s ease;padding:0;font-family:inherit}.ticket-cell:hover:not(:disabled){border-color:var(--selected-color);transform:scale(1.05);z-index:1}.ticket-cell:focus{outline:2px solid var(--selected-color);outline-offset:1px}.ticket-cell.status-available{background:var(--ion-color-light);border-color:var(--ion-color-medium)}.ticket-cell.status-available:hover:not(:disabled){background:var(--ion-color-light-shade)}.ticket-cell.status-selected{background:var(--selected-color);border-color:var(--selected-color);color:#fff;font-weight:600}.ticket-cell.status-sold{background:var(--ion-color-medium);border-color:var(--ion-color-medium-shade);color:var(--ion-color-medium-contrast);cursor:not-allowed;opacity:.7}.ticket-cell.status-reserved{background:var(--ion-color-warning-tint);border-color:var(--ion-color-warning);color:var(--ion-color-warning-shade);cursor:not-allowed}.ticket-cell.status-disabled{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium);color:var(--ion-color-medium);cursor:not-allowed;opacity:.5}.ticket-cell.highlighted{box-shadow:0 0 0 2px var(--ion-color-tertiary);z-index:2}.ticket-cell:disabled{cursor:not-allowed}.size-small .ticket-grid{--grid-gap: 2px}.size-small .ticket-cell{font-size:10px;border-radius:2px}.size-small .ticket-legend{gap:12px}.size-small .legend-color{width:12px;height:12px}.size-small .legend-item{font-size:11px}.size-large .ticket-grid{--grid-gap: 6px}.size-large .ticket-cell{font-size:14px;border-radius:6px;font-weight:600}.size-large .ticket-legend{gap:20px}.size-large .legend-color{width:20px;height:20px}.size-large .legend-item{font-size:14px}@media (max-width: 576px){.grid-controls{flex-direction:column;align-items:stretch}.ticket-search{max-width:100%}.ticket-legend{justify-content:center}}\n"] }]
|
|
14929
|
-
}], propDecorators: { props: [{
|
|
14930
|
-
type: Input
|
|
14931
|
-
}], selectionChange: [{
|
|
14932
|
-
type: Output
|
|
14933
|
-
}], ticketClick: [{
|
|
14934
|
-
type: Output
|
|
14935
|
-
}] } });
|
|
14936
|
-
|
|
14937
14445
|
/**
|
|
14938
14446
|
* Default platform configurations.
|
|
14939
14447
|
*/
|
|
@@ -15288,1380 +14796,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
15288
14796
|
type: Output
|
|
15289
14797
|
}] } });
|
|
15290
14798
|
|
|
15291
|
-
/**
|
|
15292
|
-
* Default labels.
|
|
15293
|
-
*/
|
|
15294
|
-
const DEFAULT_WINNER_LABELS = {
|
|
15295
|
-
winner: '¡Ganador!',
|
|
15296
|
-
ticket: 'Boleto #',
|
|
15297
|
-
prize: 'Premio:',
|
|
15298
|
-
};
|
|
15299
|
-
|
|
15300
|
-
addIcons({ trophyOutline, ticketOutline, giftOutline, locationOutline });
|
|
15301
|
-
/**
|
|
15302
|
-
* val-winner-display
|
|
15303
|
-
*
|
|
15304
|
-
* A component for displaying raffle winners with celebration animations.
|
|
15305
|
-
*
|
|
15306
|
-
* @example Basic usage
|
|
15307
|
-
* ```html
|
|
15308
|
-
* <val-winner-display
|
|
15309
|
-
* [props]="{
|
|
15310
|
-
* winner: {
|
|
15311
|
-
* name: 'Juan Pérez',
|
|
15312
|
-
* ticketNumber: 42
|
|
15313
|
-
* }
|
|
15314
|
-
* }"
|
|
15315
|
-
* ></val-winner-display>
|
|
15316
|
-
* ```
|
|
15317
|
-
*
|
|
15318
|
-
* @example Full celebration mode
|
|
15319
|
-
* ```html
|
|
15320
|
-
* <val-winner-display
|
|
15321
|
-
* [props]="{
|
|
15322
|
-
* winner: {
|
|
15323
|
-
* name: 'María García',
|
|
15324
|
-
* ticketNumber: 156,
|
|
15325
|
-
* prize: 'iPhone 15 Pro',
|
|
15326
|
-
* prizeValue: 25000,
|
|
15327
|
-
* location: 'CDMX, México',
|
|
15328
|
-
* avatar: { image: 'avatar.jpg' }
|
|
15329
|
-
* },
|
|
15330
|
-
* mode: 'celebration',
|
|
15331
|
-
* showConfetti: true,
|
|
15332
|
-
* animation: 'zoom',
|
|
15333
|
-
* color: 'warning'
|
|
15334
|
-
* }"
|
|
15335
|
-
* (animationComplete)="onReveal($event)"
|
|
15336
|
-
* ></val-winner-display>
|
|
15337
|
-
* ```
|
|
15338
|
-
*/
|
|
15339
|
-
class WinnerDisplayComponent {
|
|
15340
|
-
constructor() {
|
|
15341
|
-
this.animationComplete = new EventEmitter();
|
|
15342
|
-
this.isAnimating = false;
|
|
15343
|
-
this.isRevealed = false;
|
|
15344
|
-
this.showConfetti = false;
|
|
15345
|
-
this.confettiPieces = Array.from({ length: 50 }, (_, i) => i);
|
|
15346
|
-
this.revealTimeout = null;
|
|
15347
|
-
this.animationTimeout = null;
|
|
15348
|
-
this.elementRef = inject(ElementRef);
|
|
15349
|
-
}
|
|
15350
|
-
ngOnInit() {
|
|
15351
|
-
if (this.props.autoPlay !== false) {
|
|
15352
|
-
this.startReveal();
|
|
15353
|
-
}
|
|
15354
|
-
}
|
|
15355
|
-
ngAfterViewInit() {
|
|
15356
|
-
// Additional setup if needed
|
|
15357
|
-
}
|
|
15358
|
-
ngOnDestroy() {
|
|
15359
|
-
if (this.revealTimeout)
|
|
15360
|
-
clearTimeout(this.revealTimeout);
|
|
15361
|
-
if (this.animationTimeout)
|
|
15362
|
-
clearTimeout(this.animationTimeout);
|
|
15363
|
-
}
|
|
15364
|
-
startReveal() {
|
|
15365
|
-
const delay = this.props.revealDelay || 0;
|
|
15366
|
-
this.revealTimeout = setTimeout(() => {
|
|
15367
|
-
this.isAnimating = true;
|
|
15368
|
-
const animationDuration = this.props.animationDuration || 800;
|
|
15369
|
-
this.animationTimeout = setTimeout(() => {
|
|
15370
|
-
this.isAnimating = false;
|
|
15371
|
-
this.isRevealed = true;
|
|
15372
|
-
if (this.props.showConfetti) {
|
|
15373
|
-
this.showConfetti = true;
|
|
15374
|
-
}
|
|
15375
|
-
this.animationComplete.emit({
|
|
15376
|
-
animation: this.props.animation || 'fade',
|
|
15377
|
-
winner: this.props.winner,
|
|
15378
|
-
});
|
|
15379
|
-
}, animationDuration);
|
|
15380
|
-
}, delay);
|
|
15381
|
-
}
|
|
15382
|
-
/**
|
|
15383
|
-
* Manually trigger the reveal animation.
|
|
15384
|
-
*/
|
|
15385
|
-
reveal() {
|
|
15386
|
-
this.isRevealed = false;
|
|
15387
|
-
this.showConfetti = false;
|
|
15388
|
-
this.startReveal();
|
|
15389
|
-
}
|
|
15390
|
-
/**
|
|
15391
|
-
* Reset to initial state.
|
|
15392
|
-
*/
|
|
15393
|
-
reset() {
|
|
15394
|
-
this.isAnimating = false;
|
|
15395
|
-
this.isRevealed = false;
|
|
15396
|
-
this.showConfetti = false;
|
|
15397
|
-
}
|
|
15398
|
-
formatTicketNumber() {
|
|
15399
|
-
const num = this.props.winner.ticketNumber;
|
|
15400
|
-
if (this.props.numberPadding) {
|
|
15401
|
-
return String(num).padStart(this.props.numberPadding, '0');
|
|
15402
|
-
}
|
|
15403
|
-
return String(num);
|
|
15404
|
-
}
|
|
15405
|
-
formatPrizeValue() {
|
|
15406
|
-
if (!this.props.winner.prizeValue)
|
|
15407
|
-
return '';
|
|
15408
|
-
return `$${this.props.winner.prizeValue.toLocaleString('es-MX')}`;
|
|
15409
|
-
}
|
|
15410
|
-
getRandomX(index) {
|
|
15411
|
-
return `${(index * 17) % 100}%`;
|
|
15412
|
-
}
|
|
15413
|
-
getRandomRotation(index) {
|
|
15414
|
-
return `${(index * 37) % 360}deg`;
|
|
15415
|
-
}
|
|
15416
|
-
getWinnerLabel() {
|
|
15417
|
-
return this.props.winnerLabel || DEFAULT_WINNER_LABELS.winner;
|
|
15418
|
-
}
|
|
15419
|
-
getTicketLabel() {
|
|
15420
|
-
return this.props.ticketLabel || DEFAULT_WINNER_LABELS.ticket;
|
|
15421
|
-
}
|
|
15422
|
-
getPrizeLabel() {
|
|
15423
|
-
return this.props.prizeLabel || DEFAULT_WINNER_LABELS.prize;
|
|
15424
|
-
}
|
|
15425
|
-
getColor() {
|
|
15426
|
-
if (this.props.color) {
|
|
15427
|
-
return `var(--ion-color-${this.props.color})`;
|
|
15428
|
-
}
|
|
15429
|
-
return 'var(--ion-color-warning)';
|
|
15430
|
-
}
|
|
15431
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WinnerDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
15432
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: WinnerDisplayComponent, isStandalone: true, selector: "val-winner-display", inputs: { props: "props" }, outputs: { animationComplete: "animationComplete" }, ngImport: i0, template: `
|
|
15433
|
-
<div
|
|
15434
|
-
class="winner-display-container"
|
|
15435
|
-
[class]="props.cssClass"
|
|
15436
|
-
[class.mode-compact]="props.mode === 'compact'"
|
|
15437
|
-
[class.mode-standard]="props.mode === 'standard' || !props.mode"
|
|
15438
|
-
[class.mode-full]="props.mode === 'full'"
|
|
15439
|
-
[class.mode-celebration]="props.mode === 'celebration'"
|
|
15440
|
-
[class.size-small]="props.size === 'small'"
|
|
15441
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
15442
|
-
[class.size-large]="props.size === 'large'"
|
|
15443
|
-
[class.bg-solid]="props.background === 'solid' || !props.background"
|
|
15444
|
-
[class.bg-gradient]="props.background === 'gradient'"
|
|
15445
|
-
[class.bg-transparent]="props.background === 'transparent'"
|
|
15446
|
-
[class.animating]="isAnimating"
|
|
15447
|
-
[class.revealed]="isRevealed"
|
|
15448
|
-
[class.animation-fade]="props.animation === 'fade'"
|
|
15449
|
-
[class.animation-zoom]="props.animation === 'zoom'"
|
|
15450
|
-
[class.animation-slide]="props.animation === 'slide'"
|
|
15451
|
-
[class.animation-spotlight]="props.animation === 'spotlight'"
|
|
15452
|
-
[style.--winner-color]="getColor()"
|
|
15453
|
-
[style.--animation-duration]="(props.animationDuration || 800) + 'ms'"
|
|
15454
|
-
>
|
|
15455
|
-
<!-- Confetti overlay -->
|
|
15456
|
-
@if (props.showConfetti && (props.mode === 'celebration' || props.mode === 'full')) {
|
|
15457
|
-
<div class="confetti-container" [class.active]="showConfetti">
|
|
15458
|
-
@for (i of confettiPieces; track i) {
|
|
15459
|
-
<div
|
|
15460
|
-
class="confetti-piece"
|
|
15461
|
-
[style.--delay]="i * 0.1 + 's'"
|
|
15462
|
-
[style.--x]="getRandomX(i)"
|
|
15463
|
-
[style.--rotation]="getRandomRotation(i)"
|
|
15464
|
-
></div>
|
|
15465
|
-
}
|
|
15466
|
-
</div>
|
|
15467
|
-
}
|
|
15468
|
-
|
|
15469
|
-
<!-- Trophy icon -->
|
|
15470
|
-
@if (props.showTrophy !== false) {
|
|
15471
|
-
<div class="trophy-container">
|
|
15472
|
-
<ion-icon name="trophy-outline" class="trophy-icon"></ion-icon>
|
|
15473
|
-
</div>
|
|
15474
|
-
}
|
|
15475
|
-
|
|
15476
|
-
<!-- Winner label -->
|
|
15477
|
-
<div class="winner-label">{{ getWinnerLabel() }}</div>
|
|
15478
|
-
|
|
15479
|
-
<!-- Winner info -->
|
|
15480
|
-
<div class="winner-info">
|
|
15481
|
-
<!-- Avatar -->
|
|
15482
|
-
@if (props.winner.avatar && (props.mode === 'full' || props.mode === 'celebration')) {
|
|
15483
|
-
<val-avatar [props]="props.winner.avatar" class="winner-avatar"></val-avatar>
|
|
15484
|
-
}
|
|
15485
|
-
|
|
15486
|
-
<!-- Name -->
|
|
15487
|
-
<h2 class="winner-name">{{ props.winner.name }}</h2>
|
|
15488
|
-
|
|
15489
|
-
<!-- Location -->
|
|
15490
|
-
@if (props.showLocation !== false && props.winner.location) {
|
|
15491
|
-
<div class="winner-location">
|
|
15492
|
-
<ion-icon name="location-outline"></ion-icon>
|
|
15493
|
-
<span>{{ props.winner.location }}</span>
|
|
15494
|
-
</div>
|
|
15495
|
-
}
|
|
15496
|
-
|
|
15497
|
-
<!-- Ticket number -->
|
|
15498
|
-
@if (props.showTicketNumber !== false) {
|
|
15499
|
-
<div class="ticket-info">
|
|
15500
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
15501
|
-
<span class="ticket-label">{{ getTicketLabel() }}</span>
|
|
15502
|
-
<span class="ticket-number">{{ formatTicketNumber() }}</span>
|
|
15503
|
-
</div>
|
|
15504
|
-
}
|
|
15505
|
-
</div>
|
|
15506
|
-
|
|
15507
|
-
<!-- Prize info -->
|
|
15508
|
-
@if (props.showPrize !== false && props.winner.prize) {
|
|
15509
|
-
<div class="prize-info">
|
|
15510
|
-
@if (props.winner.prizeImage && (props.mode === 'full' || props.mode === 'celebration')) {
|
|
15511
|
-
<div class="prize-image">
|
|
15512
|
-
<img [src]="props.winner.prizeImage" [alt]="props.winner.prize" />
|
|
15513
|
-
</div>
|
|
15514
|
-
}
|
|
15515
|
-
|
|
15516
|
-
<div class="prize-details">
|
|
15517
|
-
<div class="prize-header">
|
|
15518
|
-
<ion-icon name="gift-outline"></ion-icon>
|
|
15519
|
-
<span class="prize-label">{{ getPrizeLabel() }}</span>
|
|
15520
|
-
</div>
|
|
15521
|
-
<h3 class="prize-name">{{ props.winner.prize }}</h3>
|
|
15522
|
-
|
|
15523
|
-
@if (props.winner.prizeDescription) {
|
|
15524
|
-
<p class="prize-description">{{ props.winner.prizeDescription }}</p>
|
|
15525
|
-
}
|
|
15526
|
-
|
|
15527
|
-
@if (props.showPrizeValue !== false && props.winner.prizeValue) {
|
|
15528
|
-
<div class="prize-value">
|
|
15529
|
-
{{ formatPrizeValue() }}
|
|
15530
|
-
</div>
|
|
15531
|
-
}
|
|
15532
|
-
</div>
|
|
15533
|
-
</div>
|
|
15534
|
-
}
|
|
15535
|
-
</div>
|
|
15536
|
-
`, isInline: true, styles: [":host{display:block}.winner-display-container{--winner-color: var(--ion-color-warning);--animation-duration: .8s;position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;padding:32px 24px;border-radius:16px;overflow:hidden}.bg-solid{background:var(--ion-color-light);border:2px solid var(--winner-color)}.bg-gradient{background:linear-gradient(135deg,var(--ion-color-light) 0%,rgba(var(--ion-color-warning-rgb),.1) 100%);border:2px solid var(--winner-color)}.bg-transparent{background:transparent}.trophy-container{margin-bottom:16px}.trophy-icon{font-size:56px;color:var(--winner-color);filter:drop-shadow(0 4px 8px rgba(0,0,0,.1))}.winner-label{font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:2px;color:var(--winner-color);margin-bottom:8px}.winner-info{display:flex;flex-direction:column;align-items:center;gap:8px;margin-bottom:16px}.winner-avatar{margin-bottom:8px}.winner-name{font-size:28px;font-weight:700;color:var(--ion-color-dark);margin:0;line-height:1.2}.winner-location{display:flex;align-items:center;gap:4px;font-size:14px;color:var(--ion-color-medium-shade)}.winner-location ion-icon{font-size:16px}.ticket-info{display:flex;align-items:center;gap:8px;padding:8px 16px;background:rgba(var(--ion-color-dark-rgb),.05);border-radius:24px;margin-top:8px}.ticket-info ion-icon{font-size:20px;color:var(--winner-color)}.ticket-label{font-size:14px;color:var(--ion-color-medium-shade)}.ticket-number{font-size:18px;font-weight:700;color:var(--ion-color-dark);font-variant-numeric:tabular-nums}.prize-info{display:flex;flex-direction:column;align-items:center;gap:12px;padding:16px;background:var(--ion-color-light-shade);border-radius:12px;width:100%;max-width:400px}.prize-image{width:120px;height:120px;border-radius:8px;overflow:hidden;background:#fff;box-shadow:0 4px 12px #0000001a}.prize-image img{width:100%;height:100%;object-fit:cover}.prize-details{display:flex;flex-direction:column;align-items:center;gap:4px}.prize-header{display:flex;align-items:center;gap:4px;color:var(--ion-color-medium-shade);font-size:12px}.prize-header ion-icon{font-size:16px;color:var(--winner-color)}.prize-label{text-transform:uppercase;letter-spacing:1px}.prize-name{font-size:20px;font-weight:600;color:var(--ion-color-dark);margin:0}.prize-description{font-size:14px;color:var(--ion-color-medium-shade);margin:4px 0 0}.prize-value{font-size:24px;font-weight:700;color:var(--winner-color);margin-top:8px}.confetti-container{position:absolute;inset:0;pointer-events:none;overflow:hidden;opacity:0;transition:opacity .3s}.confetti-container.active{opacity:1}.confetti-piece{position:absolute;width:10px;height:10px;top:-20px;left:var(--x, 50%);background:var(--winner-color);opacity:0;animation:confetti-fall 3s ease-out var(--delay, 0s) forwards}.confetti-piece:nth-child(2n){background:var(--ion-color-primary);width:8px;height:12px}.confetti-piece:nth-child(3n){background:var(--ion-color-danger);border-radius:50%}.confetti-piece:nth-child(5n){background:var(--ion-color-success);width:6px;height:14px}@keyframes confetti-fall{0%{opacity:1;transform:translateY(0) rotate(0)}to{opacity:0;transform:translateY(400px) rotate(var(--rotation, 720deg))}}.animation-fade:not(.revealed) .winner-info,.animation-fade:not(.revealed) .prize-info{opacity:0}.animation-fade.animating .winner-info,.animation-fade.animating .prize-info{animation:fade-in var(--animation-duration) ease-out forwards}.animation-zoom:not(.revealed) .winner-info,.animation-zoom:not(.revealed) .prize-info{opacity:0;transform:scale(.5)}.animation-zoom.animating .winner-info,.animation-zoom.animating .prize-info{animation:zoom-in var(--animation-duration) cubic-bezier(.34,1.56,.64,1) forwards}.animation-slide:not(.revealed) .winner-info,.animation-slide:not(.revealed) .prize-info{opacity:0;transform:translateY(40px)}.animation-slide.animating .winner-info,.animation-slide.animating .prize-info{animation:slide-up var(--animation-duration) ease-out forwards}.animation-slide.animating .prize-info{animation-delay:.2s}.animation-spotlight:not(.revealed) .winner-info,.animation-spotlight:not(.revealed) .prize-info{opacity:0}.animation-spotlight:not(.revealed):before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:radial-gradient(circle,rgba(255,255,255,.8) 0%,transparent 70%);border-radius:50%;transform:translate(-50%,-50%)}.animation-spotlight.animating:before{animation:spotlight var(--animation-duration) ease-out forwards}.animation-spotlight.animating .winner-info,.animation-spotlight.animating .prize-info{animation:fade-in calc(var(--animation-duration) * .5) ease-out calc(var(--animation-duration) * .5) forwards}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes zoom-in{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}@keyframes slide-up{0%{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}}@keyframes spotlight{0%{width:0;height:0}to{width:200%;height:200%}}.size-small{padding:20px 16px}.size-small .trophy-icon{font-size:40px}.size-small .winner-label{font-size:12px}.size-small .winner-name{font-size:20px}.size-small .ticket-number,.size-small .prize-name{font-size:16px}.size-small .prize-value{font-size:18px}.size-large{padding:48px 32px}.size-large .trophy-icon{font-size:80px}.size-large .winner-label{font-size:18px;letter-spacing:3px}.size-large .winner-name{font-size:40px}.size-large .ticket-number{font-size:24px}.size-large .prize-image{width:160px;height:160px}.size-large .prize-name{font-size:28px}.size-large .prize-value{font-size:32px}.mode-compact{padding:16px}.mode-compact .trophy-container,.mode-compact .prize-info{display:none}.mode-compact .winner-label{font-size:11px;margin-bottom:4px}.mode-compact .winner-name{font-size:18px}.mode-celebration .trophy-icon{animation:trophy-bounce 1s ease-in-out infinite}.mode-celebration.revealed .winner-name{animation:glow 2s ease-in-out infinite}@keyframes trophy-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes glow{0%,to{text-shadow:0 0 10px rgba(var(--ion-color-warning-rgb),.3)}50%{text-shadow:0 0 20px rgba(var(--ion-color-warning-rgb),.6)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: AvatarComponent, selector: "val-avatar", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
|
|
15537
|
-
}
|
|
15538
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WinnerDisplayComponent, decorators: [{
|
|
15539
|
-
type: Component,
|
|
15540
|
-
args: [{ selector: 'val-winner-display', standalone: true, imports: [CommonModule, IonIcon, AvatarComponent], template: `
|
|
15541
|
-
<div
|
|
15542
|
-
class="winner-display-container"
|
|
15543
|
-
[class]="props.cssClass"
|
|
15544
|
-
[class.mode-compact]="props.mode === 'compact'"
|
|
15545
|
-
[class.mode-standard]="props.mode === 'standard' || !props.mode"
|
|
15546
|
-
[class.mode-full]="props.mode === 'full'"
|
|
15547
|
-
[class.mode-celebration]="props.mode === 'celebration'"
|
|
15548
|
-
[class.size-small]="props.size === 'small'"
|
|
15549
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
15550
|
-
[class.size-large]="props.size === 'large'"
|
|
15551
|
-
[class.bg-solid]="props.background === 'solid' || !props.background"
|
|
15552
|
-
[class.bg-gradient]="props.background === 'gradient'"
|
|
15553
|
-
[class.bg-transparent]="props.background === 'transparent'"
|
|
15554
|
-
[class.animating]="isAnimating"
|
|
15555
|
-
[class.revealed]="isRevealed"
|
|
15556
|
-
[class.animation-fade]="props.animation === 'fade'"
|
|
15557
|
-
[class.animation-zoom]="props.animation === 'zoom'"
|
|
15558
|
-
[class.animation-slide]="props.animation === 'slide'"
|
|
15559
|
-
[class.animation-spotlight]="props.animation === 'spotlight'"
|
|
15560
|
-
[style.--winner-color]="getColor()"
|
|
15561
|
-
[style.--animation-duration]="(props.animationDuration || 800) + 'ms'"
|
|
15562
|
-
>
|
|
15563
|
-
<!-- Confetti overlay -->
|
|
15564
|
-
@if (props.showConfetti && (props.mode === 'celebration' || props.mode === 'full')) {
|
|
15565
|
-
<div class="confetti-container" [class.active]="showConfetti">
|
|
15566
|
-
@for (i of confettiPieces; track i) {
|
|
15567
|
-
<div
|
|
15568
|
-
class="confetti-piece"
|
|
15569
|
-
[style.--delay]="i * 0.1 + 's'"
|
|
15570
|
-
[style.--x]="getRandomX(i)"
|
|
15571
|
-
[style.--rotation]="getRandomRotation(i)"
|
|
15572
|
-
></div>
|
|
15573
|
-
}
|
|
15574
|
-
</div>
|
|
15575
|
-
}
|
|
15576
|
-
|
|
15577
|
-
<!-- Trophy icon -->
|
|
15578
|
-
@if (props.showTrophy !== false) {
|
|
15579
|
-
<div class="trophy-container">
|
|
15580
|
-
<ion-icon name="trophy-outline" class="trophy-icon"></ion-icon>
|
|
15581
|
-
</div>
|
|
15582
|
-
}
|
|
15583
|
-
|
|
15584
|
-
<!-- Winner label -->
|
|
15585
|
-
<div class="winner-label">{{ getWinnerLabel() }}</div>
|
|
15586
|
-
|
|
15587
|
-
<!-- Winner info -->
|
|
15588
|
-
<div class="winner-info">
|
|
15589
|
-
<!-- Avatar -->
|
|
15590
|
-
@if (props.winner.avatar && (props.mode === 'full' || props.mode === 'celebration')) {
|
|
15591
|
-
<val-avatar [props]="props.winner.avatar" class="winner-avatar"></val-avatar>
|
|
15592
|
-
}
|
|
15593
|
-
|
|
15594
|
-
<!-- Name -->
|
|
15595
|
-
<h2 class="winner-name">{{ props.winner.name }}</h2>
|
|
15596
|
-
|
|
15597
|
-
<!-- Location -->
|
|
15598
|
-
@if (props.showLocation !== false && props.winner.location) {
|
|
15599
|
-
<div class="winner-location">
|
|
15600
|
-
<ion-icon name="location-outline"></ion-icon>
|
|
15601
|
-
<span>{{ props.winner.location }}</span>
|
|
15602
|
-
</div>
|
|
15603
|
-
}
|
|
15604
|
-
|
|
15605
|
-
<!-- Ticket number -->
|
|
15606
|
-
@if (props.showTicketNumber !== false) {
|
|
15607
|
-
<div class="ticket-info">
|
|
15608
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
15609
|
-
<span class="ticket-label">{{ getTicketLabel() }}</span>
|
|
15610
|
-
<span class="ticket-number">{{ formatTicketNumber() }}</span>
|
|
15611
|
-
</div>
|
|
15612
|
-
}
|
|
15613
|
-
</div>
|
|
15614
|
-
|
|
15615
|
-
<!-- Prize info -->
|
|
15616
|
-
@if (props.showPrize !== false && props.winner.prize) {
|
|
15617
|
-
<div class="prize-info">
|
|
15618
|
-
@if (props.winner.prizeImage && (props.mode === 'full' || props.mode === 'celebration')) {
|
|
15619
|
-
<div class="prize-image">
|
|
15620
|
-
<img [src]="props.winner.prizeImage" [alt]="props.winner.prize" />
|
|
15621
|
-
</div>
|
|
15622
|
-
}
|
|
15623
|
-
|
|
15624
|
-
<div class="prize-details">
|
|
15625
|
-
<div class="prize-header">
|
|
15626
|
-
<ion-icon name="gift-outline"></ion-icon>
|
|
15627
|
-
<span class="prize-label">{{ getPrizeLabel() }}</span>
|
|
15628
|
-
</div>
|
|
15629
|
-
<h3 class="prize-name">{{ props.winner.prize }}</h3>
|
|
15630
|
-
|
|
15631
|
-
@if (props.winner.prizeDescription) {
|
|
15632
|
-
<p class="prize-description">{{ props.winner.prizeDescription }}</p>
|
|
15633
|
-
}
|
|
15634
|
-
|
|
15635
|
-
@if (props.showPrizeValue !== false && props.winner.prizeValue) {
|
|
15636
|
-
<div class="prize-value">
|
|
15637
|
-
{{ formatPrizeValue() }}
|
|
15638
|
-
</div>
|
|
15639
|
-
}
|
|
15640
|
-
</div>
|
|
15641
|
-
</div>
|
|
15642
|
-
}
|
|
15643
|
-
</div>
|
|
15644
|
-
`, styles: [":host{display:block}.winner-display-container{--winner-color: var(--ion-color-warning);--animation-duration: .8s;position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;padding:32px 24px;border-radius:16px;overflow:hidden}.bg-solid{background:var(--ion-color-light);border:2px solid var(--winner-color)}.bg-gradient{background:linear-gradient(135deg,var(--ion-color-light) 0%,rgba(var(--ion-color-warning-rgb),.1) 100%);border:2px solid var(--winner-color)}.bg-transparent{background:transparent}.trophy-container{margin-bottom:16px}.trophy-icon{font-size:56px;color:var(--winner-color);filter:drop-shadow(0 4px 8px rgba(0,0,0,.1))}.winner-label{font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:2px;color:var(--winner-color);margin-bottom:8px}.winner-info{display:flex;flex-direction:column;align-items:center;gap:8px;margin-bottom:16px}.winner-avatar{margin-bottom:8px}.winner-name{font-size:28px;font-weight:700;color:var(--ion-color-dark);margin:0;line-height:1.2}.winner-location{display:flex;align-items:center;gap:4px;font-size:14px;color:var(--ion-color-medium-shade)}.winner-location ion-icon{font-size:16px}.ticket-info{display:flex;align-items:center;gap:8px;padding:8px 16px;background:rgba(var(--ion-color-dark-rgb),.05);border-radius:24px;margin-top:8px}.ticket-info ion-icon{font-size:20px;color:var(--winner-color)}.ticket-label{font-size:14px;color:var(--ion-color-medium-shade)}.ticket-number{font-size:18px;font-weight:700;color:var(--ion-color-dark);font-variant-numeric:tabular-nums}.prize-info{display:flex;flex-direction:column;align-items:center;gap:12px;padding:16px;background:var(--ion-color-light-shade);border-radius:12px;width:100%;max-width:400px}.prize-image{width:120px;height:120px;border-radius:8px;overflow:hidden;background:#fff;box-shadow:0 4px 12px #0000001a}.prize-image img{width:100%;height:100%;object-fit:cover}.prize-details{display:flex;flex-direction:column;align-items:center;gap:4px}.prize-header{display:flex;align-items:center;gap:4px;color:var(--ion-color-medium-shade);font-size:12px}.prize-header ion-icon{font-size:16px;color:var(--winner-color)}.prize-label{text-transform:uppercase;letter-spacing:1px}.prize-name{font-size:20px;font-weight:600;color:var(--ion-color-dark);margin:0}.prize-description{font-size:14px;color:var(--ion-color-medium-shade);margin:4px 0 0}.prize-value{font-size:24px;font-weight:700;color:var(--winner-color);margin-top:8px}.confetti-container{position:absolute;inset:0;pointer-events:none;overflow:hidden;opacity:0;transition:opacity .3s}.confetti-container.active{opacity:1}.confetti-piece{position:absolute;width:10px;height:10px;top:-20px;left:var(--x, 50%);background:var(--winner-color);opacity:0;animation:confetti-fall 3s ease-out var(--delay, 0s) forwards}.confetti-piece:nth-child(2n){background:var(--ion-color-primary);width:8px;height:12px}.confetti-piece:nth-child(3n){background:var(--ion-color-danger);border-radius:50%}.confetti-piece:nth-child(5n){background:var(--ion-color-success);width:6px;height:14px}@keyframes confetti-fall{0%{opacity:1;transform:translateY(0) rotate(0)}to{opacity:0;transform:translateY(400px) rotate(var(--rotation, 720deg))}}.animation-fade:not(.revealed) .winner-info,.animation-fade:not(.revealed) .prize-info{opacity:0}.animation-fade.animating .winner-info,.animation-fade.animating .prize-info{animation:fade-in var(--animation-duration) ease-out forwards}.animation-zoom:not(.revealed) .winner-info,.animation-zoom:not(.revealed) .prize-info{opacity:0;transform:scale(.5)}.animation-zoom.animating .winner-info,.animation-zoom.animating .prize-info{animation:zoom-in var(--animation-duration) cubic-bezier(.34,1.56,.64,1) forwards}.animation-slide:not(.revealed) .winner-info,.animation-slide:not(.revealed) .prize-info{opacity:0;transform:translateY(40px)}.animation-slide.animating .winner-info,.animation-slide.animating .prize-info{animation:slide-up var(--animation-duration) ease-out forwards}.animation-slide.animating .prize-info{animation-delay:.2s}.animation-spotlight:not(.revealed) .winner-info,.animation-spotlight:not(.revealed) .prize-info{opacity:0}.animation-spotlight:not(.revealed):before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;background:radial-gradient(circle,rgba(255,255,255,.8) 0%,transparent 70%);border-radius:50%;transform:translate(-50%,-50%)}.animation-spotlight.animating:before{animation:spotlight var(--animation-duration) ease-out forwards}.animation-spotlight.animating .winner-info,.animation-spotlight.animating .prize-info{animation:fade-in calc(var(--animation-duration) * .5) ease-out calc(var(--animation-duration) * .5) forwards}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes zoom-in{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}@keyframes slide-up{0%{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}}@keyframes spotlight{0%{width:0;height:0}to{width:200%;height:200%}}.size-small{padding:20px 16px}.size-small .trophy-icon{font-size:40px}.size-small .winner-label{font-size:12px}.size-small .winner-name{font-size:20px}.size-small .ticket-number,.size-small .prize-name{font-size:16px}.size-small .prize-value{font-size:18px}.size-large{padding:48px 32px}.size-large .trophy-icon{font-size:80px}.size-large .winner-label{font-size:18px;letter-spacing:3px}.size-large .winner-name{font-size:40px}.size-large .ticket-number{font-size:24px}.size-large .prize-image{width:160px;height:160px}.size-large .prize-name{font-size:28px}.size-large .prize-value{font-size:32px}.mode-compact{padding:16px}.mode-compact .trophy-container,.mode-compact .prize-info{display:none}.mode-compact .winner-label{font-size:11px;margin-bottom:4px}.mode-compact .winner-name{font-size:18px}.mode-celebration .trophy-icon{animation:trophy-bounce 1s ease-in-out infinite}.mode-celebration.revealed .winner-name{animation:glow 2s ease-in-out infinite}@keyframes trophy-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes glow{0%,to{text-shadow:0 0 10px rgba(var(--ion-color-warning-rgb),.3)}50%{text-shadow:0 0 20px rgba(var(--ion-color-warning-rgb),.6)}}\n"] }]
|
|
15645
|
-
}], propDecorators: { props: [{
|
|
15646
|
-
type: Input
|
|
15647
|
-
}], animationComplete: [{
|
|
15648
|
-
type: Output
|
|
15649
|
-
}] } });
|
|
15650
|
-
|
|
15651
|
-
/**
|
|
15652
|
-
* Default status labels.
|
|
15653
|
-
*/
|
|
15654
|
-
const DEFAULT_STATUS_LABELS = {
|
|
15655
|
-
upcoming: 'Próximamente',
|
|
15656
|
-
active: 'Activo',
|
|
15657
|
-
sold_out: 'Agotado',
|
|
15658
|
-
drawing: 'Sorteando',
|
|
15659
|
-
completed: 'Finalizado',
|
|
15660
|
-
cancelled: 'Cancelado',
|
|
15661
|
-
};
|
|
15662
|
-
/**
|
|
15663
|
-
* Default status colors.
|
|
15664
|
-
*/
|
|
15665
|
-
const DEFAULT_STATUS_COLORS = {
|
|
15666
|
-
upcoming: 'medium',
|
|
15667
|
-
active: 'success',
|
|
15668
|
-
sold_out: 'warning',
|
|
15669
|
-
drawing: 'tertiary',
|
|
15670
|
-
completed: 'primary',
|
|
15671
|
-
cancelled: 'danger',
|
|
15672
|
-
};
|
|
15673
|
-
|
|
15674
|
-
addIcons({
|
|
15675
|
-
ticketOutline,
|
|
15676
|
-
calendarOutline,
|
|
15677
|
-
giftOutline,
|
|
15678
|
-
heartOutline,
|
|
15679
|
-
timeOutline,
|
|
15680
|
-
});
|
|
15681
|
-
/**
|
|
15682
|
-
* val-raffle-status-card
|
|
15683
|
-
*
|
|
15684
|
-
* A card component for displaying raffle status and information.
|
|
15685
|
-
*
|
|
15686
|
-
* @example Basic usage
|
|
15687
|
-
* ```html
|
|
15688
|
-
* <val-raffle-status-card
|
|
15689
|
-
* [props]="{
|
|
15690
|
-
* title: 'Rifa Benéfica 2024',
|
|
15691
|
-
* status: 'active',
|
|
15692
|
-
* ticketPrice: 50,
|
|
15693
|
-
* progress: {
|
|
15694
|
-
* totalTickets: 1000,
|
|
15695
|
-
* soldTickets: 450
|
|
15696
|
-
* }
|
|
15697
|
-
* }"
|
|
15698
|
-
* ></val-raffle-status-card>
|
|
15699
|
-
* ```
|
|
15700
|
-
*
|
|
15701
|
-
* @example Featured with prize
|
|
15702
|
-
* ```html
|
|
15703
|
-
* <val-raffle-status-card
|
|
15704
|
-
* [props]="{
|
|
15705
|
-
* title: 'Gran Sorteo iPhone 15',
|
|
15706
|
-
* description: 'Participa y gana un iPhone 15 Pro Max',
|
|
15707
|
-
* status: 'active',
|
|
15708
|
-
* variant: 'featured',
|
|
15709
|
-
* coverImage: { src: 'cover.jpg' },
|
|
15710
|
-
* prize: {
|
|
15711
|
-
* name: 'iPhone 15 Pro Max 256GB',
|
|
15712
|
-
* value: 32000,
|
|
15713
|
-
* image: { src: 'iphone.jpg' }
|
|
15714
|
-
* },
|
|
15715
|
-
* ticketPrice: 100,
|
|
15716
|
-
* endDate: '2024-12-25',
|
|
15717
|
-
* showCountdown: true,
|
|
15718
|
-
* primaryAction: {
|
|
15719
|
-
* label: 'Comprar boletos',
|
|
15720
|
-
* color: 'success'
|
|
15721
|
-
* }
|
|
15722
|
-
* }"
|
|
15723
|
-
* ></val-raffle-status-card>
|
|
15724
|
-
* ```
|
|
15725
|
-
*/
|
|
15726
|
-
class RaffleStatusCardComponent {
|
|
15727
|
-
constructor() {
|
|
15728
|
-
this.primaryActionClick = new EventEmitter();
|
|
15729
|
-
this.secondaryActionClick = new EventEmitter();
|
|
15730
|
-
}
|
|
15731
|
-
get isActiveOrUpcoming() {
|
|
15732
|
-
return this.props.status === 'active' || this.props.status === 'upcoming';
|
|
15733
|
-
}
|
|
15734
|
-
get progressPercentage() {
|
|
15735
|
-
if (!this.props.progress)
|
|
15736
|
-
return 0;
|
|
15737
|
-
const { soldTickets, totalTickets } = this.props.progress;
|
|
15738
|
-
if (totalTickets === 0)
|
|
15739
|
-
return 0;
|
|
15740
|
-
return Math.round((soldTickets / totalTickets) * 100);
|
|
15741
|
-
}
|
|
15742
|
-
getStatusLabel() {
|
|
15743
|
-
const labels = { ...DEFAULT_STATUS_LABELS, ...this.props.statusLabels };
|
|
15744
|
-
return labels[this.props.status] || this.props.status;
|
|
15745
|
-
}
|
|
15746
|
-
getStatusColor() {
|
|
15747
|
-
if (this.props.statusColor)
|
|
15748
|
-
return this.props.statusColor;
|
|
15749
|
-
return DEFAULT_STATUS_COLORS[this.props.status] || 'medium';
|
|
15750
|
-
}
|
|
15751
|
-
getProgressColor() {
|
|
15752
|
-
if (this.progressPercentage >= 100)
|
|
15753
|
-
return 'success';
|
|
15754
|
-
if (this.progressPercentage >= 75)
|
|
15755
|
-
return 'warning';
|
|
15756
|
-
return 'primary';
|
|
15757
|
-
}
|
|
15758
|
-
getTitle() {
|
|
15759
|
-
return this.props.title || '';
|
|
15760
|
-
}
|
|
15761
|
-
getDescription() {
|
|
15762
|
-
return this.props.description || '';
|
|
15763
|
-
}
|
|
15764
|
-
formatCurrency(amount) {
|
|
15765
|
-
const symbol = this.props.currencySymbol || '$';
|
|
15766
|
-
return `${symbol}${amount.toLocaleString('es-MX')}`;
|
|
15767
|
-
}
|
|
15768
|
-
formatDate(date) {
|
|
15769
|
-
const d = typeof date === 'string' ? new Date(date) : date;
|
|
15770
|
-
return d.toLocaleDateString('es-MX', {
|
|
15771
|
-
day: 'numeric',
|
|
15772
|
-
month: 'short',
|
|
15773
|
-
year: 'numeric',
|
|
15774
|
-
});
|
|
15775
|
-
}
|
|
15776
|
-
onPrimaryAction() {
|
|
15777
|
-
this.primaryActionClick.emit();
|
|
15778
|
-
}
|
|
15779
|
-
onSecondaryAction() {
|
|
15780
|
-
this.secondaryActionClick.emit();
|
|
15781
|
-
}
|
|
15782
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RaffleStatusCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
15783
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RaffleStatusCardComponent, isStandalone: true, selector: "val-raffle-status-card", inputs: { props: "props" }, outputs: { primaryActionClick: "primaryActionClick", secondaryActionClick: "secondaryActionClick" }, ngImport: i0, template: `
|
|
15784
|
-
<article
|
|
15785
|
-
class="raffle-card"
|
|
15786
|
-
[class]="props.cssClass"
|
|
15787
|
-
[class.variant-default]="props.variant === 'default' || !props.variant"
|
|
15788
|
-
[class.variant-featured]="props.variant === 'featured'"
|
|
15789
|
-
[class.variant-compact]="props.variant === 'compact'"
|
|
15790
|
-
[class.variant-horizontal]="props.variant === 'horizontal'"
|
|
15791
|
-
[class.size-small]="props.size === 'small'"
|
|
15792
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
15793
|
-
[class.size-large]="props.size === 'large'"
|
|
15794
|
-
[class]="'status-' + props.status"
|
|
15795
|
-
>
|
|
15796
|
-
<!-- Cover image -->
|
|
15797
|
-
@if (props.coverImage && props.variant !== 'compact') {
|
|
15798
|
-
<div class="card-image">
|
|
15799
|
-
<val-image [props]="props.coverImage"></val-image>
|
|
15800
|
-
|
|
15801
|
-
<!-- Status badge over image -->
|
|
15802
|
-
@if (props.showStatusBadge !== false) {
|
|
15803
|
-
<ion-badge [color]="getStatusColor()" class="status-badge">
|
|
15804
|
-
{{ getStatusLabel() }}
|
|
15805
|
-
</ion-badge>
|
|
15806
|
-
}
|
|
15807
|
-
|
|
15808
|
-
<!-- Countdown overlay -->
|
|
15809
|
-
@if (props.showCountdown && props.endDate && isActiveOrUpcoming) {
|
|
15810
|
-
<div class="countdown-overlay">
|
|
15811
|
-
<val-countdown
|
|
15812
|
-
[props]="{
|
|
15813
|
-
targetDate: props.endDate,
|
|
15814
|
-
format: 'compact',
|
|
15815
|
-
size: 'small',
|
|
15816
|
-
color: 'light'
|
|
15817
|
-
}"
|
|
15818
|
-
></val-countdown>
|
|
15819
|
-
</div>
|
|
15820
|
-
}
|
|
15821
|
-
</div>
|
|
15822
|
-
}
|
|
15823
|
-
|
|
15824
|
-
<div class="card-content">
|
|
15825
|
-
<!-- Header -->
|
|
15826
|
-
<header class="card-header">
|
|
15827
|
-
@if (props.showStatusBadge !== false && (props.variant === 'compact' || !props.coverImage)) {
|
|
15828
|
-
<ion-badge [color]="getStatusColor()" class="status-badge inline">
|
|
15829
|
-
{{ getStatusLabel() }}
|
|
15830
|
-
</ion-badge>
|
|
15831
|
-
}
|
|
15832
|
-
|
|
15833
|
-
<h3 class="card-title">{{ getTitle() }}</h3>
|
|
15834
|
-
|
|
15835
|
-
@if (props.description) {
|
|
15836
|
-
<p class="card-description">{{ getDescription() }}</p>
|
|
15837
|
-
}
|
|
15838
|
-
</header>
|
|
15839
|
-
|
|
15840
|
-
<!-- Beneficiary -->
|
|
15841
|
-
@if (props.beneficiary) {
|
|
15842
|
-
<div class="beneficiary-info">
|
|
15843
|
-
<ion-icon name="heart-outline"></ion-icon>
|
|
15844
|
-
@if (props.beneficiaryImage) {
|
|
15845
|
-
<val-image [props]="props.beneficiaryImage" class="beneficiary-image"></val-image>
|
|
15846
|
-
}
|
|
15847
|
-
<span>{{ props.beneficiary }}</span>
|
|
15848
|
-
</div>
|
|
15849
|
-
}
|
|
15850
|
-
|
|
15851
|
-
<!-- Prize preview -->
|
|
15852
|
-
@if (props.prize && props.variant !== 'compact') {
|
|
15853
|
-
<div class="prize-preview">
|
|
15854
|
-
<div class="prize-header">
|
|
15855
|
-
<ion-icon name="gift-outline"></ion-icon>
|
|
15856
|
-
<span>Premio</span>
|
|
15857
|
-
</div>
|
|
15858
|
-
<div class="prize-name">{{ props.prize.name }}</div>
|
|
15859
|
-
@if (props.prize.value) {
|
|
15860
|
-
<div class="prize-value">
|
|
15861
|
-
{{ formatCurrency(props.prize.value) }}
|
|
15862
|
-
</div>
|
|
15863
|
-
}
|
|
15864
|
-
</div>
|
|
15865
|
-
}
|
|
15866
|
-
|
|
15867
|
-
<!-- Progress -->
|
|
15868
|
-
@if (props.showProgress !== false && props.progress) {
|
|
15869
|
-
<div class="progress-section">
|
|
15870
|
-
<div class="progress-header">
|
|
15871
|
-
<span class="progress-label">Progreso</span>
|
|
15872
|
-
<span class="progress-value">{{ progressPercentage }}%</span>
|
|
15873
|
-
</div>
|
|
15874
|
-
<ion-progress-bar
|
|
15875
|
-
[value]="progressPercentage / 100"
|
|
15876
|
-
[color]="getProgressColor()"
|
|
15877
|
-
></ion-progress-bar>
|
|
15878
|
-
</div>
|
|
15879
|
-
}
|
|
15880
|
-
|
|
15881
|
-
<!-- Ticket stats -->
|
|
15882
|
-
@if (props.showTicketStats !== false && props.progress) {
|
|
15883
|
-
<div class="ticket-stats">
|
|
15884
|
-
<div class="stat">
|
|
15885
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
15886
|
-
<span class="stat-value">{{ props.progress.soldTickets }}</span>
|
|
15887
|
-
<span class="stat-label">vendidos</span>
|
|
15888
|
-
</div>
|
|
15889
|
-
<div class="stat-divider"></div>
|
|
15890
|
-
<div class="stat">
|
|
15891
|
-
<span class="stat-value">{{ props.progress.totalTickets - props.progress.soldTickets }}</span>
|
|
15892
|
-
<span class="stat-label">disponibles</span>
|
|
15893
|
-
</div>
|
|
15894
|
-
</div>
|
|
15895
|
-
}
|
|
15896
|
-
|
|
15897
|
-
<!-- Price -->
|
|
15898
|
-
@if (props.showPrice !== false && props.ticketPrice) {
|
|
15899
|
-
<div class="price-section">
|
|
15900
|
-
<val-price-tag
|
|
15901
|
-
[props]="{
|
|
15902
|
-
amount: props.ticketPrice,
|
|
15903
|
-
currency: props.currency || 'MXN',
|
|
15904
|
-
currencySymbol: props.currencySymbol,
|
|
15905
|
-
period: 'por boleto',
|
|
15906
|
-
size: props.size === 'large' ? 'large' : 'medium',
|
|
15907
|
-
variant: 'highlight'
|
|
15908
|
-
}"
|
|
15909
|
-
></val-price-tag>
|
|
15910
|
-
</div>
|
|
15911
|
-
}
|
|
15912
|
-
|
|
15913
|
-
<!-- Dates -->
|
|
15914
|
-
@if (props.showDates !== false && (props.startDate || props.endDate)) {
|
|
15915
|
-
<div class="dates-section">
|
|
15916
|
-
@if (props.startDate) {
|
|
15917
|
-
<div class="date-item">
|
|
15918
|
-
<ion-icon name="calendar-outline"></ion-icon>
|
|
15919
|
-
<span>Inicia: {{ formatDate(props.startDate) }}</span>
|
|
15920
|
-
</div>
|
|
15921
|
-
}
|
|
15922
|
-
@if (props.endDate) {
|
|
15923
|
-
<div class="date-item">
|
|
15924
|
-
<ion-icon name="time-outline"></ion-icon>
|
|
15925
|
-
<span>Sorteo: {{ formatDate(props.endDate) }}</span>
|
|
15926
|
-
</div>
|
|
15927
|
-
}
|
|
15928
|
-
</div>
|
|
15929
|
-
}
|
|
15930
|
-
|
|
15931
|
-
<!-- Actions -->
|
|
15932
|
-
@if (props.primaryAction || props.secondaryAction) {
|
|
15933
|
-
<div class="card-actions">
|
|
15934
|
-
@if (props.primaryAction) {
|
|
15935
|
-
<val-button
|
|
15936
|
-
[props]="props.primaryAction"
|
|
15937
|
-
(click)="onPrimaryAction()"
|
|
15938
|
-
></val-button>
|
|
15939
|
-
}
|
|
15940
|
-
@if (props.secondaryAction) {
|
|
15941
|
-
<val-button
|
|
15942
|
-
[props]="props.secondaryAction"
|
|
15943
|
-
(click)="onSecondaryAction()"
|
|
15944
|
-
></val-button>
|
|
15945
|
-
}
|
|
15946
|
-
</div>
|
|
15947
|
-
}
|
|
15948
|
-
</div>
|
|
15949
|
-
</article>
|
|
15950
|
-
`, isInline: true, styles: [":host{display:block}.raffle-card{display:flex;flex-direction:column;background:var(--ion-color-light);border-radius:12px;overflow:hidden;box-shadow:0 2px 8px #00000014;transition:transform .2s,box-shadow .2s}.raffle-card:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.card-image{position:relative;aspect-ratio:16/9;overflow:hidden}.card-image val-image{width:100%;height:100%}.card-image val-image ::ng-deep img{width:100%;height:100%;object-fit:cover}.status-badge{position:absolute;top:12px;left:12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:4px 10px;border-radius:4px}.status-badge.inline{position:static;margin-bottom:8px}.countdown-overlay{position:absolute;bottom:0;left:0;right:0;padding:8px 12px;background:linear-gradient(transparent,#000000b3)}.card-content{display:flex;flex-direction:column;gap:12px;padding:16px}.card-header{display:flex;flex-direction:column;gap:4px}.card-title{font-size:18px;font-weight:600;color:var(--ion-color-dark);margin:0;line-height:1.3}.card-description{font-size:14px;color:var(--ion-color-medium-shade);margin:0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.beneficiary-info{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ion-color-medium-shade)}.beneficiary-info ion-icon{font-size:16px;color:var(--ion-color-danger)}.beneficiary-info .beneficiary-image{width:24px;height:24px;border-radius:50%;overflow:hidden}.prize-preview{padding:12px;background:var(--ion-color-light-shade);border-radius:8px}.prize-header{display:flex;align-items:center;gap:4px;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--ion-color-medium);margin-bottom:4px}.prize-header ion-icon{font-size:14px;color:var(--ion-color-warning)}.prize-name{font-size:15px;font-weight:600;color:var(--ion-color-dark)}.prize-value{font-size:18px;font-weight:700;color:var(--ion-color-success);margin-top:4px}.progress-section{display:flex;flex-direction:column;gap:6px}.progress-header{display:flex;justify-content:space-between;align-items:center}.progress-label{font-size:12px;color:var(--ion-color-medium-shade)}.progress-value{font-size:14px;font-weight:600;color:var(--ion-color-dark)}ion-progress-bar{height:8px;border-radius:4px;--background: var(--ion-color-light-shade)}.ticket-stats{display:flex;align-items:center;justify-content:center;gap:16px;padding:12px;background:var(--ion-color-light-shade);border-radius:8px}.stat{display:flex;align-items:center;gap:6px;font-size:13px}.stat ion-icon{font-size:18px;color:var(--ion-color-primary)}.stat-value{font-weight:700;color:var(--ion-color-dark);font-size:16px}.stat-label{color:var(--ion-color-medium-shade)}.stat-divider{width:1px;height:24px;background:var(--ion-color-medium-tint)}.price-section{display:flex;justify-content:center;padding:8px 0}.dates-section{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.date-item{display:flex;align-items:center;gap:6px}.date-item ion-icon{font-size:16px;color:var(--ion-color-primary)}.card-actions{display:flex;gap:8px;margin-top:4px}.card-actions val-button{flex:1}.variant-featured{border:2px solid var(--ion-color-warning)}.variant-featured .card-image{aspect-ratio:2/1}.variant-featured .card-title{font-size:22px}.variant-compact .card-content{padding:12px;gap:8px}.variant-compact .card-title{font-size:15px}.variant-compact .card-description{font-size:13px;-webkit-line-clamp:1}.variant-compact .ticket-stats,.variant-compact .dates-section{display:none}.variant-horizontal{flex-direction:row}.variant-horizontal .card-image{width:40%;min-width:150px;aspect-ratio:1}.variant-horizontal .card-content{flex:1;justify-content:center}.size-small .card-content{padding:12px;gap:8px}.size-small .card-title{font-size:15px}.size-small .card-description{font-size:12px}.size-small .ticket-stats{padding:8px}.size-small .stat-value{font-size:14px}.size-large .card-content{padding:24px;gap:16px}.size-large .card-title{font-size:24px}.size-large .card-description{font-size:16px}.size-large .prize-name{font-size:18px}.size-large .prize-value{font-size:22px}.status-upcoming{opacity:.9}.status-sold_out .card-image:after{content:\"\";position:absolute;inset:0;background:#0000004d}.status-completed .card-actions{opacity:.5;pointer-events:none}.status-cancelled{opacity:.6}.status-cancelled .card-image:after{content:\"\";position:absolute;inset:0;background:#0006}@media (max-width: 480px){.variant-horizontal{flex-direction:column}.variant-horizontal .card-image{width:100%;aspect-ratio:16/9}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { kind: "component", type: IonProgressBar, selector: "ion-progress-bar", inputs: ["buffer", "color", "mode", "reversed", "type", "value"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: CountdownComponent, selector: "val-countdown", inputs: ["props"], outputs: ["complete", "tick"] }, { kind: "component", type: PriceTagComponent, selector: "val-price-tag", inputs: ["props"] }] }); }
|
|
15951
|
-
}
|
|
15952
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RaffleStatusCardComponent, decorators: [{
|
|
15953
|
-
type: Component,
|
|
15954
|
-
args: [{ selector: 'val-raffle-status-card', standalone: true, imports: [
|
|
15955
|
-
CommonModule,
|
|
15956
|
-
IonIcon,
|
|
15957
|
-
IonBadge,
|
|
15958
|
-
IonProgressBar,
|
|
15959
|
-
ImageComponent,
|
|
15960
|
-
ButtonComponent,
|
|
15961
|
-
CountdownComponent,
|
|
15962
|
-
PriceTagComponent,
|
|
15963
|
-
], template: `
|
|
15964
|
-
<article
|
|
15965
|
-
class="raffle-card"
|
|
15966
|
-
[class]="props.cssClass"
|
|
15967
|
-
[class.variant-default]="props.variant === 'default' || !props.variant"
|
|
15968
|
-
[class.variant-featured]="props.variant === 'featured'"
|
|
15969
|
-
[class.variant-compact]="props.variant === 'compact'"
|
|
15970
|
-
[class.variant-horizontal]="props.variant === 'horizontal'"
|
|
15971
|
-
[class.size-small]="props.size === 'small'"
|
|
15972
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
15973
|
-
[class.size-large]="props.size === 'large'"
|
|
15974
|
-
[class]="'status-' + props.status"
|
|
15975
|
-
>
|
|
15976
|
-
<!-- Cover image -->
|
|
15977
|
-
@if (props.coverImage && props.variant !== 'compact') {
|
|
15978
|
-
<div class="card-image">
|
|
15979
|
-
<val-image [props]="props.coverImage"></val-image>
|
|
15980
|
-
|
|
15981
|
-
<!-- Status badge over image -->
|
|
15982
|
-
@if (props.showStatusBadge !== false) {
|
|
15983
|
-
<ion-badge [color]="getStatusColor()" class="status-badge">
|
|
15984
|
-
{{ getStatusLabel() }}
|
|
15985
|
-
</ion-badge>
|
|
15986
|
-
}
|
|
15987
|
-
|
|
15988
|
-
<!-- Countdown overlay -->
|
|
15989
|
-
@if (props.showCountdown && props.endDate && isActiveOrUpcoming) {
|
|
15990
|
-
<div class="countdown-overlay">
|
|
15991
|
-
<val-countdown
|
|
15992
|
-
[props]="{
|
|
15993
|
-
targetDate: props.endDate,
|
|
15994
|
-
format: 'compact',
|
|
15995
|
-
size: 'small',
|
|
15996
|
-
color: 'light'
|
|
15997
|
-
}"
|
|
15998
|
-
></val-countdown>
|
|
15999
|
-
</div>
|
|
16000
|
-
}
|
|
16001
|
-
</div>
|
|
16002
|
-
}
|
|
16003
|
-
|
|
16004
|
-
<div class="card-content">
|
|
16005
|
-
<!-- Header -->
|
|
16006
|
-
<header class="card-header">
|
|
16007
|
-
@if (props.showStatusBadge !== false && (props.variant === 'compact' || !props.coverImage)) {
|
|
16008
|
-
<ion-badge [color]="getStatusColor()" class="status-badge inline">
|
|
16009
|
-
{{ getStatusLabel() }}
|
|
16010
|
-
</ion-badge>
|
|
16011
|
-
}
|
|
16012
|
-
|
|
16013
|
-
<h3 class="card-title">{{ getTitle() }}</h3>
|
|
16014
|
-
|
|
16015
|
-
@if (props.description) {
|
|
16016
|
-
<p class="card-description">{{ getDescription() }}</p>
|
|
16017
|
-
}
|
|
16018
|
-
</header>
|
|
16019
|
-
|
|
16020
|
-
<!-- Beneficiary -->
|
|
16021
|
-
@if (props.beneficiary) {
|
|
16022
|
-
<div class="beneficiary-info">
|
|
16023
|
-
<ion-icon name="heart-outline"></ion-icon>
|
|
16024
|
-
@if (props.beneficiaryImage) {
|
|
16025
|
-
<val-image [props]="props.beneficiaryImage" class="beneficiary-image"></val-image>
|
|
16026
|
-
}
|
|
16027
|
-
<span>{{ props.beneficiary }}</span>
|
|
16028
|
-
</div>
|
|
16029
|
-
}
|
|
16030
|
-
|
|
16031
|
-
<!-- Prize preview -->
|
|
16032
|
-
@if (props.prize && props.variant !== 'compact') {
|
|
16033
|
-
<div class="prize-preview">
|
|
16034
|
-
<div class="prize-header">
|
|
16035
|
-
<ion-icon name="gift-outline"></ion-icon>
|
|
16036
|
-
<span>Premio</span>
|
|
16037
|
-
</div>
|
|
16038
|
-
<div class="prize-name">{{ props.prize.name }}</div>
|
|
16039
|
-
@if (props.prize.value) {
|
|
16040
|
-
<div class="prize-value">
|
|
16041
|
-
{{ formatCurrency(props.prize.value) }}
|
|
16042
|
-
</div>
|
|
16043
|
-
}
|
|
16044
|
-
</div>
|
|
16045
|
-
}
|
|
16046
|
-
|
|
16047
|
-
<!-- Progress -->
|
|
16048
|
-
@if (props.showProgress !== false && props.progress) {
|
|
16049
|
-
<div class="progress-section">
|
|
16050
|
-
<div class="progress-header">
|
|
16051
|
-
<span class="progress-label">Progreso</span>
|
|
16052
|
-
<span class="progress-value">{{ progressPercentage }}%</span>
|
|
16053
|
-
</div>
|
|
16054
|
-
<ion-progress-bar
|
|
16055
|
-
[value]="progressPercentage / 100"
|
|
16056
|
-
[color]="getProgressColor()"
|
|
16057
|
-
></ion-progress-bar>
|
|
16058
|
-
</div>
|
|
16059
|
-
}
|
|
16060
|
-
|
|
16061
|
-
<!-- Ticket stats -->
|
|
16062
|
-
@if (props.showTicketStats !== false && props.progress) {
|
|
16063
|
-
<div class="ticket-stats">
|
|
16064
|
-
<div class="stat">
|
|
16065
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
16066
|
-
<span class="stat-value">{{ props.progress.soldTickets }}</span>
|
|
16067
|
-
<span class="stat-label">vendidos</span>
|
|
16068
|
-
</div>
|
|
16069
|
-
<div class="stat-divider"></div>
|
|
16070
|
-
<div class="stat">
|
|
16071
|
-
<span class="stat-value">{{ props.progress.totalTickets - props.progress.soldTickets }}</span>
|
|
16072
|
-
<span class="stat-label">disponibles</span>
|
|
16073
|
-
</div>
|
|
16074
|
-
</div>
|
|
16075
|
-
}
|
|
16076
|
-
|
|
16077
|
-
<!-- Price -->
|
|
16078
|
-
@if (props.showPrice !== false && props.ticketPrice) {
|
|
16079
|
-
<div class="price-section">
|
|
16080
|
-
<val-price-tag
|
|
16081
|
-
[props]="{
|
|
16082
|
-
amount: props.ticketPrice,
|
|
16083
|
-
currency: props.currency || 'MXN',
|
|
16084
|
-
currencySymbol: props.currencySymbol,
|
|
16085
|
-
period: 'por boleto',
|
|
16086
|
-
size: props.size === 'large' ? 'large' : 'medium',
|
|
16087
|
-
variant: 'highlight'
|
|
16088
|
-
}"
|
|
16089
|
-
></val-price-tag>
|
|
16090
|
-
</div>
|
|
16091
|
-
}
|
|
16092
|
-
|
|
16093
|
-
<!-- Dates -->
|
|
16094
|
-
@if (props.showDates !== false && (props.startDate || props.endDate)) {
|
|
16095
|
-
<div class="dates-section">
|
|
16096
|
-
@if (props.startDate) {
|
|
16097
|
-
<div class="date-item">
|
|
16098
|
-
<ion-icon name="calendar-outline"></ion-icon>
|
|
16099
|
-
<span>Inicia: {{ formatDate(props.startDate) }}</span>
|
|
16100
|
-
</div>
|
|
16101
|
-
}
|
|
16102
|
-
@if (props.endDate) {
|
|
16103
|
-
<div class="date-item">
|
|
16104
|
-
<ion-icon name="time-outline"></ion-icon>
|
|
16105
|
-
<span>Sorteo: {{ formatDate(props.endDate) }}</span>
|
|
16106
|
-
</div>
|
|
16107
|
-
}
|
|
16108
|
-
</div>
|
|
16109
|
-
}
|
|
16110
|
-
|
|
16111
|
-
<!-- Actions -->
|
|
16112
|
-
@if (props.primaryAction || props.secondaryAction) {
|
|
16113
|
-
<div class="card-actions">
|
|
16114
|
-
@if (props.primaryAction) {
|
|
16115
|
-
<val-button
|
|
16116
|
-
[props]="props.primaryAction"
|
|
16117
|
-
(click)="onPrimaryAction()"
|
|
16118
|
-
></val-button>
|
|
16119
|
-
}
|
|
16120
|
-
@if (props.secondaryAction) {
|
|
16121
|
-
<val-button
|
|
16122
|
-
[props]="props.secondaryAction"
|
|
16123
|
-
(click)="onSecondaryAction()"
|
|
16124
|
-
></val-button>
|
|
16125
|
-
}
|
|
16126
|
-
</div>
|
|
16127
|
-
}
|
|
16128
|
-
</div>
|
|
16129
|
-
</article>
|
|
16130
|
-
`, styles: [":host{display:block}.raffle-card{display:flex;flex-direction:column;background:var(--ion-color-light);border-radius:12px;overflow:hidden;box-shadow:0 2px 8px #00000014;transition:transform .2s,box-shadow .2s}.raffle-card:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.card-image{position:relative;aspect-ratio:16/9;overflow:hidden}.card-image val-image{width:100%;height:100%}.card-image val-image ::ng-deep img{width:100%;height:100%;object-fit:cover}.status-badge{position:absolute;top:12px;left:12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:4px 10px;border-radius:4px}.status-badge.inline{position:static;margin-bottom:8px}.countdown-overlay{position:absolute;bottom:0;left:0;right:0;padding:8px 12px;background:linear-gradient(transparent,#000000b3)}.card-content{display:flex;flex-direction:column;gap:12px;padding:16px}.card-header{display:flex;flex-direction:column;gap:4px}.card-title{font-size:18px;font-weight:600;color:var(--ion-color-dark);margin:0;line-height:1.3}.card-description{font-size:14px;color:var(--ion-color-medium-shade);margin:0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.beneficiary-info{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ion-color-medium-shade)}.beneficiary-info ion-icon{font-size:16px;color:var(--ion-color-danger)}.beneficiary-info .beneficiary-image{width:24px;height:24px;border-radius:50%;overflow:hidden}.prize-preview{padding:12px;background:var(--ion-color-light-shade);border-radius:8px}.prize-header{display:flex;align-items:center;gap:4px;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--ion-color-medium);margin-bottom:4px}.prize-header ion-icon{font-size:14px;color:var(--ion-color-warning)}.prize-name{font-size:15px;font-weight:600;color:var(--ion-color-dark)}.prize-value{font-size:18px;font-weight:700;color:var(--ion-color-success);margin-top:4px}.progress-section{display:flex;flex-direction:column;gap:6px}.progress-header{display:flex;justify-content:space-between;align-items:center}.progress-label{font-size:12px;color:var(--ion-color-medium-shade)}.progress-value{font-size:14px;font-weight:600;color:var(--ion-color-dark)}ion-progress-bar{height:8px;border-radius:4px;--background: var(--ion-color-light-shade)}.ticket-stats{display:flex;align-items:center;justify-content:center;gap:16px;padding:12px;background:var(--ion-color-light-shade);border-radius:8px}.stat{display:flex;align-items:center;gap:6px;font-size:13px}.stat ion-icon{font-size:18px;color:var(--ion-color-primary)}.stat-value{font-weight:700;color:var(--ion-color-dark);font-size:16px}.stat-label{color:var(--ion-color-medium-shade)}.stat-divider{width:1px;height:24px;background:var(--ion-color-medium-tint)}.price-section{display:flex;justify-content:center;padding:8px 0}.dates-section{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.date-item{display:flex;align-items:center;gap:6px}.date-item ion-icon{font-size:16px;color:var(--ion-color-primary)}.card-actions{display:flex;gap:8px;margin-top:4px}.card-actions val-button{flex:1}.variant-featured{border:2px solid var(--ion-color-warning)}.variant-featured .card-image{aspect-ratio:2/1}.variant-featured .card-title{font-size:22px}.variant-compact .card-content{padding:12px;gap:8px}.variant-compact .card-title{font-size:15px}.variant-compact .card-description{font-size:13px;-webkit-line-clamp:1}.variant-compact .ticket-stats,.variant-compact .dates-section{display:none}.variant-horizontal{flex-direction:row}.variant-horizontal .card-image{width:40%;min-width:150px;aspect-ratio:1}.variant-horizontal .card-content{flex:1;justify-content:center}.size-small .card-content{padding:12px;gap:8px}.size-small .card-title{font-size:15px}.size-small .card-description{font-size:12px}.size-small .ticket-stats{padding:8px}.size-small .stat-value{font-size:14px}.size-large .card-content{padding:24px;gap:16px}.size-large .card-title{font-size:24px}.size-large .card-description{font-size:16px}.size-large .prize-name{font-size:18px}.size-large .prize-value{font-size:22px}.status-upcoming{opacity:.9}.status-sold_out .card-image:after{content:\"\";position:absolute;inset:0;background:#0000004d}.status-completed .card-actions{opacity:.5;pointer-events:none}.status-cancelled{opacity:.6}.status-cancelled .card-image:after{content:\"\";position:absolute;inset:0;background:#0006}@media (max-width: 480px){.variant-horizontal{flex-direction:column}.variant-horizontal .card-image{width:100%;aspect-ratio:16/9}}\n"] }]
|
|
16131
|
-
}], propDecorators: { props: [{
|
|
16132
|
-
type: Input
|
|
16133
|
-
}], primaryActionClick: [{
|
|
16134
|
-
type: Output
|
|
16135
|
-
}], secondaryActionClick: [{
|
|
16136
|
-
type: Output
|
|
16137
|
-
}] } });
|
|
16138
|
-
|
|
16139
|
-
/**
|
|
16140
|
-
* Default payment status labels.
|
|
16141
|
-
*/
|
|
16142
|
-
const DEFAULT_PAYMENT_STATUS_LABELS = {
|
|
16143
|
-
pending: 'Pendiente',
|
|
16144
|
-
processing: 'Procesando',
|
|
16145
|
-
paid: 'Pagado',
|
|
16146
|
-
refunded: 'Reembolsado',
|
|
16147
|
-
failed: 'Fallido',
|
|
16148
|
-
};
|
|
16149
|
-
/**
|
|
16150
|
-
* Default payment status colors.
|
|
16151
|
-
*/
|
|
16152
|
-
const DEFAULT_PAYMENT_STATUS_COLORS = {
|
|
16153
|
-
pending: 'warning',
|
|
16154
|
-
processing: 'tertiary',
|
|
16155
|
-
paid: 'success',
|
|
16156
|
-
refunded: 'medium',
|
|
16157
|
-
failed: 'danger',
|
|
16158
|
-
};
|
|
16159
|
-
|
|
16160
|
-
addIcons({
|
|
16161
|
-
personOutline,
|
|
16162
|
-
mailOutline,
|
|
16163
|
-
callOutline,
|
|
16164
|
-
ticketOutline,
|
|
16165
|
-
locationOutline,
|
|
16166
|
-
calendarOutline,
|
|
16167
|
-
trophyOutline,
|
|
16168
|
-
ellipsisVertical,
|
|
16169
|
-
checkmarkCircle,
|
|
16170
|
-
timeOutline,
|
|
16171
|
-
closeCircle,
|
|
16172
|
-
});
|
|
16173
|
-
/**
|
|
16174
|
-
* val-participant-card
|
|
16175
|
-
*
|
|
16176
|
-
* A card component for displaying participant information in a raffle.
|
|
16177
|
-
*
|
|
16178
|
-
* @example Basic usage
|
|
16179
|
-
* ```html
|
|
16180
|
-
* <val-participant-card
|
|
16181
|
-
* [props]="{
|
|
16182
|
-
* participant: {
|
|
16183
|
-
* id: '1',
|
|
16184
|
-
* name: 'Juan Pérez',
|
|
16185
|
-
* email: 'juan@email.com',
|
|
16186
|
-
* tickets: [42, 156, 789],
|
|
16187
|
-
* paymentStatus: 'paid'
|
|
16188
|
-
* }
|
|
16189
|
-
* }"
|
|
16190
|
-
* ></val-participant-card>
|
|
16191
|
-
* ```
|
|
16192
|
-
*
|
|
16193
|
-
* @example Admin variant with actions
|
|
16194
|
-
* ```html
|
|
16195
|
-
* <val-participant-card
|
|
16196
|
-
* [props]="{
|
|
16197
|
-
* participant: participant,
|
|
16198
|
-
* variant: 'admin',
|
|
16199
|
-
* showActions: true,
|
|
16200
|
-
* actions: [
|
|
16201
|
-
* { id: 'edit', label: 'Editar', icon: 'create-outline' },
|
|
16202
|
-
* { id: 'refund', label: 'Reembolsar', icon: 'cash-outline', color: 'warning' },
|
|
16203
|
-
* { id: 'delete', label: 'Eliminar', icon: 'trash-outline', destructive: true }
|
|
16204
|
-
* ]
|
|
16205
|
-
* }"
|
|
16206
|
-
* (cardClick)="onParticipantClick($event)"
|
|
16207
|
-
* (actionClick)="onActionClick($event)"
|
|
16208
|
-
* ></val-participant-card>
|
|
16209
|
-
* ```
|
|
16210
|
-
*
|
|
16211
|
-
* @example Winner highlight
|
|
16212
|
-
* ```html
|
|
16213
|
-
* <val-participant-card
|
|
16214
|
-
* [props]="{
|
|
16215
|
-
* participant: {
|
|
16216
|
-
* id: '1',
|
|
16217
|
-
* name: 'María García',
|
|
16218
|
-
* tickets: [{ number: 42, status: 'winner' }],
|
|
16219
|
-
* isWinner: true,
|
|
16220
|
-
* paymentStatus: 'paid'
|
|
16221
|
-
* },
|
|
16222
|
-
* highlightWinner: true,
|
|
16223
|
-
* variant: 'detailed'
|
|
16224
|
-
* }"
|
|
16225
|
-
* ></val-participant-card>
|
|
16226
|
-
* ```
|
|
16227
|
-
*/
|
|
16228
|
-
class ParticipantCardComponent {
|
|
16229
|
-
constructor() {
|
|
16230
|
-
this.cardClick = new EventEmitter();
|
|
16231
|
-
this.actionClick = new EventEmitter();
|
|
16232
|
-
this.i18n = inject(I18nService);
|
|
16233
|
-
this.showAllTickets = false;
|
|
16234
|
-
}
|
|
16235
|
-
/** Get winner badge text */
|
|
16236
|
-
getWinnerText() {
|
|
16237
|
-
return this.i18n.t('winner');
|
|
16238
|
-
}
|
|
16239
|
-
/** Get tickets count text */
|
|
16240
|
-
getTicketsCountText(count) {
|
|
16241
|
-
return `${count} ${count !== 1 ? this.i18n.t('tickets') : this.i18n.t('ticket')}`;
|
|
16242
|
-
}
|
|
16243
|
-
/** Get more tickets text */
|
|
16244
|
-
getMoreText(count) {
|
|
16245
|
-
return `+${count} ${this.i18n.t('more')}`;
|
|
16246
|
-
}
|
|
16247
|
-
/** Get notes label */
|
|
16248
|
-
getNotesLabel() {
|
|
16249
|
-
return this.i18n.t('notes');
|
|
16250
|
-
}
|
|
16251
|
-
get ticketNumbers() {
|
|
16252
|
-
return this.props.participant.tickets || [];
|
|
16253
|
-
}
|
|
16254
|
-
get visibleTickets() {
|
|
16255
|
-
const max = this.props.maxTicketsVisible || 5;
|
|
16256
|
-
if (this.showAllTickets || this.ticketNumbers.length <= max) {
|
|
16257
|
-
return this.ticketNumbers;
|
|
16258
|
-
}
|
|
16259
|
-
return this.ticketNumbers.slice(0, max);
|
|
16260
|
-
}
|
|
16261
|
-
get hiddenTicketsCount() {
|
|
16262
|
-
if (this.showAllTickets)
|
|
16263
|
-
return 0;
|
|
16264
|
-
const max = this.props.maxTicketsVisible || 5;
|
|
16265
|
-
return Math.max(0, this.ticketNumbers.length - max);
|
|
16266
|
-
}
|
|
16267
|
-
formatTicketNumber(ticket) {
|
|
16268
|
-
const num = typeof ticket === 'number' ? ticket : ticket.number;
|
|
16269
|
-
if (this.props.numberPadding) {
|
|
16270
|
-
return String(num).padStart(this.props.numberPadding, '0');
|
|
16271
|
-
}
|
|
16272
|
-
return String(num);
|
|
16273
|
-
}
|
|
16274
|
-
getTicketColor(ticket) {
|
|
16275
|
-
if (typeof ticket === 'number')
|
|
16276
|
-
return 'primary';
|
|
16277
|
-
switch (ticket.status) {
|
|
16278
|
-
case 'winner':
|
|
16279
|
-
return 'warning';
|
|
16280
|
-
case 'reserved':
|
|
16281
|
-
return 'tertiary';
|
|
16282
|
-
case 'cancelled':
|
|
16283
|
-
return 'medium';
|
|
16284
|
-
default:
|
|
16285
|
-
return 'primary';
|
|
16286
|
-
}
|
|
16287
|
-
}
|
|
16288
|
-
isWinnerTicket(ticket) {
|
|
16289
|
-
if (typeof ticket === 'number')
|
|
16290
|
-
return false;
|
|
16291
|
-
return ticket.status === 'winner';
|
|
16292
|
-
}
|
|
16293
|
-
getPaymentStatusLabel() {
|
|
16294
|
-
const status = this.props.participant.paymentStatus;
|
|
16295
|
-
if (!status)
|
|
16296
|
-
return '';
|
|
16297
|
-
// If custom labels are provided, use them first
|
|
16298
|
-
if (this.props.paymentStatusLabels?.[status]) {
|
|
16299
|
-
return this.props.paymentStatusLabels[status];
|
|
16300
|
-
}
|
|
16301
|
-
// Use i18n for default labels
|
|
16302
|
-
const i18nKeys = {
|
|
16303
|
-
pending: 'paymentPending',
|
|
16304
|
-
processing: 'paymentProcessing',
|
|
16305
|
-
paid: 'paymentPaid',
|
|
16306
|
-
refunded: 'paymentRefunded',
|
|
16307
|
-
failed: 'paymentFailed',
|
|
16308
|
-
};
|
|
16309
|
-
const key = i18nKeys[status];
|
|
16310
|
-
return key ? this.i18n.t(key) : status;
|
|
16311
|
-
}
|
|
16312
|
-
getPaymentStatusColor() {
|
|
16313
|
-
const status = this.props.participant.paymentStatus;
|
|
16314
|
-
if (!status)
|
|
16315
|
-
return 'medium';
|
|
16316
|
-
return DEFAULT_PAYMENT_STATUS_COLORS[status] || 'medium';
|
|
16317
|
-
}
|
|
16318
|
-
getPaymentStatusIcon() {
|
|
16319
|
-
const status = this.props.participant.paymentStatus;
|
|
16320
|
-
switch (status) {
|
|
16321
|
-
case 'paid':
|
|
16322
|
-
return 'checkmark-circle';
|
|
16323
|
-
case 'pending':
|
|
16324
|
-
case 'processing':
|
|
16325
|
-
return 'time-outline';
|
|
16326
|
-
case 'failed':
|
|
16327
|
-
case 'refunded':
|
|
16328
|
-
return 'close-circle';
|
|
16329
|
-
default:
|
|
16330
|
-
return 'time-outline';
|
|
16331
|
-
}
|
|
16332
|
-
}
|
|
16333
|
-
formatCurrency(amount) {
|
|
16334
|
-
const symbol = this.props.currencySymbol || '$';
|
|
16335
|
-
return `${symbol}${amount.toLocaleString('es-MX')}`;
|
|
16336
|
-
}
|
|
16337
|
-
formatDate(date) {
|
|
16338
|
-
const d = typeof date === 'string' ? new Date(date) : date;
|
|
16339
|
-
return d.toLocaleDateString('es-MX', {
|
|
16340
|
-
day: 'numeric',
|
|
16341
|
-
month: 'short',
|
|
16342
|
-
year: 'numeric',
|
|
16343
|
-
});
|
|
16344
|
-
}
|
|
16345
|
-
toggleShowAllTickets(event) {
|
|
16346
|
-
event.stopPropagation();
|
|
16347
|
-
this.showAllTickets = !this.showAllTickets;
|
|
16348
|
-
}
|
|
16349
|
-
onCardClick() {
|
|
16350
|
-
if (!this.props.clickable)
|
|
16351
|
-
return;
|
|
16352
|
-
this.cardClick.emit({
|
|
16353
|
-
participant: this.props.participant,
|
|
16354
|
-
});
|
|
16355
|
-
}
|
|
16356
|
-
onActionsClick(event) {
|
|
16357
|
-
event.stopPropagation();
|
|
16358
|
-
// In a real implementation, this would open a popover menu
|
|
16359
|
-
// For now, we'll emit the first action
|
|
16360
|
-
if (this.props.actions?.length) {
|
|
16361
|
-
this.actionClick.emit({
|
|
16362
|
-
actionId: this.props.actions[0].id,
|
|
16363
|
-
participant: this.props.participant,
|
|
16364
|
-
});
|
|
16365
|
-
}
|
|
16366
|
-
}
|
|
16367
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ParticipantCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
16368
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ParticipantCardComponent, isStandalone: true, selector: "val-participant-card", inputs: { props: "props" }, outputs: { cardClick: "cardClick", actionClick: "actionClick" }, ngImport: i0, template: `
|
|
16369
|
-
<article
|
|
16370
|
-
class="participant-card"
|
|
16371
|
-
[class]="props.cssClass"
|
|
16372
|
-
[class.variant-default]="props.variant === 'default' || !props.variant"
|
|
16373
|
-
[class.variant-compact]="props.variant === 'compact'"
|
|
16374
|
-
[class.variant-detailed]="props.variant === 'detailed'"
|
|
16375
|
-
[class.variant-admin]="props.variant === 'admin'"
|
|
16376
|
-
[class.size-small]="props.size === 'small'"
|
|
16377
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
16378
|
-
[class.size-large]="props.size === 'large'"
|
|
16379
|
-
[class.is-winner]="props.participant.isWinner && props.highlightWinner !== false"
|
|
16380
|
-
[class.clickable]="props.clickable"
|
|
16381
|
-
(click)="onCardClick()"
|
|
16382
|
-
>
|
|
16383
|
-
<!-- Winner badge -->
|
|
16384
|
-
@if (props.participant.isWinner && props.highlightWinner !== false) {
|
|
16385
|
-
<div class="winner-badge">
|
|
16386
|
-
<ion-icon name="trophy-outline"></ion-icon>
|
|
16387
|
-
<span>{{ getWinnerText() }}</span>
|
|
16388
|
-
</div>
|
|
16389
|
-
}
|
|
16390
|
-
|
|
16391
|
-
<!-- Main content -->
|
|
16392
|
-
<div class="card-main">
|
|
16393
|
-
<!-- Avatar -->
|
|
16394
|
-
@if (props.showAvatar !== false) {
|
|
16395
|
-
<div class="avatar-section">
|
|
16396
|
-
@if (props.participant.avatar) {
|
|
16397
|
-
<val-avatar [props]="props.participant.avatar"></val-avatar>
|
|
16398
|
-
} @else {
|
|
16399
|
-
<div class="default-avatar">
|
|
16400
|
-
<ion-icon name="person-outline"></ion-icon>
|
|
16401
|
-
</div>
|
|
16402
|
-
}
|
|
16403
|
-
</div>
|
|
16404
|
-
}
|
|
16405
|
-
|
|
16406
|
-
<!-- Info -->
|
|
16407
|
-
<div class="info-section">
|
|
16408
|
-
<h4 class="participant-name">{{ props.participant.name }}</h4>
|
|
16409
|
-
|
|
16410
|
-
@if (props.showEmail !== false && props.participant.email) {
|
|
16411
|
-
<div class="info-item">
|
|
16412
|
-
<ion-icon name="mail-outline"></ion-icon>
|
|
16413
|
-
<span>{{ props.participant.email }}</span>
|
|
16414
|
-
</div>
|
|
16415
|
-
}
|
|
16416
|
-
|
|
16417
|
-
@if (props.showPhone !== false && props.participant.phone) {
|
|
16418
|
-
<div class="info-item">
|
|
16419
|
-
<ion-icon name="call-outline"></ion-icon>
|
|
16420
|
-
<span>{{ props.participant.phone }}</span>
|
|
16421
|
-
</div>
|
|
16422
|
-
}
|
|
16423
|
-
|
|
16424
|
-
@if (props.participant.location) {
|
|
16425
|
-
<div class="info-item">
|
|
16426
|
-
<ion-icon name="location-outline"></ion-icon>
|
|
16427
|
-
<span>{{ props.participant.location }}</span>
|
|
16428
|
-
</div>
|
|
16429
|
-
}
|
|
16430
|
-
|
|
16431
|
-
@if (props.showDate !== false && props.participant.registrationDate) {
|
|
16432
|
-
<div class="info-item">
|
|
16433
|
-
<ion-icon name="calendar-outline"></ion-icon>
|
|
16434
|
-
<span>{{ formatDate(props.participant.registrationDate) }}</span>
|
|
16435
|
-
</div>
|
|
16436
|
-
}
|
|
16437
|
-
</div>
|
|
16438
|
-
|
|
16439
|
-
<!-- Status & Amount (right side) -->
|
|
16440
|
-
<div class="status-section">
|
|
16441
|
-
@if (props.showPaymentStatus !== false && props.participant.paymentStatus) {
|
|
16442
|
-
<ion-badge [color]="getPaymentStatusColor()" class="payment-badge">
|
|
16443
|
-
<ion-icon [name]="getPaymentStatusIcon()"></ion-icon>
|
|
16444
|
-
{{ getPaymentStatusLabel() }}
|
|
16445
|
-
</ion-badge>
|
|
16446
|
-
}
|
|
16447
|
-
|
|
16448
|
-
@if (props.showAmount !== false && props.participant.amountPaid) {
|
|
16449
|
-
<div class="amount">
|
|
16450
|
-
{{ formatCurrency(props.participant.amountPaid) }}
|
|
16451
|
-
</div>
|
|
16452
|
-
}
|
|
16453
|
-
</div>
|
|
16454
|
-
|
|
16455
|
-
<!-- Actions menu -->
|
|
16456
|
-
@if (props.showActions && props.actions?.length) {
|
|
16457
|
-
<ion-button
|
|
16458
|
-
fill="clear"
|
|
16459
|
-
class="actions-button"
|
|
16460
|
-
(click)="onActionsClick($event)"
|
|
16461
|
-
>
|
|
16462
|
-
<ion-icon slot="icon-only" name="ellipsis-vertical"></ion-icon>
|
|
16463
|
-
</ion-button>
|
|
16464
|
-
}
|
|
16465
|
-
</div>
|
|
16466
|
-
|
|
16467
|
-
<!-- Tickets section -->
|
|
16468
|
-
@if (props.showTickets !== false && ticketNumbers.length > 0) {
|
|
16469
|
-
<div class="tickets-section">
|
|
16470
|
-
<div class="tickets-header">
|
|
16471
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
16472
|
-
<span>{{ getTicketsCountText(ticketNumbers.length) }}</span>
|
|
16473
|
-
</div>
|
|
16474
|
-
|
|
16475
|
-
<div class="tickets-list">
|
|
16476
|
-
@for (ticket of visibleTickets; track $index) {
|
|
16477
|
-
<ion-chip
|
|
16478
|
-
[color]="getTicketColor(ticket)"
|
|
16479
|
-
[class.winner-ticket]="isWinnerTicket(ticket)"
|
|
16480
|
-
class="ticket-chip"
|
|
16481
|
-
>
|
|
16482
|
-
@if (isWinnerTicket(ticket)) {
|
|
16483
|
-
<ion-icon name="trophy-outline"></ion-icon>
|
|
16484
|
-
}
|
|
16485
|
-
{{ formatTicketNumber(ticket) }}
|
|
16486
|
-
</ion-chip>
|
|
16487
|
-
}
|
|
16488
|
-
|
|
16489
|
-
@if (hiddenTicketsCount > 0) {
|
|
16490
|
-
<ion-chip
|
|
16491
|
-
color="medium"
|
|
16492
|
-
class="more-tickets"
|
|
16493
|
-
(click)="toggleShowAllTickets($event)"
|
|
16494
|
-
>
|
|
16495
|
-
{{ getMoreText(hiddenTicketsCount) }}
|
|
16496
|
-
</ion-chip>
|
|
16497
|
-
}
|
|
16498
|
-
</div>
|
|
16499
|
-
</div>
|
|
16500
|
-
}
|
|
16501
|
-
|
|
16502
|
-
<!-- Notes (admin variant) -->
|
|
16503
|
-
@if (props.variant === 'admin' && props.participant.notes) {
|
|
16504
|
-
<div class="notes-section">
|
|
16505
|
-
<span class="notes-label">{{ getNotesLabel() }}</span>
|
|
16506
|
-
<p class="notes-text">{{ props.participant.notes }}</p>
|
|
16507
|
-
</div>
|
|
16508
|
-
}
|
|
16509
|
-
</article>
|
|
16510
|
-
`, isInline: true, styles: [":host{display:block}.participant-card{position:relative;display:flex;flex-direction:column;gap:12px;padding:16px;background:var(--ion-color-light);border-radius:12px;border:1px solid var(--ion-color-light-shade);transition:all .2s}.participant-card.clickable{cursor:pointer}.participant-card.clickable:hover{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium-tint)}.participant-card.clickable:active{transform:scale(.99)}.is-winner{border:2px solid var(--ion-color-warning);background:linear-gradient(135deg,var(--ion-color-light) 0%,rgba(var(--ion-color-warning-rgb),.1) 100%)}.winner-badge{position:absolute;top:-1px;right:16px;display:flex;align-items:center;gap:4px;padding:4px 12px;background:var(--ion-color-warning);color:var(--ion-color-warning-contrast);border-radius:0 0 8px 8px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.winner-badge ion-icon{font-size:14px}.card-main{display:flex;align-items:flex-start;gap:12px}.avatar-section{flex-shrink:0}.default-avatar{width:48px;height:48px;border-radius:50%;background:var(--ion-color-light-shade);display:flex;align-items:center;justify-content:center}.default-avatar ion-icon{font-size:24px;color:var(--ion-color-medium)}.info-section{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.participant-name{font-size:16px;font-weight:600;color:var(--ion-color-dark);margin:0;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-item{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.info-item ion-icon{font-size:14px;color:var(--ion-color-medium);flex-shrink:0}.info-item span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.status-section{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex-shrink:0}.payment-badge{display:flex;align-items:center;gap:4px;font-size:11px;font-weight:500;padding:4px 8px}.payment-badge ion-icon{font-size:12px}.amount{font-size:16px;font-weight:700;color:var(--ion-color-success)}.actions-button{--padding-start: 4px;--padding-end: 4px;margin:-8px -8px -8px 0}.tickets-section{display:flex;flex-direction:column;gap:8px;padding-top:12px;border-top:1px solid var(--ion-color-light-shade)}.tickets-header{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.tickets-header ion-icon{font-size:16px;color:var(--ion-color-primary)}.tickets-list{display:flex;flex-wrap:wrap;gap:6px}.ticket-chip{--padding-start: 10px;--padding-end: 10px;height:28px;font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.ticket-chip ion-icon{font-size:14px;margin-right:4px}.ticket-chip.winner-ticket{--background: var(--ion-color-warning);--color: var(--ion-color-warning-contrast)}.more-tickets{--padding-start: 8px;--padding-end: 8px;cursor:pointer;font-size:12px}.notes-section{padding-top:12px;border-top:1px solid var(--ion-color-light-shade)}.notes-label{font-size:12px;color:var(--ion-color-medium);text-transform:uppercase;letter-spacing:.5px}.notes-text{margin:4px 0 0;font-size:13px;color:var(--ion-color-dark-shade);line-height:1.4}.variant-compact{padding:12px;gap:8px}.variant-compact .avatar-section{display:none}.variant-compact .participant-name{font-size:14px}.variant-compact .info-item{font-size:12px}.variant-compact .tickets-section{padding-top:8px}.variant-detailed .info-section{gap:6px}.variant-detailed .info-item{font-size:14px}.variant-admin{border-left:4px solid var(--ion-color-primary)}.variant-admin.is-winner{border-left-color:var(--ion-color-warning)}.size-small{padding:10px;gap:8px}.size-small .default-avatar{width:36px;height:36px}.size-small .default-avatar ion-icon{font-size:18px}.size-small .participant-name{font-size:14px}.size-small .info-item{font-size:12px}.size-small .amount{font-size:14px}.size-small .ticket-chip{height:24px;font-size:11px;--padding-start: 8px;--padding-end: 8px}.size-large{padding:20px;gap:16px}.size-large .default-avatar{width:64px;height:64px}.size-large .default-avatar ion-icon{font-size:32px}.size-large .participant-name{font-size:20px}.size-large .info-item{font-size:15px}.size-large .info-item ion-icon{font-size:18px}.size-large .amount{font-size:20px}.size-large .ticket-chip{height:32px;font-size:14px}@media (max-width: 480px){.card-main{flex-wrap:wrap}.status-section{flex-direction:row;width:100%;justify-content:space-between;margin-top:8px;padding-top:8px;border-top:1px solid var(--ion-color-light-shade)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonBadge, selector: "ion-badge", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: AvatarComponent, selector: "val-avatar", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
|
|
16511
|
-
}
|
|
16512
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ParticipantCardComponent, decorators: [{
|
|
16513
|
-
type: Component,
|
|
16514
|
-
args: [{ selector: 'val-participant-card', standalone: true, imports: [CommonModule, IonIcon, IonBadge, IonButton, IonChip, AvatarComponent], template: `
|
|
16515
|
-
<article
|
|
16516
|
-
class="participant-card"
|
|
16517
|
-
[class]="props.cssClass"
|
|
16518
|
-
[class.variant-default]="props.variant === 'default' || !props.variant"
|
|
16519
|
-
[class.variant-compact]="props.variant === 'compact'"
|
|
16520
|
-
[class.variant-detailed]="props.variant === 'detailed'"
|
|
16521
|
-
[class.variant-admin]="props.variant === 'admin'"
|
|
16522
|
-
[class.size-small]="props.size === 'small'"
|
|
16523
|
-
[class.size-medium]="props.size === 'medium' || !props.size"
|
|
16524
|
-
[class.size-large]="props.size === 'large'"
|
|
16525
|
-
[class.is-winner]="props.participant.isWinner && props.highlightWinner !== false"
|
|
16526
|
-
[class.clickable]="props.clickable"
|
|
16527
|
-
(click)="onCardClick()"
|
|
16528
|
-
>
|
|
16529
|
-
<!-- Winner badge -->
|
|
16530
|
-
@if (props.participant.isWinner && props.highlightWinner !== false) {
|
|
16531
|
-
<div class="winner-badge">
|
|
16532
|
-
<ion-icon name="trophy-outline"></ion-icon>
|
|
16533
|
-
<span>{{ getWinnerText() }}</span>
|
|
16534
|
-
</div>
|
|
16535
|
-
}
|
|
16536
|
-
|
|
16537
|
-
<!-- Main content -->
|
|
16538
|
-
<div class="card-main">
|
|
16539
|
-
<!-- Avatar -->
|
|
16540
|
-
@if (props.showAvatar !== false) {
|
|
16541
|
-
<div class="avatar-section">
|
|
16542
|
-
@if (props.participant.avatar) {
|
|
16543
|
-
<val-avatar [props]="props.participant.avatar"></val-avatar>
|
|
16544
|
-
} @else {
|
|
16545
|
-
<div class="default-avatar">
|
|
16546
|
-
<ion-icon name="person-outline"></ion-icon>
|
|
16547
|
-
</div>
|
|
16548
|
-
}
|
|
16549
|
-
</div>
|
|
16550
|
-
}
|
|
16551
|
-
|
|
16552
|
-
<!-- Info -->
|
|
16553
|
-
<div class="info-section">
|
|
16554
|
-
<h4 class="participant-name">{{ props.participant.name }}</h4>
|
|
16555
|
-
|
|
16556
|
-
@if (props.showEmail !== false && props.participant.email) {
|
|
16557
|
-
<div class="info-item">
|
|
16558
|
-
<ion-icon name="mail-outline"></ion-icon>
|
|
16559
|
-
<span>{{ props.participant.email }}</span>
|
|
16560
|
-
</div>
|
|
16561
|
-
}
|
|
16562
|
-
|
|
16563
|
-
@if (props.showPhone !== false && props.participant.phone) {
|
|
16564
|
-
<div class="info-item">
|
|
16565
|
-
<ion-icon name="call-outline"></ion-icon>
|
|
16566
|
-
<span>{{ props.participant.phone }}</span>
|
|
16567
|
-
</div>
|
|
16568
|
-
}
|
|
16569
|
-
|
|
16570
|
-
@if (props.participant.location) {
|
|
16571
|
-
<div class="info-item">
|
|
16572
|
-
<ion-icon name="location-outline"></ion-icon>
|
|
16573
|
-
<span>{{ props.participant.location }}</span>
|
|
16574
|
-
</div>
|
|
16575
|
-
}
|
|
16576
|
-
|
|
16577
|
-
@if (props.showDate !== false && props.participant.registrationDate) {
|
|
16578
|
-
<div class="info-item">
|
|
16579
|
-
<ion-icon name="calendar-outline"></ion-icon>
|
|
16580
|
-
<span>{{ formatDate(props.participant.registrationDate) }}</span>
|
|
16581
|
-
</div>
|
|
16582
|
-
}
|
|
16583
|
-
</div>
|
|
16584
|
-
|
|
16585
|
-
<!-- Status & Amount (right side) -->
|
|
16586
|
-
<div class="status-section">
|
|
16587
|
-
@if (props.showPaymentStatus !== false && props.participant.paymentStatus) {
|
|
16588
|
-
<ion-badge [color]="getPaymentStatusColor()" class="payment-badge">
|
|
16589
|
-
<ion-icon [name]="getPaymentStatusIcon()"></ion-icon>
|
|
16590
|
-
{{ getPaymentStatusLabel() }}
|
|
16591
|
-
</ion-badge>
|
|
16592
|
-
}
|
|
16593
|
-
|
|
16594
|
-
@if (props.showAmount !== false && props.participant.amountPaid) {
|
|
16595
|
-
<div class="amount">
|
|
16596
|
-
{{ formatCurrency(props.participant.amountPaid) }}
|
|
16597
|
-
</div>
|
|
16598
|
-
}
|
|
16599
|
-
</div>
|
|
16600
|
-
|
|
16601
|
-
<!-- Actions menu -->
|
|
16602
|
-
@if (props.showActions && props.actions?.length) {
|
|
16603
|
-
<ion-button
|
|
16604
|
-
fill="clear"
|
|
16605
|
-
class="actions-button"
|
|
16606
|
-
(click)="onActionsClick($event)"
|
|
16607
|
-
>
|
|
16608
|
-
<ion-icon slot="icon-only" name="ellipsis-vertical"></ion-icon>
|
|
16609
|
-
</ion-button>
|
|
16610
|
-
}
|
|
16611
|
-
</div>
|
|
16612
|
-
|
|
16613
|
-
<!-- Tickets section -->
|
|
16614
|
-
@if (props.showTickets !== false && ticketNumbers.length > 0) {
|
|
16615
|
-
<div class="tickets-section">
|
|
16616
|
-
<div class="tickets-header">
|
|
16617
|
-
<ion-icon name="ticket-outline"></ion-icon>
|
|
16618
|
-
<span>{{ getTicketsCountText(ticketNumbers.length) }}</span>
|
|
16619
|
-
</div>
|
|
16620
|
-
|
|
16621
|
-
<div class="tickets-list">
|
|
16622
|
-
@for (ticket of visibleTickets; track $index) {
|
|
16623
|
-
<ion-chip
|
|
16624
|
-
[color]="getTicketColor(ticket)"
|
|
16625
|
-
[class.winner-ticket]="isWinnerTicket(ticket)"
|
|
16626
|
-
class="ticket-chip"
|
|
16627
|
-
>
|
|
16628
|
-
@if (isWinnerTicket(ticket)) {
|
|
16629
|
-
<ion-icon name="trophy-outline"></ion-icon>
|
|
16630
|
-
}
|
|
16631
|
-
{{ formatTicketNumber(ticket) }}
|
|
16632
|
-
</ion-chip>
|
|
16633
|
-
}
|
|
16634
|
-
|
|
16635
|
-
@if (hiddenTicketsCount > 0) {
|
|
16636
|
-
<ion-chip
|
|
16637
|
-
color="medium"
|
|
16638
|
-
class="more-tickets"
|
|
16639
|
-
(click)="toggleShowAllTickets($event)"
|
|
16640
|
-
>
|
|
16641
|
-
{{ getMoreText(hiddenTicketsCount) }}
|
|
16642
|
-
</ion-chip>
|
|
16643
|
-
}
|
|
16644
|
-
</div>
|
|
16645
|
-
</div>
|
|
16646
|
-
}
|
|
16647
|
-
|
|
16648
|
-
<!-- Notes (admin variant) -->
|
|
16649
|
-
@if (props.variant === 'admin' && props.participant.notes) {
|
|
16650
|
-
<div class="notes-section">
|
|
16651
|
-
<span class="notes-label">{{ getNotesLabel() }}</span>
|
|
16652
|
-
<p class="notes-text">{{ props.participant.notes }}</p>
|
|
16653
|
-
</div>
|
|
16654
|
-
}
|
|
16655
|
-
</article>
|
|
16656
|
-
`, styles: [":host{display:block}.participant-card{position:relative;display:flex;flex-direction:column;gap:12px;padding:16px;background:var(--ion-color-light);border-radius:12px;border:1px solid var(--ion-color-light-shade);transition:all .2s}.participant-card.clickable{cursor:pointer}.participant-card.clickable:hover{background:var(--ion-color-light-shade);border-color:var(--ion-color-medium-tint)}.participant-card.clickable:active{transform:scale(.99)}.is-winner{border:2px solid var(--ion-color-warning);background:linear-gradient(135deg,var(--ion-color-light) 0%,rgba(var(--ion-color-warning-rgb),.1) 100%)}.winner-badge{position:absolute;top:-1px;right:16px;display:flex;align-items:center;gap:4px;padding:4px 12px;background:var(--ion-color-warning);color:var(--ion-color-warning-contrast);border-radius:0 0 8px 8px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.winner-badge ion-icon{font-size:14px}.card-main{display:flex;align-items:flex-start;gap:12px}.avatar-section{flex-shrink:0}.default-avatar{width:48px;height:48px;border-radius:50%;background:var(--ion-color-light-shade);display:flex;align-items:center;justify-content:center}.default-avatar ion-icon{font-size:24px;color:var(--ion-color-medium)}.info-section{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.participant-name{font-size:16px;font-weight:600;color:var(--ion-color-dark);margin:0;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-item{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.info-item ion-icon{font-size:14px;color:var(--ion-color-medium);flex-shrink:0}.info-item span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.status-section{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex-shrink:0}.payment-badge{display:flex;align-items:center;gap:4px;font-size:11px;font-weight:500;padding:4px 8px}.payment-badge ion-icon{font-size:12px}.amount{font-size:16px;font-weight:700;color:var(--ion-color-success)}.actions-button{--padding-start: 4px;--padding-end: 4px;margin:-8px -8px -8px 0}.tickets-section{display:flex;flex-direction:column;gap:8px;padding-top:12px;border-top:1px solid var(--ion-color-light-shade)}.tickets-header{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--ion-color-medium-shade)}.tickets-header ion-icon{font-size:16px;color:var(--ion-color-primary)}.tickets-list{display:flex;flex-wrap:wrap;gap:6px}.ticket-chip{--padding-start: 10px;--padding-end: 10px;height:28px;font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.ticket-chip ion-icon{font-size:14px;margin-right:4px}.ticket-chip.winner-ticket{--background: var(--ion-color-warning);--color: var(--ion-color-warning-contrast)}.more-tickets{--padding-start: 8px;--padding-end: 8px;cursor:pointer;font-size:12px}.notes-section{padding-top:12px;border-top:1px solid var(--ion-color-light-shade)}.notes-label{font-size:12px;color:var(--ion-color-medium);text-transform:uppercase;letter-spacing:.5px}.notes-text{margin:4px 0 0;font-size:13px;color:var(--ion-color-dark-shade);line-height:1.4}.variant-compact{padding:12px;gap:8px}.variant-compact .avatar-section{display:none}.variant-compact .participant-name{font-size:14px}.variant-compact .info-item{font-size:12px}.variant-compact .tickets-section{padding-top:8px}.variant-detailed .info-section{gap:6px}.variant-detailed .info-item{font-size:14px}.variant-admin{border-left:4px solid var(--ion-color-primary)}.variant-admin.is-winner{border-left-color:var(--ion-color-warning)}.size-small{padding:10px;gap:8px}.size-small .default-avatar{width:36px;height:36px}.size-small .default-avatar ion-icon{font-size:18px}.size-small .participant-name{font-size:14px}.size-small .info-item{font-size:12px}.size-small .amount{font-size:14px}.size-small .ticket-chip{height:24px;font-size:11px;--padding-start: 8px;--padding-end: 8px}.size-large{padding:20px;gap:16px}.size-large .default-avatar{width:64px;height:64px}.size-large .default-avatar ion-icon{font-size:32px}.size-large .participant-name{font-size:20px}.size-large .info-item{font-size:15px}.size-large .info-item ion-icon{font-size:18px}.size-large .amount{font-size:20px}.size-large .ticket-chip{height:32px;font-size:14px}@media (max-width: 480px){.card-main{flex-wrap:wrap}.status-section{flex-direction:row;width:100%;justify-content:space-between;margin-top:8px;padding-top:8px;border-top:1px solid var(--ion-color-light-shade)}}\n"] }]
|
|
16657
|
-
}], propDecorators: { props: [{
|
|
16658
|
-
type: Input
|
|
16659
|
-
}], cardClick: [{
|
|
16660
|
-
type: Output
|
|
16661
|
-
}], actionClick: [{
|
|
16662
|
-
type: Output
|
|
16663
|
-
}] } });
|
|
16664
|
-
|
|
16665
14799
|
/**
|
|
16666
14800
|
* val-glow-card
|
|
16667
14801
|
*
|
|
@@ -17177,77 +15311,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
17177
15311
|
args: ['swiperContainer']
|
|
17178
15312
|
}] } });
|
|
17179
15313
|
|
|
17180
|
-
/**
|
|
17181
|
-
* val-recap-card
|
|
17182
|
-
*
|
|
17183
|
-
* A decorative card component with geometric shapes, title, and link.
|
|
17184
|
-
* Useful for recap sections, feature highlights, or promotional content.
|
|
17185
|
-
*
|
|
17186
|
-
* @example
|
|
17187
|
-
* <val-recap-card
|
|
17188
|
-
* [props]="{
|
|
17189
|
-
* title: { title: 'Feature Title', subtitle: 'Subtitle here' },
|
|
17190
|
-
* link: { text: 'Learn more', url: '/features' },
|
|
17191
|
-
* color: 'primary',
|
|
17192
|
-
* shapes: [
|
|
17193
|
-
* { color: '#ffffff33', style: { top: '-20px', right: '-20px', width: '100px', height: '100px' } }
|
|
17194
|
-
* ]
|
|
17195
|
-
* }"
|
|
17196
|
-
* ></val-recap-card>
|
|
17197
|
-
*
|
|
17198
|
-
* @input props - Card configuration (title, link, shapes, color)
|
|
17199
|
-
*/
|
|
17200
|
-
class RecapCardComponent {
|
|
17201
|
-
/**
|
|
17202
|
-
* Merges shape color with additional styles.
|
|
17203
|
-
*/
|
|
17204
|
-
mergeShapeStyle(shape) {
|
|
17205
|
-
return { 'background-color': shape.color, ...(shape.style || {}) };
|
|
17206
|
-
}
|
|
17207
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RecapCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
17208
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RecapCardComponent, isStandalone: true, selector: "val-recap-card", inputs: { props: "props" }, ngImport: i0, template: `
|
|
17209
|
-
<ion-card class="recap-card" [color]="props.color || ''">
|
|
17210
|
-
<div class="shapes">
|
|
17211
|
-
<ng-container *ngFor="let shape of props.shapes">
|
|
17212
|
-
<div class="shape" [ngStyle]="mergeShapeStyle(shape)"></div>
|
|
17213
|
-
</ng-container>
|
|
17214
|
-
</div>
|
|
17215
|
-
<ion-card-content
|
|
17216
|
-
class="recap-card__content"
|
|
17217
|
-
[style.min-height]="props.minHeight || '400px'"
|
|
17218
|
-
[style.min-width]="props.width || '280px'"
|
|
17219
|
-
[style.max-width]="props.width || '280px'"
|
|
17220
|
-
>
|
|
17221
|
-
<val-title-block [props]="props.title" />
|
|
17222
|
-
<val-link [props]="props.link" />
|
|
17223
|
-
</ion-card-content>
|
|
17224
|
-
</ion-card>
|
|
17225
|
-
`, isInline: true, styles: [".recap-card{border-radius:24px;box-shadow:0 4px 10px #0000001a;margin:10px;position:relative;overflow:hidden}.recap-card .shapes{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.7;pointer-events:none}.recap-card .shapes .shape{position:absolute;border-radius:50%}.recap-card .recap-card__content{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:400px;min-width:280px;max-width:280px;padding:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: LinkComponent, selector: "val-link", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: TitleBlockComponent, selector: "val-title-block", inputs: ["props"] }] }); }
|
|
17226
|
-
}
|
|
17227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RecapCardComponent, decorators: [{
|
|
17228
|
-
type: Component,
|
|
17229
|
-
args: [{ selector: 'val-recap-card', standalone: true, imports: [CommonModule, IonCard, IonCardContent, LinkComponent, TitleBlockComponent], template: `
|
|
17230
|
-
<ion-card class="recap-card" [color]="props.color || ''">
|
|
17231
|
-
<div class="shapes">
|
|
17232
|
-
<ng-container *ngFor="let shape of props.shapes">
|
|
17233
|
-
<div class="shape" [ngStyle]="mergeShapeStyle(shape)"></div>
|
|
17234
|
-
</ng-container>
|
|
17235
|
-
</div>
|
|
17236
|
-
<ion-card-content
|
|
17237
|
-
class="recap-card__content"
|
|
17238
|
-
[style.min-height]="props.minHeight || '400px'"
|
|
17239
|
-
[style.min-width]="props.width || '280px'"
|
|
17240
|
-
[style.max-width]="props.width || '280px'"
|
|
17241
|
-
>
|
|
17242
|
-
<val-title-block [props]="props.title" />
|
|
17243
|
-
<val-link [props]="props.link" />
|
|
17244
|
-
</ion-card-content>
|
|
17245
|
-
</ion-card>
|
|
17246
|
-
`, styles: [".recap-card{border-radius:24px;box-shadow:0 4px 10px #0000001a;margin:10px;position:relative;overflow:hidden}.recap-card .shapes{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.7;pointer-events:none}.recap-card .shapes .shape{position:absolute;border-radius:50%}.recap-card .recap-card__content{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:400px;min-width:280px;max-width:280px;padding:16px}\n"] }]
|
|
17247
|
-
}], propDecorators: { props: [{
|
|
17248
|
-
type: Input
|
|
17249
|
-
}] } });
|
|
17250
|
-
|
|
17251
15314
|
/**
|
|
17252
15315
|
* val-testimonial-card
|
|
17253
15316
|
*
|
|
@@ -25466,17 +23529,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
25466
23529
|
/**
|
|
25467
23530
|
* val-cards-carousel
|
|
25468
23531
|
*
|
|
25469
|
-
* A horizontal carousel of
|
|
25470
|
-
* Combines HorizontalScroll for smooth horizontal scrolling with
|
|
25471
|
-
*
|
|
23532
|
+
* A horizontal carousel of cards with optional action header.
|
|
23533
|
+
* Combines HorizontalScroll for smooth horizontal scrolling with inline
|
|
23534
|
+
* card rendering for consistent card styling.
|
|
25472
23535
|
*
|
|
25473
23536
|
* @example
|
|
25474
23537
|
* <val-cards-carousel
|
|
25475
23538
|
* [props]="{
|
|
25476
23539
|
* header: { title: 'Featured Items', actionType: 'link', actionLabel: 'View All' },
|
|
25477
23540
|
* cards: [
|
|
25478
|
-
* { title: 'Card 1',
|
|
25479
|
-
* { title: 'Card 2',
|
|
23541
|
+
* { title: { title: 'Card 1' }, link: { text: 'Learn more', url: '/item/1' } },
|
|
23542
|
+
* { title: { title: 'Card 2' }, link: { text: 'Learn more', url: '/item/2' } }
|
|
25480
23543
|
* ]
|
|
25481
23544
|
* }"
|
|
25482
23545
|
* ></val-cards-carousel>
|
|
@@ -25490,30 +23553,74 @@ class CardsCarouselComponent {
|
|
|
25490
23553
|
*/
|
|
25491
23554
|
this.props = { cards: [] };
|
|
25492
23555
|
}
|
|
23556
|
+
/**
|
|
23557
|
+
* Merges shape color with additional styles.
|
|
23558
|
+
*/
|
|
23559
|
+
mergeShapeStyle(shape) {
|
|
23560
|
+
return { 'background-color': shape.color, ...(shape.style || {}) };
|
|
23561
|
+
}
|
|
25493
23562
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CardsCarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
25494
23563
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CardsCarouselComponent, isStandalone: true, selector: "val-cards-carousel", inputs: { props: "props" }, ngImport: i0, template: `
|
|
25495
23564
|
@if (props.header) {
|
|
25496
23565
|
<val-action-header [props]="props.header" />
|
|
25497
23566
|
}
|
|
25498
23567
|
|
|
25499
|
-
<val-horizontal-scroll [items]="props.cards" [itemTemplate]="
|
|
25500
|
-
<ng-template #
|
|
25501
|
-
<
|
|
23568
|
+
<val-horizontal-scroll [items]="props.cards" [itemTemplate]="cardTemplate" />
|
|
23569
|
+
<ng-template #cardTemplate let-card>
|
|
23570
|
+
<ion-card class="carousel-card" [color]="card.color || ''">
|
|
23571
|
+
<div class="shapes">
|
|
23572
|
+
<ng-container *ngFor="let shape of card.shapes">
|
|
23573
|
+
<div class="shape" [ngStyle]="mergeShapeStyle(shape)"></div>
|
|
23574
|
+
</ng-container>
|
|
23575
|
+
</div>
|
|
23576
|
+
<ion-card-content
|
|
23577
|
+
class="carousel-card__content"
|
|
23578
|
+
[style.min-height]="card.minHeight || '400px'"
|
|
23579
|
+
[style.min-width]="card.width || '280px'"
|
|
23580
|
+
[style.max-width]="card.width || '280px'"
|
|
23581
|
+
>
|
|
23582
|
+
<val-title-block [props]="card.title" />
|
|
23583
|
+
<val-link [props]="card.link" />
|
|
23584
|
+
</ion-card-content>
|
|
23585
|
+
</ion-card>
|
|
25502
23586
|
</ng-template>
|
|
25503
|
-
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "
|
|
23587
|
+
`, isInline: true, styles: [":host{display:block}.carousel-card{border-radius:24px;box-shadow:0 4px 10px #0000001a;margin:10px;position:relative;overflow:hidden;.shapes{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.7;pointer-events:none;.shape{position:absolute;border-radius:50%}}.carousel-card__content{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-between;height:100%;padding:16px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HorizontalScrollComponent, selector: "val-horizontal-scroll", inputs: ["items", "itemTemplate", "props"] }, { kind: "component", type: ActionHeaderComponent, selector: "val-action-header", inputs: ["props"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: LinkComponent, selector: "val-link", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: TitleBlockComponent, selector: "val-title-block", inputs: ["props"] }] }); }
|
|
25504
23588
|
}
|
|
25505
23589
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CardsCarouselComponent, decorators: [{
|
|
25506
23590
|
type: Component,
|
|
25507
|
-
args: [{ selector: 'val-cards-carousel', standalone: true, imports: [
|
|
23591
|
+
args: [{ selector: 'val-cards-carousel', standalone: true, imports: [
|
|
23592
|
+
CommonModule,
|
|
23593
|
+
HorizontalScrollComponent,
|
|
23594
|
+
ActionHeaderComponent,
|
|
23595
|
+
IonCard,
|
|
23596
|
+
IonCardContent,
|
|
23597
|
+
LinkComponent,
|
|
23598
|
+
TitleBlockComponent,
|
|
23599
|
+
], template: `
|
|
25508
23600
|
@if (props.header) {
|
|
25509
23601
|
<val-action-header [props]="props.header" />
|
|
25510
23602
|
}
|
|
25511
23603
|
|
|
25512
|
-
<val-horizontal-scroll [items]="props.cards" [itemTemplate]="
|
|
25513
|
-
<ng-template #
|
|
25514
|
-
<
|
|
23604
|
+
<val-horizontal-scroll [items]="props.cards" [itemTemplate]="cardTemplate" />
|
|
23605
|
+
<ng-template #cardTemplate let-card>
|
|
23606
|
+
<ion-card class="carousel-card" [color]="card.color || ''">
|
|
23607
|
+
<div class="shapes">
|
|
23608
|
+
<ng-container *ngFor="let shape of card.shapes">
|
|
23609
|
+
<div class="shape" [ngStyle]="mergeShapeStyle(shape)"></div>
|
|
23610
|
+
</ng-container>
|
|
23611
|
+
</div>
|
|
23612
|
+
<ion-card-content
|
|
23613
|
+
class="carousel-card__content"
|
|
23614
|
+
[style.min-height]="card.minHeight || '400px'"
|
|
23615
|
+
[style.min-width]="card.width || '280px'"
|
|
23616
|
+
[style.max-width]="card.width || '280px'"
|
|
23617
|
+
>
|
|
23618
|
+
<val-title-block [props]="card.title" />
|
|
23619
|
+
<val-link [props]="card.link" />
|
|
23620
|
+
</ion-card-content>
|
|
23621
|
+
</ion-card>
|
|
25515
23622
|
</ng-template>
|
|
25516
|
-
`, styles: [":host{display:block}\n"] }]
|
|
23623
|
+
`, styles: [":host{display:block}.carousel-card{border-radius:24px;box-shadow:0 4px 10px #0000001a;margin:10px;position:relative;overflow:hidden;.shapes{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.7;pointer-events:none;.shape{position:absolute;border-radius:50%}}.carousel-card__content{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-between;height:100%;padding:16px}}\n"] }]
|
|
25517
23624
|
}], propDecorators: { props: [{
|
|
25518
23625
|
type: Input
|
|
25519
23626
|
}] } });
|
|
@@ -30829,13 +28936,16 @@ class AuthService {
|
|
|
30829
28936
|
this.stateService.updateRefreshToken(response.refreshToken); // NUEVO: guardar refresh rotado
|
|
30830
28937
|
this.storageService.saveAccessToken(response.accessToken, expiresAt);
|
|
30831
28938
|
this.storageService.saveRefreshToken(response.refreshToken); // NUEVO: persistir refresh rotado
|
|
28939
|
+
if (this.config.enableFirebaseIntegration && response.firebaseToken) {
|
|
28940
|
+
this.signInWithFirebase(response.firebaseToken);
|
|
28941
|
+
}
|
|
30832
28942
|
this.startRefreshTimer();
|
|
30833
28943
|
this.syncService.broadcast({
|
|
30834
28944
|
type: 'TOKEN_REFRESH',
|
|
30835
28945
|
payload: {
|
|
30836
28946
|
accessToken: response.accessToken,
|
|
30837
28947
|
refreshToken: response.refreshToken, // NUEVO: sincronizar entre tabs
|
|
30838
|
-
expiresAt
|
|
28948
|
+
expiresAt,
|
|
30839
28949
|
},
|
|
30840
28950
|
});
|
|
30841
28951
|
}), catchError$1(error => {
|
|
@@ -30977,9 +29087,7 @@ class AuthService {
|
|
|
30977
29087
|
* ```
|
|
30978
29088
|
*/
|
|
30979
29089
|
switchOrg(organizationId) {
|
|
30980
|
-
return this.http
|
|
30981
|
-
.post(`${this.baseUrl}/switch-org`, { organizationId })
|
|
30982
|
-
.pipe(switchMap$1(response => {
|
|
29090
|
+
return this.http.post(`${this.baseUrl}/switch-org`, { organizationId }).pipe(switchMap$1(response => {
|
|
30983
29091
|
// Re-autenticar en Firebase con el nuevo token
|
|
30984
29092
|
// Usar switchMap + from para esperar a que Firebase complete
|
|
30985
29093
|
const firebaseAuth$ = response.firebaseToken
|
|
@@ -31350,7 +29458,7 @@ class AuthService {
|
|
|
31350
29458
|
console.warn('[ValtechAuth] MessagingService not available');
|
|
31351
29459
|
return { granted: false };
|
|
31352
29460
|
}
|
|
31353
|
-
if (!await this.messagingService.isSupported()) {
|
|
29461
|
+
if (!(await this.messagingService.isSupported())) {
|
|
31354
29462
|
console.warn('[ValtechAuth] Push notifications not supported');
|
|
31355
29463
|
return { granted: false };
|
|
31356
29464
|
}
|
|
@@ -31389,9 +29497,11 @@ class AuthService {
|
|
|
31389
29497
|
const token = this.messagingService.currentToken;
|
|
31390
29498
|
if (token) {
|
|
31391
29499
|
// Eliminar del backend
|
|
31392
|
-
await firstValueFrom(this.http
|
|
31393
|
-
|
|
31394
|
-
|
|
29500
|
+
await firstValueFrom(this.http
|
|
29501
|
+
.request('DELETE', `${this.config.apiUrl}/v2/users/me/devices/by-token`, {
|
|
29502
|
+
body: { token },
|
|
29503
|
+
})
|
|
29504
|
+
.pipe(catchError$1(() => of(null))));
|
|
31395
29505
|
// Eliminar token de FCM
|
|
31396
29506
|
await this.messagingService.deleteToken();
|
|
31397
29507
|
console.log('[ValtechAuth] Notifications disabled');
|
|
@@ -31448,7 +29558,7 @@ class AuthService {
|
|
|
31448
29558
|
let token = providedToken || this.messagingService?.currentToken;
|
|
31449
29559
|
// Si no hay token, intentar obtenerlo del MessagingService
|
|
31450
29560
|
if (!token && this.messagingService) {
|
|
31451
|
-
if (!await this.messagingService.isSupported()) {
|
|
29561
|
+
if (!(await this.messagingService.isSupported())) {
|
|
31452
29562
|
return { registered: false, error: 'FCM no soportado en este navegador' };
|
|
31453
29563
|
}
|
|
31454
29564
|
token = await this.messagingService.getToken();
|
|
@@ -31458,7 +29568,12 @@ class AuthService {
|
|
|
31458
29568
|
}
|
|
31459
29569
|
// Registrar en backend
|
|
31460
29570
|
const { platform, browser, os } = this.detectPlatformInfo();
|
|
31461
|
-
const response = await firstValueFrom(this.http.post(`${this.config.apiUrl}/v2/users/me/devices`, {
|
|
29571
|
+
const response = await firstValueFrom(this.http.post(`${this.config.apiUrl}/v2/users/me/devices`, {
|
|
29572
|
+
token,
|
|
29573
|
+
platform,
|
|
29574
|
+
browser,
|
|
29575
|
+
os,
|
|
29576
|
+
}));
|
|
31462
29577
|
console.log('[ValtechAuth] Device registered manually:', response.device.deviceId);
|
|
31463
29578
|
return { registered: true, deviceId: response.device.deviceId, token };
|
|
31464
29579
|
}
|
|
@@ -31466,7 +29581,7 @@ class AuthService {
|
|
|
31466
29581
|
console.warn('[ValtechAuth] Manual device registration failed:', error);
|
|
31467
29582
|
return {
|
|
31468
29583
|
registered: false,
|
|
31469
|
-
error: error?.error?.message || error?.message || 'Error al registrar dispositivo'
|
|
29584
|
+
error: error?.error?.message || error?.message || 'Error al registrar dispositivo',
|
|
31470
29585
|
};
|
|
31471
29586
|
}
|
|
31472
29587
|
}
|
|
@@ -31481,7 +29596,7 @@ class AuthService {
|
|
|
31481
29596
|
}
|
|
31482
29597
|
try {
|
|
31483
29598
|
// Verificar si FCM está soportado
|
|
31484
|
-
if (!await this.messagingService.isSupported()) {
|
|
29599
|
+
if (!(await this.messagingService.isSupported())) {
|
|
31485
29600
|
return false;
|
|
31486
29601
|
}
|
|
31487
29602
|
// Verificar si ya tiene permisos
|
|
@@ -31496,7 +29611,12 @@ class AuthService {
|
|
|
31496
29611
|
}
|
|
31497
29612
|
// Registrar en backend
|
|
31498
29613
|
const { platform, browser, os } = this.detectPlatformInfo();
|
|
31499
|
-
await firstValueFrom(this.http.post(`${this.config.apiUrl}/v2/users/me/devices`, {
|
|
29614
|
+
await firstValueFrom(this.http.post(`${this.config.apiUrl}/v2/users/me/devices`, {
|
|
29615
|
+
token,
|
|
29616
|
+
platform,
|
|
29617
|
+
browser,
|
|
29618
|
+
os,
|
|
29619
|
+
}));
|
|
31500
29620
|
console.log('[ValtechAuth] Device registered successfully');
|
|
31501
29621
|
return true;
|
|
31502
29622
|
}
|
|
@@ -31517,9 +29637,12 @@ class AuthService {
|
|
|
31517
29637
|
const token = this.messagingService.currentToken;
|
|
31518
29638
|
if (token) {
|
|
31519
29639
|
// Delete from backend (fire and forget)
|
|
31520
|
-
this.http
|
|
31521
|
-
|
|
31522
|
-
|
|
29640
|
+
this.http
|
|
29641
|
+
.request('DELETE', `${this.config.apiUrl}/v2/users/me/devices/by-token`, {
|
|
29642
|
+
body: { token },
|
|
29643
|
+
})
|
|
29644
|
+
.pipe(catchError$1(() => of(null)))
|
|
29645
|
+
.subscribe();
|
|
31523
29646
|
// Delete from FCM
|
|
31524
29647
|
await this.messagingService.deleteToken();
|
|
31525
29648
|
console.log('[ValtechAuth] Device unregistered');
|
|
@@ -34569,23 +32692,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
34569
32692
|
type: Output
|
|
34570
32693
|
}] } });
|
|
34571
32694
|
|
|
34572
|
-
class LayoutComponent {
|
|
34573
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
34574
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LayoutComponent, isStandalone: true, selector: "val-layout", ngImport: i0, template: `
|
|
34575
|
-
<div class="layout-container">
|
|
34576
|
-
<ng-content></ng-content>
|
|
34577
|
-
</div>
|
|
34578
|
-
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.layout-container{margin:0 auto;padding:0;width:100%;box-sizing:border-box;margin-bottom:1rem;padding-top:.5rem}@media (max-width: 768px){.layout-container{max-width:100%}}@media (min-width: 768px){.layout-container{margin:0 auto;max-width:33.75rem;margin-bottom:1.5rem}}@media (min-width: 1200px){.layout-container{margin:0 auto;max-width:45rem}}\n"] }); }
|
|
34579
|
-
}
|
|
34580
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LayoutComponent, decorators: [{
|
|
34581
|
-
type: Component,
|
|
34582
|
-
args: [{ selector: 'val-layout', standalone: true, imports: [], template: `
|
|
34583
|
-
<div class="layout-container">
|
|
34584
|
-
<ng-content></ng-content>
|
|
34585
|
-
</div>
|
|
34586
|
-
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.layout-container{margin:0 auto;padding:0;width:100%;box-sizing:border-box;margin-bottom:1rem;padding-top:.5rem}@media (max-width: 768px){.layout-container{max-width:100%}}@media (min-width: 768px){.layout-container{margin:0 auto;max-width:33.75rem;margin-bottom:1.5rem}}@media (min-width: 1200px){.layout-container{margin:0 auto;max-width:45rem}}\n"] }]
|
|
34587
|
-
}] });
|
|
34588
|
-
|
|
34589
32695
|
class SimpleComponent {
|
|
34590
32696
|
constructor() {
|
|
34591
32697
|
this.onClick = new EventEmitter();
|
|
@@ -34633,12 +32739,12 @@ class SimpleComponent {
|
|
|
34633
32739
|
@if (props.withDivider) {
|
|
34634
32740
|
<val-divider [props]="{ fill: 'solid', size: 'medium', color: 'dark' }" />
|
|
34635
32741
|
}
|
|
34636
|
-
<
|
|
32742
|
+
<div class="layout-container">
|
|
34637
32743
|
<ng-content select="[inner-container]"></ng-content>
|
|
34638
|
-
</
|
|
32744
|
+
</div>
|
|
34639
32745
|
</ion-content>
|
|
34640
32746
|
<ng-content select="[outter-container]"></ng-content>
|
|
34641
|
-
`, isInline: true, styles: [".description-container{padding:0 16px}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: HeaderComponent, selector: "val-header", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type:
|
|
32747
|
+
`, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.description-container{padding:0 16px}.layout-container{margin:0 auto;padding:0;width:100%;box-sizing:border-box;margin-bottom:1rem;padding-top:.5rem}@media (max-width: 768px){.layout-container{max-width:100%}}@media (min-width: 768px){.layout-container{margin:0 auto;max-width:33.75rem;margin-bottom:1.5rem}}@media (min-width: 1200px){.layout-container{margin:0 auto;max-width:45rem}}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: HeaderComponent, selector: "val-header", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: DividerComponent, selector: "val-divider", inputs: ["props"] }, { kind: "component", type: LinkComponent, selector: "val-link", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: ExpandableTextComponent, selector: "val-expandable-text", inputs: ["props"] }] }); }
|
|
34642
32748
|
}
|
|
34643
32749
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SimpleComponent, decorators: [{
|
|
34644
32750
|
type: Component,
|
|
@@ -34649,7 +32755,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
34649
32755
|
IonTitle,
|
|
34650
32756
|
IonContent,
|
|
34651
32757
|
HeaderComponent,
|
|
34652
|
-
LayoutComponent,
|
|
34653
32758
|
DividerComponent,
|
|
34654
32759
|
LinkComponent,
|
|
34655
32760
|
ExpandableTextComponent,
|
|
@@ -34687,12 +32792,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
34687
32792
|
@if (props.withDivider) {
|
|
34688
32793
|
<val-divider [props]="{ fill: 'solid', size: 'medium', color: 'dark' }" />
|
|
34689
32794
|
}
|
|
34690
|
-
<
|
|
32795
|
+
<div class="layout-container">
|
|
34691
32796
|
<ng-content select="[inner-container]"></ng-content>
|
|
34692
|
-
</
|
|
32797
|
+
</div>
|
|
34693
32798
|
</ion-content>
|
|
34694
32799
|
<ng-content select="[outter-container]"></ng-content>
|
|
34695
|
-
`, styles: [".description-container{padding:0 16px}\n"] }]
|
|
32800
|
+
`, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.description-container{padding:0 16px}.layout-container{margin:0 auto;padding:0;width:100%;box-sizing:border-box;margin-bottom:1rem;padding-top:.5rem}@media (max-width: 768px){.layout-container{max-width:100%}}@media (min-width: 768px){.layout-container{margin:0 auto;max-width:33.75rem;margin-bottom:1.5rem}}@media (min-width: 1200px){.layout-container{margin:0 auto;max-width:45rem}}\n"] }]
|
|
34696
32801
|
}], propDecorators: { props: [{
|
|
34697
32802
|
type: Input
|
|
34698
32803
|
}], onClick: [{
|
|
@@ -43370,5 +41475,5 @@ function buildFooterLinks(links, t) {
|
|
|
43370
41475
|
* Generated bundle index. Do not edit.
|
|
43371
41476
|
*/
|
|
43372
41477
|
|
|
43373
|
-
export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA,
|
|
41478
|
+
export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FabComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, GlowCardComponent, GridSkeletonComponent, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, MOTION, MaintenancePageComponent, MenuComponent, MessagingService, MetaService, ModalService, MultiSelectSearchComponent, NavigationService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RightsFooterComponent, RotatingTextComponent, SKELETON_PRESETS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_DEFAULT_CONTENT, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, news, permissionGuard, permissionGuardFromRoute, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechPresets, provideValtechSkeleton, query, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
|
|
43374
41479
|
//# sourceMappingURL=valtech-components.mjs.map
|