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));  | 
