import { Component, model, signal, viewChild } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { MatButtonModule } from '@angular/material/button'; import { CreateExpense, Expense, ExpenseService, UpdateExpense } from '../../services/expense.service'; import { MatIcon } from '@angular/material/icon'; import { ExpenseForm, ExpenseFormComponent } from './expense-form/expense-form.component'; import { CurrencyPipe, DatePipe } from '@angular/common'; import { Temporal } from '@js-temporal/polyfill'; import { SnackBarService } from '../../services/snack-bar'; @Component({ selector: 'app-expense', imports: [MatCardModule, MatButtonModule, MatIcon, ExpenseFormComponent, DatePipe, CurrencyPipe], providers: [], templateUrl: './expense.component.html', styleUrl: './expense.component.scss' }) export class ExpenseComponent { private form = viewChild(ExpenseFormComponent); public editingExpense = signal(false); public savingExpense = signal(false); public expense = model(); public formValid = model(false); public formDirty = model(false); public formData = model(); public constructor(private readonly expenseService: ExpenseService, private readonly snackBar: SnackBarService) { } public editClick(): void { this.editingExpense.set(true); } public async addClick(): Promise { const form = this.formData()!; const postExpense: CreateExpense = { date: this.dateToPlainDate(form.date), cents: form.cents, category: form.category, merchant: form.merchant, note: form.note, tags: form.tags }; this.savingExpense.set(true); const snackId = this.snackBar.staticBar('Tracking new expense...'); try { await this.expenseService.create(postExpense); await this.expenseService.fetch(); this.resetForm(); this.snackBar.dismiss(snackId); this.snackBar.autoBar('Expense tracked!'); } catch (error) { this.snackBar.dismiss(snackId); this.snackBar.dismissableBar('Error: '); // TODO } finally { this.savingExpense.set(false); } } public resetAddClick(): void { this.resetForm(true); } public async updateClick(): Promise { const form = this.formData()!; const putExpense: UpdateExpense = { id: this.expense()!.id, date: this.dateToPlainDate(form.date), cents: form.cents, category: form.category, merchant: form.merchant, note: form.note, tags: form.tags }; this.savingExpense.set(true); const snackId = this.snackBar.staticBar('Updating expense...'); try { const expense = await this.expenseService.update(putExpense); this.expense.set(expense); this.form()?.refresh(expense); this.editingExpense.set(false); this.snackBar.dismiss(snackId); this.snackBar.autoBar('Expense updated!'); } catch (error) { this.snackBar.dismiss(snackId); this.snackBar.dismissableBar('Error: '); // TODO } finally { this.savingExpense.set(false); } } public cancelUpdateClick(): void { this.resetForm(); } private resetForm(clearDate = false): void { this.form()?.reset(clearDate); this.editingExpense.set(false); } private dateToPlainDate(date: Date): Temporal.PlainDate { return new Temporal.PlainDate(date.getFullYear(), date.getMonth() + 1, date.getDate()); } }