feat(deposit): implement modal animations with GSAP

This commit is contained in:
Jan-Marlon Leibl 2025-03-06 11:52:31 +01:00
parent c651337d30
commit 08a1a5e877
Signed by: jleibl
GPG key ID: 300B2F906DC6F1D5
9 changed files with 177 additions and 17 deletions

View file

@ -1,6 +1,6 @@
@if (isOpen) {
<div class="modal-bg">
<div class="modal-card">
<div #modalBg class="modal-bg">
<div #modalCard class="modal-card">
<h2 class="modal-heading">Guthaben aufladen</h2>
<form [formGroup]="form">
@if (errorMsg) {

View file

@ -1,11 +1,18 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
EventEmitter,
inject,
Input,
OnInit,
Output,
ViewChild,
AfterViewInit,
OnDestroy,
OnChanges,
SimpleChanges,
ChangeDetectorRef,
} from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { loadStripe, Stripe } from '@stripe/stripe-js';
@ -13,6 +20,8 @@ import { DepositService } from '../../service/deposit.service';
import { debounceTime } from 'rxjs';
import { environment } from '../../../environments/environment';
import { NgIf } from '@angular/common';
import { ModalAnimationService } from '../../shared/services/modal-animation.service';
import gsap from 'gsap';
@Component({
selector: 'app-deposit',
@ -21,13 +30,17 @@ import { NgIf } from '@angular/common';
templateUrl: './deposit.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DepositComponent implements OnInit {
export class DepositComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {
@Input() isOpen = false;
@Output() close = new EventEmitter<void>();
@ViewChild('modalBg') modalBg!: ElementRef;
@ViewChild('modalCard') modalCard!: ElementRef;
protected form!: FormGroup;
protected errorMsg = '';
private stripe: Stripe | null = null;
private service: DepositService = inject(DepositService);
private modalAnimationService: ModalAnimationService = inject(ModalAnimationService);
private cdr: ChangeDetectorRef = inject(ChangeDetectorRef);
async ngOnInit() {
this.form = new FormGroup({
@ -43,6 +56,43 @@ export class DepositComponent implements OnInit {
this.stripe = await loadStripe(environment.STRIPE_KEY);
}
ngAfterViewInit() {
if (this.isOpen) {
this.openModal();
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes['isOpen']) {
// Force change detection to ensure DOM is updated
this.cdr.detectChanges();
// Small delay to ensure DOM is ready
setTimeout(() => {
if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
if (changes['isOpen'].currentValue) {
this.openModal();
} else {
this.closeModal();
}
}
}, 0);
}
}
ngOnDestroy() {
gsap.killTweensOf([this.modalBg?.nativeElement, this.modalCard?.nativeElement]);
}
private openModal() {
if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
this.modalAnimationService.openModal(
this.modalCard.nativeElement,
this.modalBg.nativeElement
);
}
}
submit() {
if (!this.stripe) {
this.errorMsg = 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.';
@ -59,6 +109,12 @@ export class DepositComponent implements OnInit {
}
public closeModal() {
this.close.emit();
if (this.modalBg?.nativeElement && this.modalCard?.nativeElement) {
this.modalAnimationService.closeModal(
this.modalCard.nativeElement,
this.modalBg.nativeElement,
() => this.close.emit()
);
}
}
}