aboutsummaryrefslogtreecommitdiff
path: root/ufund-ui/src/app/components
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2025-03-17 23:16:29 -0400
committersowgro <tpoke.ferrari@gmail.com>2025-03-17 23:16:29 -0400
commit68515441acd77d3356e8ec8b58700411661fec13 (patch)
treef3e08e4eecb5c06c8149d56ca08253a3c2d92607 /ufund-ui/src/app/components
parent7a5c5073e9e410b3ccc3ab7902a0d6f558277c7d (diff)
parent275a6062007380389b7a8f1b8958e8033b4f0925 (diff)
downloadJellySolutions-68515441acd77d3356e8ec8b58700411661fec13.tar.gz
JellySolutions-68515441acd77d3356e8ec8b58700411661fec13.tar.bz2
JellySolutions-68515441acd77d3356e8ec8b58700411661fec13.zip
Merge remote-tracking branch 'refs/remotes/origin/main' into funding_basket
# Conflicts: # ufund-ui/src/app/components/funding-basket/funding-basket.component.ts
Diffstat (limited to 'ufund-ui/src/app/components')
-rw-r--r--ufund-ui/src/app/components/cupboard/cupboard.component.css21
-rw-r--r--ufund-ui/src/app/components/cupboard/cupboard.component.html63
-rw-r--r--ufund-ui/src/app/components/cupboard/cupboard.component.ts208
-rw-r--r--ufund-ui/src/app/components/dashboard/dashboard.component.html6
-rw-r--r--ufund-ui/src/app/components/dashboard/dashboard.component.ts4
-rw-r--r--ufund-ui/src/app/components/funding-basket/funding-basket.component.ts6
-rw-r--r--ufund-ui/src/app/components/home-page/home-page.component.html3
-rw-r--r--ufund-ui/src/app/components/login/login.component.css12
-rw-r--r--ufund-ui/src/app/components/login/login.component.html10
-rw-r--r--ufund-ui/src/app/components/login/login.component.ts93
-rw-r--r--ufund-ui/src/app/components/need-list/need-list.component.css24
-rw-r--r--ufund-ui/src/app/components/need-list/need-list.component.html20
-rw-r--r--ufund-ui/src/app/components/need-list/need-list.component.ts87
-rw-r--r--ufund-ui/src/app/components/need-page/need-page.component.html28
-rw-r--r--ufund-ui/src/app/components/need-page/need-page.component.ts11
15 files changed, 537 insertions, 59 deletions
diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.css b/ufund-ui/src/app/components/cupboard/cupboard.component.css
index e69de29..fe4971a 100644
--- a/ufund-ui/src/app/components/cupboard/cupboard.component.css
+++ b/ufund-ui/src/app/components/cupboard/cupboard.component.css
@@ -0,0 +1,21 @@
+:host {
+ display: block;
+ border: 2px solid #000;
+ border-radius: 5px;
+ padding: 10px 20px;
+}
+
+#menu, #create-form, #delete-form, #update-form {
+ background-color: #d9d9d9;
+ padding: 10px 20px 20px 20px;
+ border: 2px solid #000;
+ border-radius: 5px;
+ width: 20%;
+ visibility: visible;
+
+}
+
+#create-button {
+ padding: 10px 20px;
+
+} \ No newline at end of file
diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.html b/ufund-ui/src/app/components/cupboard/cupboard.component.html
index ad8e60c..172360d 100644
--- a/ufund-ui/src/app/components/cupboard/cupboard.component.html
+++ b/ufund-ui/src/app/components/cupboard/cupboard.component.html
@@ -1,17 +1,50 @@
<h1> Cupboard </h1>
-<form>
- <label for="name">Name:</label><br>
- <input #name type="text" name="name"><br>
- <label for="id">Id:</label><br>
- <input #id type="number" name="id"><br>
- <label for="max-goal">Max Goal:</label><br>
- <input #maxgoal type="number" name="max-goal"><br>
- <label>Type</label><br>
- <input id="monetary" type="radio" name="type" value="MONETARY">
- <label for="monetary">Monetary</label><br>
- <input #physical type="radio" name="type" value="PHYSICAL">
- <label for="physical">Physical</label><br>
-</form>
-<button (click)="submit(name.value, id.valueAsNumber, maxgoal.valueAsNumber, physical.value)">Submit</button>
+<h2 *ngIf="isManager()" > Admin View </h2>
+<div id="menu" *ngIf="isManager()">
+ <button (click)="opencreate()">Create new Need</button>
+ <button (click)="openupdate()">Update existing Need</button>
+</div>
+<div id="create-form">
+ <h1> Create a new need </h1>
+ <form #cupboardForm="ngForm" (ngSubmit)="submit(cupboardForm.value)">
+ <label>Name:</label><br>
+ <input type="text" name="name" ngModel><br>
+ <label>Max Goal:</label><br>
+ <input type="number" name="maxGoal" ngModel><br>
+ <label>Type</label><br>
+ <input type="radio" name="type" value="MONETARY" ngModel>
+ <label>Monetary</label><br>
+ <input type="radio" name="type" value="PHYSICAL" ngModel>
+ <label>Physical</label><br>
+ <input type="submit" value="Submit">
+ </form>
+ <button (click)="back()">Close</button>
+ <span *ngIf="statusText">{{statusText | async}}</span>
-<app-need-list></app-need-list>
+</div>
+<div id="update-form">
+ <h1> Update a need </h1>
+ <label>Needs:</label><br>
+ <form #updateForm="ngForm" (ngSubmit)="update(updateForm.value)">
+ <div *ngFor="let need of needs">
+
+ <input type="radio" name="id" [value]=need.id [(ngModel)]="selectedNeedId" (change)="populateForm(need)">
+ <label name="template">{{need.name}}</label><br>
+ </div>
+ <label>Name:</label><br>
+ <input type="text" name="name" [(ngModel)]="selectedNeed.name"><br>
+ <label>Max Goal:</label><br>
+ <input type="number" name="maxGoal" [(ngModel)]="selectedNeed.maxGoal"><br>
+ <label>Type</label><br>
+ <input type="radio" name="type" value="MONETARY" [(ngModel)]="selectedNeed.type">
+ <label>Monetary</label><br>
+ <input type="radio" name="type" value="PHYSICAL" [(ngModel)]="selectedNeed.type">
+ <label>Physical</label><br>
+ <input type="submit" value="Submit">
+ </form>
+ <button (click)="back()">Close</button>
+ <span *ngIf="statusText">{{statusText | async}}</span>
+
+</div>
+<hr>
+<app-need-list #needList></app-need-list>
diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.ts b/ufund-ui/src/app/components/cupboard/cupboard.component.ts
index 53dad8a..9574de3 100644
--- a/ufund-ui/src/app/components/cupboard/cupboard.component.ts
+++ b/ufund-ui/src/app/components/cupboard/cupboard.component.ts
@@ -1,8 +1,10 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { CupboardService } from '../../services/cupboard.service';
-import { NeedListComponent } from '../need-list/need-list.component';
-
+import { UsersService } from '../../services/users.service';
import { Need, GoalType } from '../../models/Need';
+import { userType } from '../../models/User';
+import { BehaviorSubject, catchError, of } from 'rxjs';
+import {NeedListComponent} from '../need-list/need-list.component';
@Component({
selector: 'app-cupboard',
@@ -10,22 +12,190 @@ import { Need, GoalType } from '../../models/Need';
templateUrl: './cupboard.component.html',
styleUrl: './cupboard.component.css'
})
-export class CupboardComponent implements
- OnInit {
-
- constructor(private cupboardService: CupboardService){}
- ngOnInit() {
-
-
- }
- need!: Need;
- submit(name: string, id: number, maxGoal: number, type: string) {
- if (this.need) {
- this.need.name = name;
- this.need.id = id;
- this.need.maxGoal = maxGoal;
- console.log(type);
- this.cupboardService.createNeed(this.need);
+
+export class CupboardComponent implements OnInit {
+
+ protected statusText = new BehaviorSubject("")
+
+ needs: any;
+ @ViewChild("needList") needList?: NeedListComponent
+
+ constructor(private cupboardService: CupboardService, private usersService: UsersService) { }
+
+ ngOnInit(): void {
+ this.cupboardService.getNeeds().subscribe(n => this.needs = n);
+ this.close();
+ this.openmenu();
+
+ if (this.isManager()) {
+ console.log("Admin view of Cupboard");
+ } else {
+ console.log("Limited helper view of Cupboard");
}
}
+
+ selectedNeed: any = {
+ name: '',
+ id: null,
+ maxGoal: null,
+ type: ''
+ };
+ selectedNeedId: number | null = null;
+
+ private hideElement(element: any) {
+ if (element){
+ element.style.visibility = 'hidden';
+ element.style.position = 'absolute';
+ }
+ }
+
+ private showElement(element: any) {
+ if (element){
+ element.style.visibility = 'visible';
+ element.style.position = 'relative';
+ }
+ }
+
+ openmenu() {
+ const menuElement = document.getElementById('menu');
+ this.showElement(menuElement);
+ }
+
+ opencreate() {
+ this.close();
+ this.showElement(document.getElementById('create-form'));
+ }
+
+ openupdate() {
+ this.close();
+ this.showElement(document.getElementById('update-form'));
+ }
+
+ back() {
+ this.close();
+ this.openmenu();
+ }
+
+ close() {
+ this.hideElement(document.getElementById('create-form'));
+ this.hideElement(document.getElementById('destroy-form'));
+ this.hideElement(document.getElementById('menu'));
+ this.hideElement(document.getElementById('update-form'));
+ }
+
+ populateForm(need: any): void {
+ this.selectedNeed = { ...need };
+ }
+
+ isManager() {
+ const type = this.usersService.getCurrentUser()?.type;
+ return type === ("MANAGER" as unknown as userType);
+ }
+
+ update(form: any) {
+ console.log(form);
+ const need: Need = {
+ name: form.name,
+ id: form.id, //system will control this
+ maxGoal: form.maxGoal,
+ type: GoalType[form.type as keyof typeof GoalType],
+ filterAttributes: [],
+ current: 0
+ };
+ console.log("need:", need);
+ console.log(need.id, need, "need updated");
+ this.cupboardService.updateNeed(need.id, need)
+ .pipe(catchError((ex, r) => {
+ this.statusText.next("Max goal must be greater than 0 " + friendlyHttpStatus[ex.status])
+ return of()
+ }))
+ .subscribe(
+ (result) => {
+ if (result) {
+ console.log("need updated successfully");
+ this.needList?.refresh()
+ } else {
+ console.log("need update failed");
+ }
+ }
+
+ );
+ }
+
+ submit(form: any) {
+ const need: Need = {
+ name: form.name,
+ id: 0,
+ maxGoal: form.maxGoal,
+ type: form.type,
+ filterAttributes: [],
+ current: 0
+ };
+ console.log("need:", need);
+ console.log("form submitted. creating need: ", need);
+ this.cupboardService.createNeed(need)
+ .pipe(catchError((ex, r) => {
+ this.statusText.next("Max goal must be greater than 0 " + friendlyHttpStatus[ex.status])
+ return of()
+ }))
+ .subscribe(
+ (result) => {
+ if (result) {
+ console.log("need created successfully");
+ this.needList?.refresh()
+ } else {
+ console.log("need creation failed");
+ }
+ }
+
+ );
+ }
+
+ destroy() {
+
+ }
}
+
+let friendlyHttpStatus: {[key: number]: string} = {
+ 200: 'OK',
+ 201: 'Created',
+ 202: 'Accepted',
+ 203: 'Non-Authoritative Information',
+ 204: 'No Content',
+ 205: 'Reset Content',
+ 206: 'Partial Content',
+ 300: 'Multiple Choices',
+ 301: 'Moved Permanently',
+ 302: 'Found',
+ 303: 'See Other',
+ 304: 'Not Modified',
+ 305: 'Use Proxy',
+ 306: 'Unused',
+ 307: 'Temporary Redirect',
+ 400: 'Bad Request',
+ 401: 'Unauthorized',
+ 402: 'Payment Required',
+ 403: 'Forbidden',
+ 404: 'Not Found',
+ 405: 'Method Not Allowed',
+ 406: 'Not Acceptable',
+ 407: 'Proxy Authentication Required',
+ 408: 'Request Timeout',
+ 409: 'Conflict',
+ 410: 'Gone',
+ 411: 'Length Required',
+ 412: 'Precondition Required',
+ 413: 'Request Entry Too Large',
+ 414: 'Request-URI Too Long',
+ 415: 'Unsupported Media Type',
+ 416: 'Requested Range Not Satisfiable',
+ 417: 'Expectation Failed',
+ 418: 'I\'m a teapot',
+ 429: 'Too Many Requests',
+ 500: 'Internal Server Error',
+ 501: 'Not Implemented',
+ 502: 'Bad Gateway',
+ 503: 'Service Unavailable',
+ 504: 'Gateway Timeout',
+ 505: 'HTTP Version Not Supported',
+};
diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.html b/ufund-ui/src/app/components/dashboard/dashboard.component.html
index 9c5fce9..fc8baf0 100644
--- a/ufund-ui/src/app/components/dashboard/dashboard.component.html
+++ b/ufund-ui/src/app/components/dashboard/dashboard.component.html
@@ -1 +1,5 @@
-<p>dashboard works!</p>
+
+<h1>Dashboard</h1>
+<input type="button" value="Back to Login" (click)="back()">
+<app-cupboard></app-cupboard>
+<app-funding-basket></app-funding-basket> \ No newline at end of file
diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.ts b/ufund-ui/src/app/components/dashboard/dashboard.component.ts
index 6da4013..48c5894 100644
--- a/ufund-ui/src/app/components/dashboard/dashboard.component.ts
+++ b/ufund-ui/src/app/components/dashboard/dashboard.component.ts
@@ -7,5 +7,9 @@ import { Component } from '@angular/core';
styleUrl: './dashboard.component.css'
})
export class DashboardComponent {
+ constructor() {}
+ back() {
+ window.history.back();
+ }
}
diff --git a/ufund-ui/src/app/components/funding-basket/funding-basket.component.ts b/ufund-ui/src/app/components/funding-basket/funding-basket.component.ts
index 1dcebc5..31f2982 100644
--- a/ufund-ui/src/app/components/funding-basket/funding-basket.component.ts
+++ b/ufund-ui/src/app/components/funding-basket/funding-basket.component.ts
@@ -22,7 +22,7 @@ export class FundingBasketComponent implements
private router: Router,
private usersService: UsersService
) {}
-
+
ngOnInit(): void {
if (!this.usersService.getCurrentUser()) {
this.router.navigate(['/login'], {queryParams: {redir: this.router.url}});
@@ -47,7 +47,7 @@ export class FundingBasketComponent implements
isInBasket(need: Need): boolean {
return this.basket.some(n => n.id == need.id);
}
-
+
addNeed(need: Need, quantity: number=1): void {
if (this.user && !this.isInBasket(need)) {
this.basket.push(need);
@@ -57,7 +57,7 @@ export class FundingBasketComponent implements
}
this.needCount++;
}
-
+
removeNeed(need: Need, quantity:number=1): void {
if (this.user && this.isInBasket(need)) {
this.need_quantity[need.id] -= quantity;
diff --git a/ufund-ui/src/app/components/home-page/home-page.component.html b/ufund-ui/src/app/components/home-page/home-page.component.html
index e13c539..d41e670 100644
--- a/ufund-ui/src/app/components/home-page/home-page.component.html
+++ b/ufund-ui/src/app/components/home-page/home-page.component.html
@@ -1,4 +1,3 @@
<a routerLink="/login">
Login/Sign Up
-</a>
-<p>home-page works!</p>
+</a> \ No newline at end of file
diff --git a/ufund-ui/src/app/components/login/login.component.css b/ufund-ui/src/app/components/login/login.component.css
index afd4bf1..435cc87 100644
--- a/ufund-ui/src/app/components/login/login.component.css
+++ b/ufund-ui/src/app/components/login/login.component.css
@@ -1,6 +1,16 @@
-:host {
+:host, .border {
display: flex;
flex-direction: column;
max-width: 300px;
gap: 5px
}
+
+.border {
+ border-style: solid;
+ border-width: 1px;
+ padding: 10px;
+ margin: 10px;
+ position: absolute;
+ background-color: white;
+ box-shadow: 0 0 10px 10px black;
+}
diff --git a/ufund-ui/src/app/components/login/login.component.html b/ufund-ui/src/app/components/login/login.component.html
index 41427ae..2cdb6d0 100644
--- a/ufund-ui/src/app/components/login/login.component.html
+++ b/ufund-ui/src/app/components/login/login.component.html
@@ -1,5 +1,7 @@
+<span *ngIf="next" style="color: red">You must be logged in to view this page</span>
<p>Login:</p>
-<input placeholder="Username" type="text">
-<input placeholder="Password" type="password">
-<button>Login</button>
-<button>Create Account...</button>
+<input placeholder="Username" type="text" #username>
+<input placeholder="Password" type="password" #password>
+<button type="button" (click)="login(username.value, password.value)">Login</button>
+<button type="button" (click)="signup(username.value, password.value)">Create Account</button>
+<span *ngIf="statusText">{{statusText | async}}</span>
diff --git a/ufund-ui/src/app/components/login/login.component.ts b/ufund-ui/src/app/components/login/login.component.ts
index efb8a58..9d806f5 100644
--- a/ufund-ui/src/app/components/login/login.component.ts
+++ b/ufund-ui/src/app/components/login/login.component.ts
@@ -1,4 +1,7 @@
-import { Component } from '@angular/core';
+import {Component, OnInit} from '@angular/core'
+import {UsersService} from '../../services/users.service';
+import {ActivatedRoute, Router} from '@angular/router';
+import {BehaviorSubject} from 'rxjs';
@Component({
selector: 'app-login',
@@ -6,6 +9,92 @@ import { Component } from '@angular/core';
templateUrl: './login.component.html',
styleUrl: './login.component.css'
})
-export class LoginComponent {
+export class LoginComponent implements OnInit {
+ protected next?: string | null;
+ protected statusText = new BehaviorSubject("")
+
+ constructor(
+ protected usersService: UsersService,
+ protected router: Router,
+ private route: ActivatedRoute
+ ) {}
+
+ ngOnInit() {
+ this.next = this.route.snapshot.queryParamMap.get('redir')
+ }
+
+ login(username: string | null, password: string | null) {
+ let next = this.next || '/dashboard'
+ console.log(`attempting to log in with ${username} ${password}`)
+ if (!username || !password) {
+ return;
+ }
+
+ this.usersService.login(username, password).then(() => {
+ this.router.navigate([next]);
+ }).catch(ex => {
+ this.statusText.next("Unable to login: " + friendlyHttpStatus[ex.status])
+ console.log(ex)
+ })
+ }
+
+ signup(username: string | null, password: string | null) {
+ console.log(`attempting to sign up with ${username} ${password}`)
+ if (!username || !password) {
+ return;
+ }
+
+ this.usersService.createUser(username, password).then(() => {
+ this.statusText.next("Account created, click login.")
+ }).catch(ex => {
+ this.statusText.next("Unable to create account: " + friendlyHttpStatus[ex.status])
+ console.log(ex)
+ })
+ }
}
+
+// temporary
+let friendlyHttpStatus: {[key: number]: string} = {
+ 200: 'OK',
+ 201: 'Created',
+ 202: 'Accepted',
+ 203: 'Non-Authoritative Information',
+ 204: 'No Content',
+ 205: 'Reset Content',
+ 206: 'Partial Content',
+ 300: 'Multiple Choices',
+ 301: 'Moved Permanently',
+ 302: 'Found',
+ 303: 'See Other',
+ 304: 'Not Modified',
+ 305: 'Use Proxy',
+ 306: 'Unused',
+ 307: 'Temporary Redirect',
+ 400: 'Bad Request',
+ 401: 'Unauthorized',
+ 402: 'Payment Required',
+ 403: 'Forbidden',
+ 404: 'Not Found',
+ 405: 'Method Not Allowed',
+ 406: 'Not Acceptable',
+ 407: 'Proxy Authentication Required',
+ 408: 'Request Timeout',
+ 409: 'Conflict',
+ 410: 'Gone',
+ 411: 'Length Required',
+ 412: 'Precondition Required',
+ 413: 'Request Entry Too Large',
+ 414: 'Request-URI Too Long',
+ 415: 'Unsupported Media Type',
+ 416: 'Requested Range Not Satisfiable',
+ 417: 'Expectation Failed',
+ 418: 'I\'m a teapot',
+ 429: 'Too Many Requests',
+ 500: 'Internal Server Error',
+ 501: 'Not Implemented',
+ 502: 'Bad Gateway',
+ 503: 'Service Unavailable',
+ 504: 'Gateway Timeout',
+ 505: 'HTTP Version Not Supported',
+};
diff --git a/ufund-ui/src/app/components/need-list/need-list.component.css b/ufund-ui/src/app/components/need-list/need-list.component.css
index e69de29..bbc3f2c 100644
--- a/ufund-ui/src/app/components/need-list/need-list.component.css
+++ b/ufund-ui/src/app/components/need-list/need-list.component.css
@@ -0,0 +1,24 @@
+:host {
+ list-style-type:circle;
+ border: 2px solid #000;
+ display: block;
+ width: 30%;
+ border-radius: 5px;
+
+}
+
+li, div {
+ border: 2px solid #000;
+ border-radius: 5px;
+ padding: 5px;
+ margin: 5px;
+
+}
+
+#search-form {
+ background-color: #d9d9d9;
+ padding: 10px 20px 20px 20px;
+ border: 2px solid #000;
+ border-radius: 5px;
+ visibility: visible;
+ } \ No newline at end of file
diff --git a/ufund-ui/src/app/components/need-list/need-list.component.html b/ufund-ui/src/app/components/need-list/need-list.component.html
index 6e48d96..07f6735 100644
--- a/ufund-ui/src/app/components/need-list/need-list.component.html
+++ b/ufund-ui/src/app/components/need-list/need-list.component.html
@@ -1,6 +1,26 @@
<h1>Needs List</h1>
+<input id="search-button" type="button" value="Search" (click)="open()">
+<div id="search-form">
+ <form #searchForm="ngForm">
+ <label>Search:</label><br>
+ <input type="text" name="search" (input)="search(searchForm.value)" ngModel>
+ <input type="button" value="Clear" (click)="searchForm.reset()"> <br>
+ </form>
+ <button (click)="close()">Close</button>
+ <div>
+ <h2 id="search-status">Search Results:</h2>
+ <div *ngFor="let need of searchResults">
+ <a routerLink="/need/{{need.id}}">
+ {{need.name}}
+ </a>
+ <button (click)="delete(need.id)" *ngIf="isManager()">Delete</button>
+ </div>
+ </div>
+</div>
+
<li *ngFor="let need of needs">
<a routerLink="/need/{{need.id}}">
{{need.name}}
</a>
+ <button (click)="delete(need.id)" *ngIf="isManager()">Delete</button>
</li>
diff --git a/ufund-ui/src/app/components/need-list/need-list.component.ts b/ufund-ui/src/app/components/need-list/need-list.component.ts
index a3eb072..b21979f 100644
--- a/ufund-ui/src/app/components/need-list/need-list.component.ts
+++ b/ufund-ui/src/app/components/need-list/need-list.component.ts
@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import {Need} from '../../models/Need';
import {CupboardService} from '../../services/cupboard.service';
-
+import { UsersService } from '../../services/users.service';
+import { userType } from '../../models/User';
@Component({
selector: 'app-need-list',
standalone: false,
@@ -10,12 +11,92 @@ import {CupboardService} from '../../services/cupboard.service';
})
export class NeedListComponent {
needs: Need[] = [];
+ searchResults: Need[] = [];
constructor(
- private cupboardService: CupboardService
+ private cupboardService: CupboardService,
+ private usersService: UsersService
) {}
+ refresh() {
+ this.cupboardService.getNeeds().subscribe(n => this.needs = n)
+ }
+
ngOnInit(): void {
- this.cupboardService.getNeeds().subscribe(n => this.needs = n)
+ this.refresh()
+ // this.close();
+ }
+
+ private showElement(element: any) {
+ if (element){
+ element.style.visibility = 'visible';
+ element.style.position = 'relative';
+ }
+ }
+
+ private hideElement(element: any) {
+ if (element){
+ element.style.visibility = 'hidden';
+ element.style.position = 'absolute';
+ }
+ }
+
+ private updateSearchStatus(text: string) {
+ let element = document.getElementById('search-status');
+ if (element) {
+ element.innerHTML = text;
+ }
+ }
+
+ open() {
+ this.hideElement(document.getElementById('search-button'));
+ this.showElement(document.getElementById('search-form'));
+ }
+
+ close() {
+ this.hideElement(document.getElementById('search-form'));
+ this.showElement(document.getElementById('search-button'));
+ }
+
+ private searchDelay: any;
+
+ async search(form: any) {
+ //wait .25 seconds before searching but cancel if another search is made during the wait to prevent too many api calls
+
+ //remove previous search if it exists
+ if (this.searchDelay) {
+ clearTimeout(this.searchDelay);
+ }
+
+ this.searchDelay = setTimeout(() => {
+ const currentSearchValue = form.search; //latest value of the search
+ this.cupboardService.searchNeeds(currentSearchValue).subscribe((n) => {
+ this.searchResults = n;
+ console.log(currentSearchValue, this.searchResults);
+ if (this.searchResults.length === this.needs.length) {
+ this.updateSearchStatus("Please refine your search");
+ this.searchResults = [];
+ } else if (this.searchResults.length === 0) {
+ this.updateSearchStatus("No results found");
+ } else {
+ this.updateSearchStatus("Search results:");
+ }
+ });
+ }, 250);
+ }
+
+ delete(id : number) {
+ this.cupboardService.deleteNeed(id).subscribe(() => {
+ this.needs = this.needs.filter(n => n.id !== id)
+ })
+ }
+
+ isManager() {
+ const type = this.usersService.getCurrentUser()?.type;
+ return type === ("MANAGER" as unknown as userType);
+ }
+
+ back() {
+ this.searchResults = [];
}
}
diff --git a/ufund-ui/src/app/components/need-page/need-page.component.html b/ufund-ui/src/app/components/need-page/need-page.component.html
index 0bc4746..8234ac7 100644
--- a/ufund-ui/src/app/components/need-page/need-page.component.html
+++ b/ufund-ui/src/app/components/need-page/need-page.component.html
@@ -1,7 +1,21 @@
-<h1>Need page</h1>
-<p>id: {{need?.id}}</p>
-<p>name: {{need?.name}}</p>
-<p>filterAttributes: {{need?.filterAttributes}}</p>
-<p>type: {{need?.type}}</p>
-<p>max goal: {{need?.maxGoal}}</p>
-<p>current: {{need?.maxGoal}}</p>
+<h1>Viewing Need: {{need?.name}}</h1>
+<a>internal id: {{need?.id}}</a>
+<div style="display: flex; column-gap: 6px;">
+ <h3>Looking for</h3>
+ <h3><u>{{need?.type}}</u></h3>
+ <h3>Donations.</h3>
+</div>
+<div *ngIf="need?.filterAttributes != null">
+ <p>Tags:</p>
+ <ul style="display: flex; column-gap: 24px;">
+ <li *ngFor="let tag of need?.filterAttributes">
+ <p>{{tag}}</p>
+ </li>
+ </ul>
+</div>
+
+<hr>
+
+<p>Goal: {{need?.maxGoal}}</p>
+<p>Current: {{need?.current}}</p>
+<p>This goal is <strong>{{((need?.current ?? 0)*100) / (need?.maxGoal ?? 0)}}%</strong> complete!</p> \ No newline at end of file
diff --git a/ufund-ui/src/app/components/need-page/need-page.component.ts b/ufund-ui/src/app/components/need-page/need-page.component.ts
index 15c1e87..597d0e0 100644
--- a/ufund-ui/src/app/components/need-page/need-page.component.ts
+++ b/ufund-ui/src/app/components/need-page/need-page.component.ts
@@ -1,7 +1,8 @@
import {Component, Input} from '@angular/core';
-import {Need} from '../../models/Need';
+import {GoalType, Need} from '../../models/Need';
import {ActivatedRoute} from "@angular/router";
import {CupboardService} from "../../services/cupboard.service";
+import { NgFor } from '@angular/common';
@Component({
selector: 'app-need-page',
@@ -15,10 +16,16 @@ export class NeedPageComponent {
private cupboardService: CupboardService,
) {}
+ public GoalType = GoalType;
+
@Input() need?: Need;
ngOnInit(): void {
const id = Number(this.route.snapshot.paramMap.get('id'));
this.cupboardService.getNeed(id).subscribe(n => this.need = n);
}
-}
+
+ back() {
+ window.history.back();
+ }
+} \ No newline at end of file