diff --git a/src/app/components/add-expense/add-expense.component.html b/src/app/components/add-expense/add-expense.component.html
index bcfe018..afc5f76 100644
--- a/src/app/components/add-expense/add-expense.component.html
+++ b/src/app/components/add-expense/add-expense.component.html
@@ -20,10 +20,10 @@
Category
-
-
+
+
@for (category of categories(); track category.id) {
- {{ category.name }}
+ {{ category.name }}
}
@@ -31,9 +31,9 @@
Merchant
-
+
@for (merchant of merchants(); track merchant.id) {
- {{ merchant.name }}
+ {{ merchant.name }}
}
@@ -44,7 +44,7 @@
Tags
@for (tag of tags(); track tag.id) {
- {{ tag.name }}
+ {{ tag.name }}
}
@@ -60,6 +60,12 @@
+
+ @if (errorSaving()) {
+
+ {{ errorSaving() }}
+
+ }
diff --git a/src/app/components/add-expense/add-expense.component.ts b/src/app/components/add-expense/add-expense.component.ts
index 5931c7a..e3f0d4e 100644
--- a/src/app/components/add-expense/add-expense.component.ts
+++ b/src/app/components/add-expense/add-expense.component.ts
@@ -1,7 +1,7 @@
import { Component, computed, signal } from '@angular/core';
-import { CategoryService } from '../../services/category.service';
-import { MerchantService } from '../../services/merchant.service';
-import { TagService } from '../../services/tag.service';
+import { Category, CategoryService } from '../../services/category.service';
+import { Merchant, MerchantService } from '../../services/merchant.service';
+import { Tag, TagService } from '../../services/tag.service';
import { form, FormField, min, required } from '@angular/forms/signals';
import { MatCardModule } from '@angular/material/card';
import { MatInputModule } from '@angular/material/input';
@@ -11,20 +11,22 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { provideNativeDateAdapter } from '@angular/material/core';
+import { CreateExpense, ExpenseService } from '../../services/expense.service';
+import { DatePipe } from '@angular/common';
interface ExpenseForm {
date: Date;
cents: number;
- category: string;
- merchant: string;
+ category: Category | string;
+ merchant: Merchant | string;
note: string;
- tags: string[];
+ tags: Tag[];
}
@Component({
selector: 'app-add-expense',
imports: [MatDatepickerModule, MatFormFieldModule, MatInputModule, MatCardModule, MatAutocompleteModule, MatSelectModule, MatButtonModule, FormField],
- providers: [provideNativeDateAdapter()],
+ providers: [provideNativeDateAdapter(), DatePipe],
templateUrl: './add-expense.component.html',
styleUrl: './add-expense.component.scss',
})
@@ -41,6 +43,8 @@ export class AddExpenseComponent {
return dateValid && centsValid && categoryValid && merchantValid && noteValid;
});
+ protected saving = signal(false);
+ protected errorSaving = signal('');
private defaultFormState: ExpenseForm = {
date: new Date(),
@@ -60,12 +64,40 @@ export class AddExpenseComponent {
public constructor(private readonly categoryService: CategoryService,
private readonly merchantService: MerchantService,
- private readonly tagService: TagService) { }
+ private readonly tagService: TagService,
+ private readonly expenseService: ExpenseService,
+ private readonly datePipe: DatePipe) { }
- public saveClick(): void {
- const saveExpense = this.expenseModel();
- console.log(saveExpense);
- this.expenseModel.set({ ...this.defaultFormState, date: saveExpense.date });
- this.expenseForm().reset(this.expenseModel());
+ public async saveClick(): Promise {
+ this.errorSaving.set('');
+ const saveExpenseModel = this.expenseModel();
+ const date = this.datePipe.transform(saveExpenseModel.date, 'yyyy-MM-dd')?.split('-') ?? [];
+ const expense: CreateExpense = {
+ year: date[0],
+ month: date[1],
+ day: date[2],
+ cents: saveExpenseModel.cents,
+ category: saveExpenseModel.category as Category,
+ merchant: saveExpenseModel.merchant ? saveExpenseModel.merchant as Merchant : undefined,
+ note: saveExpenseModel.note ? saveExpenseModel.note : undefined,
+ tags: saveExpenseModel.tags
+ };
+
+ this.saving.set(true);
+ try {
+ await this.expenseService.postExpense(expense);
+ this.expenseModel.set({ ...this.defaultFormState, date: saveExpenseModel.date });
+ this.expenseForm().reset(this.expenseModel());
+ }
+ catch (error) {
+ this.errorSaving.set(`Error saving expense: ${error}`)
+ }
+ finally {
+ this.saving.set(false);
+ }
+ }
+
+ public display(value: Merchant | Category | Tag) {
+ return value.name ?? null;
}
}
diff --git a/src/app/services/expense.service.ts b/src/app/services/expense.service.ts
index 993d225..2814357 100644
--- a/src/app/services/expense.service.ts
+++ b/src/app/services/expense.service.ts
@@ -19,6 +19,13 @@ export class ExpenseService {
public async fetchExpenses(): Promise {
this.internalExpenses.set(await this.http.get(this.expensePath));
}
+
+ public async postExpense(expense: CreateExpense): Promise {
+ const createdExpense = await this.http.post(this.expensePath, expense);
+ await this.fetchExpenses();
+
+ return createdExpense;
+ }
}
export interface Expense {
@@ -32,3 +39,14 @@ export interface Expense {
merchant?: Merchant;
tags: Tag[];
}
+
+export interface CreateExpense {
+ year: string;
+ month: string;
+ day: string;
+ cents: number;
+ category: Category;
+ note?: string;
+ merchant?: Merchant;
+ tags: Tag[];
+}