import { AfterContentInit, Component, HostListener, Input, OnDestroy, OnInit, forwardRef } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Trial } from '@app/domain/models/subscription.model'; import { BaseComp } from '@app/shared/base/base.component'; import { GC } from '@app/shared/global'; import { DateUtils } from '@app/shared/utils'; import { SelectItem } from 'primeng-lts/api'; const MIN_DAYS = 7; @Component({ selector: 'trial', templateUrl: './trial.component.html', styleUrls: ['./trial.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TrialComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => TrialComponent), multi: true } ] }) export class TrialComponent extends BaseComp implements OnDestroy, OnInit, AfterContentInit { @Input() trialDays: number[]; @Input() trials: Trial; @Input() disable: boolean; DAYS = GC.DAYS; BYDATE = GC.BYDATE; dayItems: SelectItem[]; form: FormGroup; toDate: Date; error: string; calMinDate: Date; calMaxDate: Date; onChange: any = () => { }; onTouched: any = () => { }; constructor( private readonly fb: FormBuilder ) { super(); const ONE_YEAR = 1; this.calMinDate = new Date(); this.calMinDate.setDate(this.calMinDate.getDate() + MIN_DAYS); this.calMinDate.setHours(0, 0, 0); this.calMaxDate = new Date(); this.calMaxDate.setFullYear(this.calMaxDate.getFullYear() + ONE_YEAR); } get value() { return this.form.value; } set value(val) { this.writeValue(val); this.onChange(val); this.onTouched(val); } ngOnInit(): void { this.form = this.fb.group({ selected: new FormControl({ value: false, disabled: this.disable }), type: new FormControl({ value: '', disabled: this.disable }), startDate: [], lastEndDate: [], lastStartDate: [], trialDays: new FormControl({ value: '', disabled: this.disable }), byDate: [] }); this.dayItems = this.trialDays?.map((day) => ({ label: `${day}`, value: day })); this.sub$.add(this.form.valueChanges.subscribe((val) => { this.onChange(val); this.onTouched(val); })); } ngAfterContentInit() { const hasExistingTrial = this.trials?.type && (this.trials.trialDays >= MIN_DAYS || this.trials.byDate); if (hasExistingTrial) { if (this.trials.type === this.BYDATE && this.trials.byDate) { this.toDate = new Date(this.trials.byDate); this.form.patchValue({ ...this.trials, selected: true }); } else if (this.trials.type === this.DAYS && this.trials.trialDays >= MIN_DAYS) { this.form.patchValue({ ...this.trials, selected: true }); } else { this.form.patchValue({ ...this.trials }); } } } writeValue(val): void { if (val) { this.form.patchValue(val); } } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } validate() { this.checkAndDisplayErr(); const isTrial = this.form.value.selected; const isInValid = !this.isValidTrialDays() && !this.isValidBydate(); return isTrial ? isInValid ? { trials: { valid: false } } : null : null; } isValidTrialDays() { return this.form.value.type === this.DAYS && this.form.value.trialDays && !isNaN(this.form.value.trialDays) && this.form.value.trialDays >= MIN_DAYS; } isValidBydate() { return this.form.value.type === this.BYDATE && this.form.value.byDate; } change() { const noPrevTrial = !this.form.value.type; if (noPrevTrial) { this.form.patchValue({ type: this.DAYS }); } const trialDays = this.form.value.trialDays; const notExistItem = this.dayItems?.every((item) => item.value != trialDays); if (this.isValidTrialDays() && notExistItem) { this.dayItems.push({ label: `${trialDays}`, value: Number(trialDays) }); this.dayItems.sort((a, b) => a.value - b.value); this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value)); } this.form.updateValueAndValidity(); } changeCal() { this.form.patchValue({ ...this.trials, type: this.BYDATE, byDate: DateUtils.tsToDate( DateUtils.endUtcTS( DateUtils.dateToTS(this.toDate))) }); this.form.updateValueAndValidity(); } checkAndDisplayErr() { this.error = ''; if (this.form.value.selected && this.form.value.type === this.BYDATE) { if (!this.toDate) { return this.error = `Please fill in end date MM/DD/YYYY from `; } } else if (this.form.value.selected && this.form.value.type === this.DAYS) { if (!this.form.value.trialDays) { return this.error = 'Please fill in the number of end days'; } else if (isNaN(this.form.value.trialDays) || this.form.value.trialDays < MIN_DAYS) { return this.error = `Number of days must be number greater than .`; } } return this.error; } remove(item) { this.dayItems = this.dayItems?.filter((day) => day.label !== item.label); this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value)); } @HostListener('document:keydown.enter', ['$event']) onKeydownHandler(e: KeyboardEvent) { const target = e.target; if (target.name === this.BYDATE) this.changeCal(); } ngOnDestroy(): void { super.ngOnDestroy(); } }