import { ChangeDetectionStrategy, Component, input, model, output } from '@angular/core'; import { AsyncPipe, DecimalPipe } from '@angular/common'; import { interval } from 'rxjs'; import { map, startWith, tap } from 'rxjs/operators'; const countdownConfig = { hoursInADay: 24, minutesInAnHour: 60, secondsInAMinute: 60, }; @Component({ standalone: true, imports: [AsyncPipe, DecimalPipe], selector: 'app-countdown', templateUrl: './countdown.component.html', styleUrls: ['./countdown.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class CountdownComponent { countdownDone = output(); enabled = input(true); dateEvent = input.required(); initialTime = model(Math.floor(Date.now() / 1000)); countdown$ = interval(1000).pipe( startWith(0), tap(() => this.initialTime.set(this.initialTime() + 1)), map(() => this.dateEvent() - this.initialTime()), tap((timeDifference) => timeDifference <= 0 && this.enabled() && this.countdownDone.emit()), map((timeDifference) => this.allocateTimeUnits(timeDifference)) ); private allocateTimeUnits(timeDifference: number) { if (timeDifference <= 0) { return [ { value: 0, label: 'Días' }, { value: 0, label: 'Horas' }, { value: 0, label: 'Minutos' }, { value: 0, label: 'Segundos' }, ]; } const { secondsInAMinute, minutesInAnHour, hoursInADay } = countdownConfig; const seconds = Math.floor(timeDifference % secondsInAMinute); const minutes = Math.floor((timeDifference / minutesInAnHour) % secondsInAMinute); const hours = Math.floor((timeDifference / (minutesInAnHour * secondsInAMinute)) % hoursInADay); const days = Math.floor(timeDifference / (minutesInAnHour * secondsInAMinute * hoursInADay)); return [ { value: days, label: 'Días' }, { value: hours, label: 'Horas' }, { value: minutes, label: 'Minutos' }, { value: seconds, label: 'Segundos' }, ]; } }