diff options
Diffstat (limited to 'ufund-ui/src')
6 files changed, 246 insertions, 185 deletions
diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.css b/ufund-ui/src/app/components/cupboard/cupboard.component.css index fe4971a..6e70951 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.css +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.css @@ -1,21 +1,43 @@  :host { -    display: block; +    display: flex; +    justify-content: space-evenly;      border: 2px solid #000;      border-radius: 5px;      padding: 10px 20px; +    > div { +      width: 40%; +    }  } -#menu, #create-form, #delete-form, #update-form { + +#menu { +      display: flex; +       +      margin: 10px; +       +} + +.tab, .selected-tab { +   background-color: lightgray; +   border: 3px solid #000; +   border-top-left-radius: 5px; +   border-top-right-radius: 5px; +   margin-right: 5px; +   border-bottom: 0px; +} + +.selected-tab { +   background-color: white; +} + +#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 0d64475..d54eed9 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.html +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.html @@ -1,50 +1,47 @@ -<h1> Cupboard </h1> -<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> +    <h1> Cupboard </h1> +    <app-need-list (currentNeed) = populateForm($event) #needList></app-need-list>  </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> +<div *ngIf="isManager()" > +    <h2 > Admin View </h2> +    <div id="menu"> +        <button [ngClass]="selectedForm === 'create' ? 'selected-tab' : 'tab'" (click)="selectForm('create')">Create new Need</button> +        <button [ngClass]="selectedForm === 'update' ? 'selected-tab' : 'tab'" (click)="selectForm('update')">Update existing Need</button> +    </div> +    <div id="create-form" *ngIf="selectedForm === 'create'"> +        <h1> Create 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> +        <span *ngIf="statusText">{{statusText | async}}</span> -</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"> +    </div> +    <div id="update-form" *ngIf="selectedForm === 'update'"> +        <h1> Update Need </h1> +        <label>Needs:</label><br> +        <form #updateForm="ngForm" (ngSubmit)="update(updateForm.value)"> +            <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> +        <span *ngIf="statusText">{{statusText | async}}</span> -            <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>  </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 24b3e2d..a8b9c14 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.ts +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import {Component, Input, OnInit, ViewChild} from '@angular/core';  import { CupboardService } from '../../services/cupboard.service';  import { UsersService } from '../../services/users.service';  import { Need, GoalType } from '../../models/Need'; @@ -16,17 +16,13 @@ import { NeedListComponent } from '../need-list/need-list.component';  export class CupboardComponent implements OnInit {      protected statusText = new BehaviorSubject("") - +    selectedForm = "create";      needs: any; -    @ViewChild("needList") needList?: NeedListComponent - +    @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 { @@ -41,49 +37,36 @@ export class CupboardComponent implements OnInit {          type: ''      };      selectedNeedId: number | null = null; +    searchResults: any[] = []; -    private hideElement(element: any) { -        if (element) { -            element.style.visibility = 'hidden'; -            element.style.position = 'absolute'; +    selectForm(name: string) { +        //get search results from the need list +        if (this.needList) { +            this.searchResults = this.needList.searchResults;          } -    } +        console.log(this.searchResults) +        this.selectedForm = name; +        if (name == 'update') { +            if (this.searchResults) { +                this.searchResults.forEach((element: any) => { +                    console.log(element) +                }); +            } -    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')); +    async updateSearchResults() { +        if (this.needList) { +            while (this.selectedForm == 'update') { +                this.searchResults = this.needList.searchResults +                await new Promise(resolve => setTimeout(resolve, 100)); +            } +        }      }      populateForm(need: any): void { +        this.selectForm('update');          this.selectedNeed = { ...need };      } @@ -96,14 +79,13 @@ export class CupboardComponent implements OnInit {          console.log(form);          const need: Need = {              name: form.name, -            id: form.id, //system will control this +            id: this.selectedNeed.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) => {                  if (ex.status == 500) { 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 bbc3f2c..2eb6a8d 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 @@ -1,24 +1,70 @@  :host { -    list-style-type:circle; +    --list-background-color: lightgray; +    list-style-type: none;      border: 2px solid #000;      display: block; -    width: 30%;      border-radius: 5px; -      } -li, div { +div {      border: 2px solid #000;      border-radius: 5px;      padding: 5px;      margin: 5px; +} + +ul { +    list-style-type: none; +    padding-inline-start: 0px; +} + +li { +    background-color: var(--list-background-color); +    display: flex; +    justify-content: space-between; +    align-items: center; +    transition: all 0.3s ease; +    font-weight: bold; +    border: 2px solid #000; +    border-radius: 5px; +    margin: 5px;  +    > button { +        background-color: transparent; +        width: 88%; +        float: left; +        transition: all 0.3s ease; +        font-weight: bold; +        display: flex; +        border: none; +        border-radius: 5px; +    } + +    > section { +        width: 12%; +    } +} +section button{ +    margin: 4%;  } -#search-form { +li > button span { +    font-style: italic; +    font-weight: normal; +} + +li > button:hover p { +    text-decoration: underline; +} + + +.icon { +    width: 18px; +    margin: 3px -3px -1px -3px; +} + +#search-container {      background-color: #d9d9d9; -    padding: 10px 20px 20px 20px;      border: 2px solid #000; -    border-radius: 5px;   -    visibility: visible; +    border-radius: 5px;   }
\ 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 283cc99..de4be58 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,5 +1,6 @@  <h1>Needs List</h1> -<div style="display: flex;"> +<div id="search-container"> +  <div style="display: flex;">      <h3>Sort by:</h3>      <table style="margin-left: 10px; display: flex; column-gap: 24px;">          <tr><h3><button (click)="changeSortAlgo('sortByName',searchForm.value)">Name(A-Z)</button></h3></tr> @@ -7,31 +8,33 @@          <tr><h3><button (click)="changeSortAlgo('sortByMaxGoal',searchForm.value)">Max Goal(Descending)</button></h3></tr>          <tr><h3><button (click)="changeSortAlgo('sortByMinGoal',searchForm.value)">Max Goal(Ascending)</button></h3></tr>      </table> -</div> -<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> +  </div> +    <form id="search-form" #searchForm="ngForm"> +        <input type="text" name="search" placeholder="Search in {{needs.length}} needs..." (input)="search(searchForm.value)" ngModel> +        <input type="reset" value="Clear" (click)="search(null)"> <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> -            <!-- <button (click)="add(need)" *ngIf="isHelper()">Add To Basket</button> --> -        </div> -    </div> +    <!--<button (click)="close()">Close</button>-->  </div> -<li *ngFor="let need of needs"> -    <a routerLink="/need/{{need.id}}"> -        {{need.name}} -    </a> -    <button (click)="delete(need.id)" *ngIf="isManager()">Delete</button> -    <button (click)="add(need)" *ngIf="isHelper()">Add To Basket</button> -</li> +<!-- display for when results are present and filtered--> +<h2 *ngIf="searchResults.length < needs.length && searchResults.length != 0"> Search Results({{needs.length - searchResults.length}} needs filtered): </h2> +<h2 *ngIf="searchResults.length == needs.length"> All Needs </h2> +<h2 *ngIf="searchResults.length == 0"> No Results Found </h2> + +<ul> +    <li *ngFor="let need of searchResults" id="need-button-{{need.id}}"> +        <button [routerLink]="'/need/' + need.id" (mouseenter) ="changeText(need.id, '(details)')" (mouseleave)="changeText(need.id, '')"> +            <p>{{need.name}}<span id="hover-status-label-{{need.id}}"> </span></p> +        </button> + +        <button (click)="add(need)" *ngIf="isHelper()">Add To Basket</button> +        <section *ngIf="isManager()"> +            <button (click)="select(need)" id="need-edit-button-{{need.id}}"> +                <img class="icon" src="/edit.png" alt="Select"> +            </button> +            <button (click)="delete(need.id)" *ngIf="isManager()">  +                <img class="icon" src="/delete.png" alt="Delete"> +            </button> +        </section> +    </li> +</ul>
\ No newline at end of file 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 06bb17e..208045f 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,4 +1,5 @@ -import { Component, Input } from '@angular/core'; +import {Component, input, Output, EventEmitter} from '@angular/core'; +import { NgForm } from '@angular/forms';  import {Need} from '../../models/Need';  import {CupboardService} from '../../services/cupboard.service';  import { UsersService } from '../../services/users.service'; @@ -41,6 +42,7 @@ const sortByMinGoal: sortAlgo = (a: Need, b: Need): number => {    styleUrl: './need-list.component.css'  })  export class NeedListComponent { +  selectedNeed: Need | null = null;    needs: Need[] = [];    searchResults: Need[] = [];    currentSortAlgo: sortAlgo = sortByMaxGoal; @@ -52,51 +54,23 @@ export class NeedListComponent {      {func:sortByMinGoal,name:"sortByMinGoal"},    ]; +  @Output() currentNeed = new EventEmitter<Need>(); +    constructor(      private cupboardService: CupboardService,      private usersService: UsersService    ) {}      refresh() { -        this.cupboardService.getNeeds().subscribe(n => this.needs = n.sort(this.currentSortAlgo)) +        this.cupboardService.getNeeds().subscribe(n => { +          this.needs = n.sort(this.currentSortAlgo); +          this.searchResults = this.needs; +        }); +        console.log(this.searchResults);      }    ngOnInit(): void {      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')); -    this.hideElement(document.getElementById('search-status'));    }    changeSortAlgo(algoName: string, form: any) { @@ -121,25 +95,23 @@ export class NeedListComponent {      if (this.searchDelay) {        clearTimeout(this.searchDelay);      } - -    this.searchDelay = setTimeout(() => { -      const currentSearchValue = form.search; //latest value of the search -      console.log("current search value: ", currentSearchValue) -      this.cupboardService.searchNeeds(currentSearchValue).subscribe((n) => { -        this.searchResults = n.sort(this.currentSortAlgo); -        console.log(currentSearchValue, this.searchResults); -        this.showElement(document.getElementById('search-results')); -        this.showElement(document.getElementById('search-status')); -        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); +    if (form) { +      this.searchDelay = setTimeout(() => { + +        if (form) { +          const currentSearchValue = form.search; //latest value of the search +          this.cupboardService.searchNeeds(currentSearchValue).subscribe((n) => { +            this.searchResults = n.sort(this.currentSortAlgo); +            console.log(currentSearchValue, this.searchResults); +            }); +          } +        }, 250); +      } else { +        //user has cleared the search bar, we can skip the timeout for a 1/4 second faster response +        //clear timeout to stop pending search +        clearTimeout(this.searchDelay); +        this.searchResults = this.needs; +      }    }    delete(id : number) { @@ -158,6 +130,13 @@ export class NeedListComponent {      return type === ("HELPER" as unknown as userType);    } +  changeText(id : number, text : string) { +    const span = document.getElementById('hover-status-label-' + id); +    if (span) { +      span.innerHTML = ' ' + text; +    } +  } +    add(need: Need) {      const currentUser = this.usersService.getCurrentUser();      //console.log("get current user in angular:", currentUser) @@ -173,13 +152,45 @@ export class NeedListComponent {        } else {          window.alert("This need is already in your basket!")        } -       +      }    }    back() { -    this.searchResults = []; +    this.searchResults = this.needs; +  } + +  select(need : Need) { +    //emit value +    this.currentNeed.emit(need); +    if (this.selectedNeed) { +      //revert already selected need to previous style +      console.log(need.id); +      let button = document.getElementById('need-button-' + this.selectedNeed.id); +      if (button) { +        console.log(button) +        button.style.background = 'lightgray'; +        button.style.marginLeft = '0%'; +        button.style.width = '98%'; +      } +      button = document.getElementById('need-edit-button-' + this.selectedNeed.id); +      if (button) { +        button.style.visibility = 'visible'; +      } +    } +      //change selected need to selected style +      this.selectedNeed = need; +      let button = document.getElementById('need-button-' + need.id); +      if (button) { +        button.style.background = 'white'; +        button.style.marginLeft = '4%'; +        button.style.width = '100%'; +      } +      button = document.getElementById('need-edit-button-' + need.id); +      if (button) { +        button.style.visibility = 'hidden'; +      }    }  }  | 
