From 90c64f2ca6dbd61c425a9c46c8bb7a440a4de081 Mon Sep 17 00:00:00 2001
From: Huffle <knaepen.selina@gmail.com>
Date: Tue, 27 May 2025 15:16:58 +0200
Subject: [PATCH 1/2] Add functionality to add allowance

---
 .../add-allowance-routing.module.ts           | 17 +++++++
 .../add-allowance/add-allowance.module.ts     | 23 +++++++++
 .../add-allowance/add-allowance.page.html     | 27 ++++++++++
 .../add-allowance/add-allowance.page.scss     | 40 +++++++++++++++
 .../add-allowance/add-allowance.page.spec.ts  | 17 +++++++
 .../pages/add-allowance/add-allowance.page.ts | 51 +++++++++++++++++++
 .../spend-allowance-routing.module.ts         | 17 +++++++
 .../add-allowance/spend-allowance.module.ts   | 22 ++++++++
 .../add-allowance/spend-allowance.page.ts     | 48 +++++++++++++++++
 .../allowance/allowance-routing.module.ts     |  8 +++
 .../app/pages/allowance/allowance.page.html   |  6 +--
 .../src/app/pages/allowance/allowance.page.ts |  8 +++
 .../src/app/services/allowance.service.ts     |  4 ++
 13 files changed, 285 insertions(+), 3 deletions(-)
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance-routing.module.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.module.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.html
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.scss
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.spec.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance-routing.module.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.module.ts
 create mode 100644 frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts

diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance-routing.module.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance-routing.module.ts
new file mode 100644
index 0000000..02b0cac
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AddAllowancePage } from './add-allowance.page';
+
+const routes: Routes = [
+  {
+    path: '',
+    component: AddAllowancePage
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class AddAllowancePageRoutingModule {}
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.module.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.module.ts
new file mode 100644
index 0000000..0c1b6a7
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { AddAllowancePageRoutingModule } from './add-allowance-routing.module';
+
+import { AddAllowancePage } from './add-allowance.page';
+import { MatIconModule } from '@angular/material/icon';
+
+@NgModule({
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonicModule,
+    AddAllowancePageRoutingModule,
+    ReactiveFormsModule,
+    MatIconModule
+  ],
+  declarations: [AddAllowancePage]
+})
+export class AddAllowancePageModule {}
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.html b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.html
new file mode 100644
index 0000000..272eaa2
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.html
@@ -0,0 +1,27 @@
+<ion-header [translucent]="true">
+  <ion-toolbar>
+    <div class="toolbar">
+      <div class="icon" (click)="navigateBack()">
+        <mat-icon>arrow_back</mat-icon>
+      </div>
+      <ion-title *ngIf="isAddMode && goalId == 0">Add to Allowance</ion-title>
+      <ion-title *ngIf="isAddMode && goalId != 0">Add to Goal</ion-title>
+      <ion-title *ngIf="!isAddMode">Spend Allowance</ion-title>
+    </div>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content [fullscreen]="true">
+  <form [formGroup]="form">
+    <label>Amount</label>
+    <input id="amount" type="number" placeholder="0.00" name="price" min="0" value="0" step="0.01" formControlName="amount"/>
+
+    <label>Description</label>
+    <input id="description" type="text" formControlName="description"/>
+
+    <button type="button" [disabled]="!form.valid" (click)="changeAllowance()">
+      <span *ngIf="isAddMode">Add</span>
+      <span *ngIf="!isAddMode">Spend</span>
+    </button>
+  </form>
+</ion-content>
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.scss b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.scss
new file mode 100644
index 0000000..b819a5f
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.scss
@@ -0,0 +1,40 @@
+.toolbar {
+    display: flex;
+    align-items: center;
+}
+
+.icon {
+    margin-left: 5px;
+}
+
+form {
+    height: 100%;
+}
+
+form,
+.item {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+label {
+    color: var(--ion-color-primary);
+    margin-top: 25px;
+    margin-bottom: 10px;
+}
+
+button {
+    background-color: var(--ion-color-primary);
+    border-radius: 5px;
+    color: white;
+    padding: 10px;
+    width: 250px;
+    margin-top: auto;
+    margin-bottom: 50px;
+}
+
+button:disabled,
+button[disabled]{
+    opacity: 0.5;
+}
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.spec.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.spec.ts
new file mode 100644
index 0000000..ac7e46f
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.spec.ts
@@ -0,0 +1,17 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { AddAllowancePage } from './add-allowance.page';
+
+describe('AddAllowancePage', () => {
+  let component: AddAllowancePage;
+  let fixture: ComponentFixture<AddAllowancePage>;
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(AddAllowancePage);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.ts
new file mode 100644
index 0000000..99d0eb2
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/add-allowance.page.ts
@@ -0,0 +1,51 @@
+import { Location } from '@angular/common';
+import { Component } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+import { AllowanceService } from 'src/app/services/allowance.service';
+
+@Component({
+  selector: 'app-add-allowance',
+  templateUrl: './add-allowance.page.html',
+  styleUrls: ['./add-allowance.page.scss'],
+  standalone: false,
+})
+export class AddAllowancePage {
+  public form: FormGroup;
+  public goalId: number;
+  public userId: number;
+  public isAddMode = true;
+// Marcus' first comment
+//            b    ........a`.OK  ø¶Ópppppppp--P09OP
+
+
+  constructor(
+    private allowanceService: AllowanceService,
+    private route: ActivatedRoute,
+    private formBuilder: FormBuilder,
+    private router: Router,
+    private location: Location
+  ) {
+    this.userId = this.route.snapshot.params['id'];
+    this.goalId = this.route.snapshot.params['goalId'];
+
+    this.form = this.formBuilder.group({
+      amount: ['', Validators.required],
+      description: ['', Validators.required]
+    });
+  }
+
+  changeAllowance() {
+    this.allowanceService.addOrSpendAllowance(
+      this.goalId,
+      this.userId,
+      this.form.value.amount,
+      this.form.value.description
+    );
+    this.router.navigate(['/tabs/allowance', this.userId]);
+  }
+
+  navigateBack() {
+    this.location.back();
+  }
+}
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance-routing.module.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance-routing.module.ts
new file mode 100644
index 0000000..5889e9e
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SpendllowancePage } from './spend-allowance.page';
+
+const routes: Routes = [
+    {
+        path: '',
+        component: SpendllowancePage
+    }
+];
+
+@NgModule({
+    imports: [RouterModule.forChild(routes)],
+    exports: [RouterModule],
+})
+export class SpendAllowancePageRoutingModule {}
\ No newline at end of file
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.module.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.module.ts
new file mode 100644
index 0000000..8cb0219
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.module.ts
@@ -0,0 +1,22 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+
+import { IonicModule } from '@ionic/angular';
+
+import { SpendAllowancePageRoutingModule } from './spend-allowance-routing.module';
+import { SpendllowancePage } from './spend-allowance.page';
+import { MatIconModule } from '@angular/material/icon';
+
+@NgModule({
+    imports: [
+        CommonModule,
+        FormsModule,
+        IonicModule,
+        SpendAllowancePageRoutingModule,
+        ReactiveFormsModule,
+        MatIconModule
+    ],
+    declarations: [SpendllowancePage]
+})
+export class SpendAllowancePageModule {}
\ No newline at end of file
diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts
new file mode 100644
index 0000000..90448d4
--- /dev/null
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts
@@ -0,0 +1,48 @@
+import { Location } from '@angular/common';
+import { Component } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+import { AllowanceService } from 'src/app/services/allowance.service';
+
+@Component({
+    selector: 'app-spend-allowance',
+    templateUrl: './add-allowance.page.html',
+    styleUrls: ['./add-allowance.page.scss'],
+    standalone: false,
+})
+export class SpendllowancePage {
+    public form: FormGroup;
+    public goalId: number;
+    public userId: number;
+    public isAddMode = false;
+
+    constructor(
+        private allowanceService: AllowanceService,
+        private route: ActivatedRoute,
+        private formBuilder: FormBuilder,
+        private router: Router,
+        private location: Location
+    ) {
+        this.userId = this.route.snapshot.params['id'];
+        this.goalId = this.route.snapshot.params['goalId'];
+
+        this.form = this.formBuilder.group({
+        amount: ['', Validators.required],
+        description: ['', Validators.required]
+        });
+    }
+
+    changeAllowance() {
+        this.allowanceService.addOrSpendAllowance(
+        this.goalId,
+        this.userId,
+        -this.form.value.amount,
+        this.form.value.description
+        );
+        this.router.navigate(['/tabs/allowance', this.userId]);
+    }
+
+    navigateBack() {
+        this.location.back();
+    }
+}
\ No newline at end of file
diff --git a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance-routing.module.ts b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance-routing.module.ts
index 5616c78..3beac25 100644
--- a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance-routing.module.ts
+++ b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance-routing.module.ts
@@ -14,6 +14,14 @@ const routes: Routes = [
   {
     path: ':id/edit/:goalId',
     loadChildren: () => import('../edit-allowance/edit-allowance.module').then(m => m.EditAllowancePageModule)
+  },
+  {
+    path: ':id/increase/:goalId',
+    loadChildren: () => import('../add-allowance/add-allowance.module').then(m => m.AddAllowancePageModule)
+  },
+  {
+    path: ':id/spend/:goalId',
+    loadChildren: () => import('../add-allowance/spend-allowance.module').then(m => m.SpendAllowancePageModule)
   }
 ];
 
diff --git a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.html b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.html
index 94f9a09..2e46e0e 100644
--- a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.html
+++ b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.html
@@ -43,9 +43,9 @@
         </div>
         <div class="progress">{{ goal.progress }} SP</div>
         <div class="buttons">
-          <button class="add-button">Add</button>
+          <button class="add-button" (click)="addAllowance(goal.id)">Add</button>
           <!-- <button class="move-button">Move</button> -->
-          <button class="spend-button">Spend</button>
+          <button class="spend-button" (click)="spendAllowance(goal.id)">Spend</button>
         </div>
       </div>
       <ng-template #other_goal>
@@ -59,7 +59,7 @@
             </div>
             <div class="progress">{{ goal.progress }} / {{ goal.target }} SP</div>
             <div class="buttons">
-              <button class="add-button">Add</button>
+              <button class="add-button" (click)="addAllowance(goal.id)">Add</button>
               <!-- <button class="move-button">Move</button> -->
               <button class="spend-button" [disabled]="!canFinishGoal(goal)" (click)="completeGoal(goal.id)">Finish goal</button>
             </div>
diff --git a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.ts b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.ts
index c0b0971..4bcfcd4 100644
--- a/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.ts
+++ b/frontend/allowance-planner-v2/src/app/pages/allowance/allowance.page.ts
@@ -72,4 +72,12 @@ export class AllowancePage implements ViewWillEnter {
     this.allowanceService.completeGoal(goalId, this.id);
     this.getAllowance();
   }
+
+  addAllowance(id: number) {
+    this.router.navigate(['increase', id], { relativeTo: this.route });
+  }
+
+  spendAllowance(id: number) {
+    this.router.navigate(['spend', id], { relativeTo: this.route });
+  }
 }
diff --git a/frontend/allowance-planner-v2/src/app/services/allowance.service.ts b/frontend/allowance-planner-v2/src/app/services/allowance.service.ts
index 61397e9..5108aeb 100644
--- a/frontend/allowance-planner-v2/src/app/services/allowance.service.ts
+++ b/frontend/allowance-planner-v2/src/app/services/allowance.service.ts
@@ -34,4 +34,8 @@ export class AllowanceService {
     completeGoal(goalId: number, userId: number) {
         this.http.post(`${this.url}/user/${userId}/allowance/${goalId}/complete`, {}).subscribe();
     }
+
+    addOrSpendAllowance(goalId: number, userId: number, amount: number, description: string) {
+        this.http.post(`${this.url}/user/${userId}/allowance/${goalId}/add`, { amount, description }).subscribe();
+    }
 }
\ No newline at end of file
-- 
2.47.2


From 85f796814cc34b74aa0b38b79c93c07f7350eb86 Mon Sep 17 00:00:00 2001
From: Huffle <knaepen.selina@gmail.com>
Date: Tue, 27 May 2025 18:38:35 +0200
Subject: [PATCH 2/2] add max validator in spend allowance page

---
 .../src/app/pages/add-allowance/spend-allowance.page.ts       | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts
index 90448d4..d15e7a1 100644
--- a/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts
+++ b/frontend/allowance-planner-v2/src/app/pages/add-allowance/spend-allowance.page.ts
@@ -30,6 +30,10 @@ export class SpendllowancePage {
         amount: ['', Validators.required],
         description: ['', Validators.required]
         });
+
+        this.allowanceService.getAllowanceById(this.goalId, this.userId).subscribe(allowance => {
+            this.form.controls['amount'].addValidators([Validators.max(allowance.progress)]);
+        }); 
     }
 
     changeAllowance() {
-- 
2.47.2