diff options
11 files changed, 125 insertions, 66 deletions
diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.html b/ufund-ui/src/app/components/cupboard/cupboard.component.html index cd8fec2..4eebc2d 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.html +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.html @@ -25,7 +25,7 @@ <span class="icon">{{sortMode === 'Ascending' ? 'arrow_upward': 'arrow_downward'}}</span> </button> <label>Needs per page: </label> - <input type ="number" [(ngModel)]="itemsPerPage" min="1" max="{{searchResults.length}}"> + <input type ="number" [(ngModel)]="itemsPerPage" (change)="editItemsPerPage()" min="1" max="{{searchResults.length}}"> </div> </div> <h2 *ngIf="searchResults.length < needs.length && searchResults.length != 0"> Search Results({{needs.length - searchResults.length}} needs filtered): </h2> @@ -46,5 +46,5 @@ <span class="icon">delete</span>Delete Need </button> </ng-template> - <app-need-list [actionArea]="NLActions" *ngIf="searchResults.length > 0" [needs]="searchResults" [itemsPerPage]="itemsPerPage" #needList/> + <app-need-list [uid]="0" [actionArea]="NLActions" *ngIf="searchResults.length > 0" [needs]="searchResults" [itemsPerPage]="itemsPerPage" #needList/> </div> diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.ts b/ufund-ui/src/app/components/cupboard/cupboard.component.ts index b03b77e..aca1397 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.ts +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.ts @@ -26,7 +26,7 @@ export class CupboardComponent implements OnInit { needs: Need[] = []; searchResults: Need[] = []; sortMode: 'Ascending' | 'Descending' = 'Ascending' - itemsPerPage = 5; + itemsPerPage = parseInt(localStorage.getItem('itemsPerPage') ?? '5') ?? 5; currentSortAlgo = 'sortByPriority'; constructor( @@ -135,6 +135,17 @@ export class CupboardComponent implements OnInit { } } + editItemsPerPage() { + if (this.itemsPerPage > this.searchResults.length) { + this.itemsPerPage = this.searchResults.length + } + if (this.itemsPerPage < 1) { + this.itemsPerPage = 1 + } + localStorage.setItem('itemsPerPage', this.itemsPerPage.toString()) + this.refresh(); + } + protected readonly SortingAlgorithms = SortingAlgoArrays; protected readonly Object = Object; } diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.css b/ufund-ui/src/app/components/dashboard/dashboard.component.css index 742a151..303b890 100644 --- a/ufund-ui/src/app/components/dashboard/dashboard.component.css +++ b/ufund-ui/src/app/components/dashboard/dashboard.component.css @@ -9,3 +9,31 @@ flex-direction: column; gap: 10px; } + +#stats { + display: flex; + flex-direction: row; + gap: 10px; +} + +.card { + background-color: #2e2e2e; + width: 400px; + height: 130px; + border-radius: 5px; + padding: 20px; + display: flex; + flex-direction: column; + +} + +.listCard { + background-color: #2e2e2e; + border-radius: 5px; + padding: 10px; + +} + +.content { + align-self: end; +} diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.html b/ufund-ui/src/app/components/dashboard/dashboard.component.html index 074ca76..233096a 100644 --- a/ufund-ui/src/app/components/dashboard/dashboard.component.html +++ b/ufund-ui/src/app/components/dashboard/dashboard.component.html @@ -1,15 +1,27 @@ <div id="box"> @if ((authService.getCurrentUserSubject() | async)?.type === userType.MANAGER) { <h1>Admin Dashboard</h1> - <span>_ Registered users</span> - <span *ngIf="count"> {{count | async}} </span> - <span>_ Fulfilled needs</span> - <app-mini-need-list [needList]="fulfilledNeeds.getValue()" label="Fulfilled needs"> </app-mini-need-list> - <span>_ Most fulfilled needs</span> - <app-mini-need-list [needList]="mostFulfilledNeeds.getValue()" label="Most fulfilled"> </app-mini-need-list> - <span>_ Total monetary contributions</span> - <span *ngIf="totalDonations">${{totalDonations | async}} </span> - <span>_ </span> + <div id="stats"> + <div class="card"> + <span>Registered users</span> + <h1 class="content" *ngIf="count"> {{count | async}} </h1> + </div> + + <div class="card"> + <span>Total monetary contributions</span> + <h1 class="content" *ngIf="totalDonations"> ${{totalDonations | async}} </h1> + </div> + </div> + + <div class="listCard"> + <span>Fulfilled needs</span> + <app-mini-need-list [needList]="fulfilledNeeds.getValue()" label="Fulfilled needs"> </app-mini-need-list> + </div> + <div class="listCard"> + <span>Most fulfilled needs</span> + <app-mini-need-list [needList]="mostFulfilledNeeds.getValue()" label="Most fulfilled"> </app-mini-need-list> + </div> + } @else { <h1>Unauthorized</h1> <span>This page requires you to be logged in as an admin! <a routerLink="/login">Log In</a></span> diff --git a/ufund-ui/src/app/components/funding-basket/funding-basket.component.css b/ufund-ui/src/app/components/funding-basket/funding-basket.component.css index c46ef57..a1485a0 100644 --- a/ufund-ui/src/app/components/funding-basket/funding-basket.component.css +++ b/ufund-ui/src/app/components/funding-basket/funding-basket.component.css @@ -80,3 +80,11 @@ padding: 5px; gap: 5px; } + +#footer { + display: flex; + flex-direction: row; + align-items: center; + gap: 20px; + margin-bottom: 10px; +} diff --git a/ufund-ui/src/app/components/funding-basket/funding-basket.component.html b/ufund-ui/src/app/components/funding-basket/funding-basket.component.html index 3f840e1..7158194 100644 --- a/ufund-ui/src/app/components/funding-basket/funding-basket.component.html +++ b/ufund-ui/src/app/components/funding-basket/funding-basket.component.html @@ -8,10 +8,11 @@ <span class="icon">delete</span>Remove from Basket </button> </ng-template> - <app-need-list [actionArea]="NLActions" [needs]="(usersService.getBasket() | async)!"/> + <app-need-list [uid]="1" [actionArea]="NLActions" [needs]="(usersService.getBasket() | async)!"/> <br> <div id="footer"> <button class="button2" title="checkout" (click)="checkout()">Checkout</button> + <span id="running-total">Your current running total is: ${{runningTotal | async}}</span> </div> </ng-template> <div *ngIf="!usersService.getBasket().getValue().length"> 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 371015a..78ce958 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 @@ -2,10 +2,11 @@ import {Component, Input, OnInit, ViewChild} from '@angular/core'; import {UsersService} from '../../services/users.service'; import {Router} from '@angular/router'; import {CupboardService} from '../../services/cupboard.service'; -import {firstValueFrom, of} from 'rxjs'; +import {BehaviorSubject, firstValueFrom, of} from 'rxjs'; import {AuthService} from '../../services/auth.service'; import {ToastsService, ToastType} from '../../services/toasts.service'; import {userType} from '../../models/User'; +import {GoalType} from '../../models/Need'; @Component({ selector: 'app-funding-basket', @@ -23,6 +24,7 @@ export class FundingBasketComponent implements OnInit { private toastService: ToastsService ) {} + public runningTotal = new BehaviorSubject(0) @ViewChild("contribution") contribution?: Input; ngOnInit(): void { @@ -59,8 +61,18 @@ export class FundingBasketComponent implements OnInit { } resetColor(ev: any) { - // for (let contribution of document.querySelectorAll<HTMLInputElement>('.contribution')!) {} - (ev.target as HTMLInputElement).setAttribute("style", "") + let total = 0 + this.runningTotal.next(total); + for (let contribution of document.querySelectorAll<HTMLInputElement>('.contribution')!) { + this.cupboardService.getNeed(+contribution.id).subscribe(need => { + if (contribution.value != '' && need.type != GoalType.PHYSICAL) { + total += contribution.valueAsNumber + } + this.runningTotal.next(total); + }) + } + + (ev.target as HTMLInputElement).setAttribute("style", "border-color: unset") } protected readonly of = of; 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 40af9f5..7ca0ae7 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 @@ -10,42 +10,46 @@ import {GoalType, Need} from '../../models/Need'; export class NeedListComponent implements OnChanges { @Input({required: true}) needs!: Need[] + @Input({required: true}) uid!: number @Input() itemsPerPage: number = 5; @Input() actionArea: TemplateRef<any> | null = null visibleNeeds: Need[] = []; - currentPage: number = 0; + currentPage: number = parseInt(localStorage.getItem('currentPage'+this.uid) ?? '0') ?? 0; totalPages: number = 0; - constructor( - - ) {} - ngOnChanges() { this.updateVisibleNeeds() + this.currentPage = parseInt(localStorage.getItem('currentPage'+this.uid) ?? '0') ?? 0; } getPrefix(need: Need) { return (need.type === GoalType.MONETARY) ? "$" : ""; } + //increment/decrement decrementPage() { this.currentPage--; + localStorage.setItem('currentPage'+this.uid, this.currentPage.toString()); this.updateVisibleNeeds(); } incrementPage() { this.currentPage++; + localStorage.setItem('currentPage'+this.uid, this.currentPage.toString()); this.updateVisibleNeeds(); } + //skipping pages lastPage() { this.currentPage = this.totalPages - 1 + localStorage.setItem('currentPage'+this.uid, this.currentPage.toString()); this.updateVisibleNeeds() } firstPage() { this.currentPage = 0 + localStorage.setItem('currentPage'+this.uid, this.currentPage.toString()); this.updateVisibleNeeds() } diff --git a/ufund-ui/src/app/components/need-page/need-page.component.css b/ufund-ui/src/app/components/need-page/need-page.component.css index f1b7f1f..6ca1350 100644 --- a/ufund-ui/src/app/components/need-page/need-page.component.css +++ b/ufund-ui/src/app/components/need-page/need-page.component.css @@ -4,11 +4,13 @@ } #box { + /*padding-top: 7.5%;*/ display: flex; flex-direction: column; width: 800px; justify-content: start; gap: 10px; + padding: 0 10px; } .needName { @@ -22,32 +24,19 @@ /*margin-bottom: 20px;*/ } -.split { - display: flex; - flex-direction: row; - justify-content: space-between; - - - .left { - display: flex; - flex-direction: column; - width : 50%; - } - - .right { - display: flex; - flex-direction: column; - align-items: end; - } -} .need-image { - width: 400px; - height: auto; + width: calc(100% + 40px); + height: 40%; + /*position: absolute;*/ + left: 22.5%; aspect-ratio: 16/9; object-fit: cover; + mask-image: linear-gradient(to bottom, rgba(255,255,255,1) 0%, rgba(255,255,255,.2) 80%, rgba(255,255,255,.1) 90%, transparent 100%); border-radius: 10px; - box-shadow: rgb(0, 40, 70) 0 0 50px; + margin-left: -20px; + margin-right: -20px; + margin-bottom: -80px; } .urgent { 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 ff5990f..2629346 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,5 +1,6 @@ <div id="box"> @if (need) { + <img *ngIf="need.image" alt="Need image" class="need-image" [src]="need.image"/> <h1>{{need.name}}</h1> <span class="needType">{{need.type}} GOAL</span> <p>{{need.description}}</p> @@ -8,35 +9,26 @@ <span>This goal is <strong>{{(((need.current)*100) / (need.maxGoal)).toFixed(0)}}%</strong> complete!</span> </div> + <span><strong>Target Goal:</strong> {{(need.type === GoalType.MONETARY) ? "$" : ""}}{{need.maxGoal}}</span> - <div class="split"> - <div class="left"> - <span><strong>Target Goal:</strong> {{(need.type === GoalType.MONETARY) ? "$" : ""}}{{need.maxGoal}}</span> + <span><strong>Amount Currently Collected:</strong> {{need.type.toString() == 'MONETARY' ? '$' : ''}}{{need.current}}</span> - <span><strong>Amount Currently Collected:</strong> {{need.type.toString() == 'MONETARY' ? '$' : ''}}{{need.current}}</span> + <span><strong>Location:</strong> {{need.location}}</span> - <span><strong>Location:</strong> {{need.location}}</span> + <span><strong>Urgency: </strong> + <span *ngIf="!need.urgent">Not urgent</span> + <span *ngIf="need.urgent" class="urgent">URGENT</span> + </span> - <span><strong>Urgency: </strong> - <span *ngIf="!need.urgent">Not urgent</span> - <span *ngIf="need.urgent" class="urgent">URGENT</span> - </span> - - <div *ngIf="need.filterAttributes?.length"> - <strong>Tags:</strong> - <ul style="display: flex; column-gap: 24px;"> - <li *ngFor="let tag of need?.filterAttributes"> - <p>{{tag}}</p> - </li> - </ul> - </div> - </div> - <div class="right"> - <img *ngIf="need.image" alt="Need image" class="need-image" [src]="need.image"/> - </div> + <div *ngIf="need.filterAttributes?.length"> + <strong>Tags:</strong> + <ul style="display: flex; column-gap: 24px;"> + <li *ngFor="let tag of need?.filterAttributes"> + <p>{{tag}}</p> + </li> + </ul> </div> - <div class="actionArea"> <button *ngIf="usersService.isHelper()" (click)="add(need)" [disabled]="usersService.inBasket(usersService.getBasket() | async, need)"> <span class="icon">{{usersService.inBasket(usersService.getBasket() | async, need)? "check": "add" }}</span>Add To Basket diff --git a/ufund-ui/src/app/services/users.service.ts b/ufund-ui/src/app/services/users.service.ts index 35d080d..688d6e4 100644 --- a/ufund-ui/src/app/services/users.service.ts +++ b/ufund-ui/src/app/services/users.service.ts @@ -60,7 +60,9 @@ export class UsersService { } refreshBasket() { - let promiseArr = this.authService.getCurrentUser()!.basket.map(async needID => { + let usr = this.authService.getCurrentUser(); + if (!usr) return; + let promiseArr = usr.basket.map(async needID => { return await firstValueFrom(this.cupboardService.getNeed(needID)); }) Promise.all(promiseArr).then(r => this.basket.next(r)); |