78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
import { DecimalPipe } from '@angular/common';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { CartItem, DeliveryOption } from '../../models';
|
|
import { TranslatePipe } from '../../i18n/translate.pipe';
|
|
|
|
let nextDeliverySelectorId = 0;
|
|
|
|
@Component({
|
|
selector: 'app-delivery-selector',
|
|
standalone: true,
|
|
imports: [FormsModule, DecimalPipe, TranslatePipe],
|
|
templateUrl: './delivery-selector.component.html',
|
|
styleUrls: ['./delivery-selector.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
})
|
|
export class DeliverySelectorComponent {
|
|
@Input({ required: true }) item: CartItem | null = null;
|
|
|
|
@Output() selectedDeliveryChange = new EventEmitter<DeliveryOption | null>();
|
|
|
|
readonly selectId = `delivery-select-${nextDeliverySelectorId++}`;
|
|
|
|
get options(): DeliveryOption[] {
|
|
return this.item?.deliveryOptions ?? [];
|
|
}
|
|
|
|
get selectedDelivery(): DeliveryOption | null {
|
|
return this.item?.selectedDelivery ?? null;
|
|
}
|
|
|
|
get currency(): string {
|
|
return this.item?.currency || 'RUB';
|
|
}
|
|
|
|
get required(): boolean {
|
|
return this.item?.deliveryMode !== 'digital'
|
|
&& this.options.length > 0
|
|
&& this.item?.deliverySelectionRequired !== false;
|
|
}
|
|
|
|
get isDigital(): boolean {
|
|
return this.item?.deliveryMode === 'digital';
|
|
}
|
|
|
|
get selectedKey(): string {
|
|
return this.selectedDelivery ? this.optionKey(this.selectedDelivery) : '';
|
|
}
|
|
|
|
get selectedDeliveryTotal(): number {
|
|
return (this.selectedDelivery?.deliveryPrice ?? 0) * (this.item?.quantity ?? 1);
|
|
}
|
|
|
|
optionKey(option: DeliveryOption): string {
|
|
return `${option.deliveryPlace}__${option.deliveryTime}__${option.deliveryPrice}`;
|
|
}
|
|
|
|
optionLabel(option: DeliveryOption): string {
|
|
const details = [option.deliveryPlace, option.deliveryTime].filter(Boolean);
|
|
details.push(`${option.deliveryPrice.toFixed(2)} ${this.currency}`);
|
|
return details.join(' • ');
|
|
}
|
|
|
|
trackByOption(index: number, option: DeliveryOption): string {
|
|
return `${index}-${this.optionKey(option)}`;
|
|
}
|
|
|
|
onSelectionChange(nextKey: string): void {
|
|
if (!nextKey) {
|
|
this.selectedDeliveryChange.emit(null);
|
|
return;
|
|
}
|
|
|
|
this.selectedDeliveryChange.emit(
|
|
this.options.find(option => this.optionKey(option) === nextKey) ?? null
|
|
);
|
|
}
|
|
} |