diff options
| author | sowgro <tpoke.ferrari@gmail.com> | 2025-03-26 15:38:46 -0400 | 
|---|---|---|
| committer | sowgro <tpoke.ferrari@gmail.com> | 2025-03-26 15:38:46 -0400 | 
| commit | ea13cf6ab3b71ff5e83fca876ec71fec1f7b00ae (patch) | |
| tree | 4450553037eaec406d8e0bb2c3a4200b188f01ea /ufund-ui/src | |
| parent | 5f03e80712f7a18370b5118fde5327bde1b6fbbf (diff) | |
| download | JellySolutions-ea13cf6ab3b71ff5e83fca876ec71fec1f7b00ae.tar.gz JellySolutions-ea13cf6ab3b71ff5e83fca876ec71fec1f7b00ae.tar.bz2 JellySolutions-ea13cf6ab3b71ff5e83fca876ec71fec1f7b00ae.zip  | |
Make frontend work with the new backend checkout system
Diffstat (limited to 'ufund-ui/src')
| -rw-r--r-- | ufund-ui/src/app/app.component.ts | 8 | ||||
| -rw-r--r-- | ufund-ui/src/app/components/cupboard/cupboard.component.ts | 58 | ||||
| -rw-r--r-- | ufund-ui/src/app/components/dashboard/dashboard.component.ts | 20 | ||||
| -rw-r--r-- | ufund-ui/src/app/components/funding-basket/funding-basket.component.ts | 122 | ||||
| -rw-r--r-- | ufund-ui/src/app/components/login/login.component.ts | 14 | ||||
| -rw-r--r-- | ufund-ui/src/app/components/need-list/need-list.component.ts | 212 | ||||
| -rw-r--r-- | ufund-ui/src/app/services/auth.service.ts | 57 | ||||
| -rw-r--r-- | ufund-ui/src/app/services/cupboard.service.ts | 30 | ||||
| -rw-r--r-- | ufund-ui/src/app/services/users.service.ts | 52 | 
9 files changed, 286 insertions, 287 deletions
diff --git a/ufund-ui/src/app/app.component.ts b/ufund-ui/src/app/app.component.ts index 7dc8ffb..86717c4 100644 --- a/ufund-ui/src/app/app.component.ts +++ b/ufund-ui/src/app/app.component.ts @@ -1,7 +1,7 @@  import {Component, OnInit, Inject} from '@angular/core'; -import {UsersService} from './services/users.service';  import {BehaviorSubject} from 'rxjs';  import { DOCUMENT } from '@angular/common'; +import {AuthService} from './services/auth.service';  @Component({    selector: 'app-root', @@ -14,16 +14,16 @@ export class AppComponent implements OnInit {      currentUser$: BehaviorSubject<string> = new BehaviorSubject<string>("Logged out.");      constructor( -        private userService: UsersService, +        private authService: AuthService,          @Inject(DOCUMENT) private document: Document      ) {}      reloadPage() {          this.document.defaultView?.location.reload(); -      } +    }      ngOnInit() { -        this.userService.getCurrentUserSubject().subscribe(r => { +        this.authService.getCurrentUserSubject().subscribe(r => {              this.currentUser$?.next(r                  ? "Logged in as " + r.username                  : "Logged out." diff --git a/ufund-ui/src/app/components/cupboard/cupboard.component.ts b/ufund-ui/src/app/components/cupboard/cupboard.component.ts index 24b3e2d..a812baf 100644 --- a/ufund-ui/src/app/components/cupboard/cupboard.component.ts +++ b/ufund-ui/src/app/components/cupboard/cupboard.component.ts @@ -1,10 +1,10 @@  import { Component, OnInit, ViewChild } from '@angular/core';  import { CupboardService } from '../../services/cupboard.service'; -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'; +import {AuthService} from '../../services/auth.service';  @Component({      selector: 'app-cupboard', @@ -20,7 +20,10 @@ export class CupboardComponent implements OnInit {      needs: any;      @ViewChild("needList") needList?: NeedListComponent -    constructor(private cupboardService: CupboardService, private usersService: UsersService) { } +    constructor( +        private cupboardService: CupboardService, +        private authService: AuthService +    ) {}      ngOnInit(): void {          this.cupboardService.getNeeds().subscribe(n => this.needs = n); @@ -88,7 +91,7 @@ export class CupboardComponent implements OnInit {      }      isManager() { -        const type = this.usersService.getCurrentUser()?.type; +        const type = this.authService.getCurrentUser()?.type;          return type === ("MANAGER" as unknown as userType);      } @@ -105,7 +108,7 @@ export class CupboardComponent implements OnInit {          console.log("need:", need);          console.log(need.id, need, "need updated");          this.cupboardService.updateNeed(need.id, need) -            .pipe(catchError((ex, r) => { +            .pipe(catchError((ex, _) => {                  if (ex.status == 500) {                      this.statusText.next("Fields cannot be blank");                  } else if (ex.status == 400) { @@ -140,7 +143,7 @@ export class CupboardComponent implements OnInit {          console.log("need:", need);          console.log("form submitted. creating need: ", need);          this.cupboardService.createNeed(need) -            .pipe(catchError((ex, r) => { +            .pipe(catchError((ex, _) => {                  if (ex.status == 500) {                      this.statusText.next("Fields cannot be blank");                  } else if (ex.status == 400) { @@ -167,48 +170,3 @@ export class CupboardComponent implements OnInit {      }  } - -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', -    422: 'Unprocessable Entity', -    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.ts b/ufund-ui/src/app/components/dashboard/dashboard.component.ts index b9faefa..a0ad566 100644 --- a/ufund-ui/src/app/components/dashboard/dashboard.component.ts +++ b/ufund-ui/src/app/components/dashboard/dashboard.component.ts @@ -1,21 +1,21 @@ -import { Component } from '@angular/core'; -import { UsersService } from '../../services/users.service'; -import { userType } from '../../models/User'; +import {Component} from '@angular/core'; +import {userType} from '../../models/User'; +import {AuthService} from '../../services/auth.service';  @Component({ -  selector: 'app-dashboard', -  standalone: false, -  templateUrl: './dashboard.component.html', -  styleUrl: './dashboard.component.css' +    selector: 'app-dashboard', +    standalone: false, +    templateUrl: './dashboard.component.html', +    styleUrl: './dashboard.component.css'  })  export class DashboardComponent {      constructor( -      protected usersService: UsersService, +        protected authService: AuthService,      ) {}      isManager() { -        const type = this.usersService.getCurrentUser()?.type; +        const type = this.authService.getCurrentUser()?.type;          return type === ("MANAGER" as unknown as userType); -      } +    }  } 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 e654711..faa7e0b 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 @@ -1,11 +1,9 @@  import {Component, Input, OnInit, ViewChild} from '@angular/core'; -import {User} from '../../models/User'; -import { UsersService } from '../../services/users.service'; -import { Need } from '../../models/Need'; -import { NeedListComponent } from '../need-list/need-list.component'; -import { Router } from '@angular/router'; -import { CupboardService } from '../../services/cupboard.service'; -import { BehaviorSubject, catchError, firstValueFrom, Observable } from 'rxjs'; +import {UsersService} from '../../services/users.service'; +import {Router} from '@angular/router'; +import {CupboardService} from '../../services/cupboard.service'; +import {catchError, firstValueFrom, Observable} from 'rxjs'; +import {AuthService} from '../../services/auth.service';  @Component({      selector: 'app-funding-basket', @@ -14,67 +12,67 @@ import { BehaviorSubject, catchError, firstValueFrom, Observable } from 'rxjs';      styleUrl: './funding-basket.component.css'  })  export class FundingBasketComponent implements OnInit { -  statusText: any; +    statusText: any; -  constructor( -    private router: Router, -    protected cupboardService: CupboardService,  -    protected usersService: UsersService -  ) {} +    constructor( +        private router: Router, +        protected cupboardService: CupboardService, +        protected usersService: UsersService, +        private authService: AuthService +    ) {} -  @ViewChild("contribution") contribution?: Input; -  @Input() isValid: boolean = true; +    @ViewChild("contribution") contribution?: Input; +    @Input() isValid: boolean = true; -  // this is for login rerouting -  ngOnInit(): void { -    if (!this.usersService.getCurrentUser()) { -      this.router.navigate(['/login'], {queryParams: {redir: this.router.url}}); -      return; -    } - -    this.usersService.refreshBasket(); -    // this.usersService.removeNeed(); <- call this to remove -  } +    // this is for login rerouting +    ngOnInit(): void { +        if (!this.authService.getCurrentUser()) { +            this.router.navigate(['/login'], {queryParams: {redir: this.router.url}}); +            return; +        } -  async checkout() { -    this.isValid = true; -    for (let c of document.getElementById("funding-basket")?.querySelectorAll('.contribution')!) { -      let contribution = c as HTMLInputElement; -      contribution.setAttribute("style",""); -      if ( contribution.value == '' || contribution.valueAsNumber <= 0) { -        this.isValid = false; -        contribution.setAttribute("style","color: #ff0000"); -      } +        this.usersService.refreshBasket(); +        // this.usersService.removeNeed(); <- call this to remove      } -    if (this.isValid) { -      for (let c of document.getElementById("funding-basket")?.querySelectorAll('.contribution')!) { -        let contribution = c as HTMLInputElement; -        let need = await firstValueFrom(this.cupboardService.getNeed(+contribution.id)); -        need.current +=+ contribution.value; -        this.usersService.removeNeed(+need.id); -        this.cupboardService.updateNeed(need.id, need) -            .pipe(catchError((ex, r) => { -                if (ex.status == 500) { -                    this.statusText.next('Fields cannot be blank'); -                } else if (ex.status == 400) { -                    this.statusText.next('Goal must be greater than 0'); -                } else { -                    this.statusText.next('Error on creating need'); -                } -                return new Observable<string>(); -            })) -            .subscribe((result) => { -                if (result) { -                    console.log('need updated successfully'); -                    //this.needList?.refresh() -                } else { -                    console.log('need update failed'); -                } -            }); -      } -    } -  } +    async checkout() { +        this.isValid = true; +        for (let c of document.getElementById("funding-basket")?.querySelectorAll('.contribution')!) { +            let contribution = c as HTMLInputElement; +            contribution.setAttribute("style", ""); +            if (contribution.value == '' || contribution.valueAsNumber <= 0) { +                this.isValid = false; +                contribution.setAttribute("style", "color: #ff0000"); +            } +        } +        if (this.isValid) { +            for (let c of document.getElementById("funding-basket")?.querySelectorAll('.contribution')!) { +                let contribution = c as HTMLInputElement; +                let need = await firstValueFrom(this.cupboardService.getNeed(+contribution.id)); +                need.current += +contribution.value; +                this.usersService.removeNeed(+need.id); +                this.cupboardService.checkoutNeed(need.id, +contribution.value) +                    .pipe(catchError((ex, _) => { +                        if (ex.status == 500) { +                            this.statusText.next('Fields cannot be blank'); +                        } else if (ex.status == 400) { +                            this.statusText.next('Goal must be greater than 0'); +                        } else { +                            this.statusText.next('Error on creating need'); +                        } +                        return new Observable<string>(); +                    })) +                    .subscribe((result) => { +                        if (result) { +                            console.log('need updated successfully'); +                            //this.needList?.refresh() +                        } else { +                            console.log('need update failed'); +                        } +                    }); +            } +        } +    }  } diff --git a/ufund-ui/src/app/components/login/login.component.ts b/ufund-ui/src/app/components/login/login.component.ts index 9d806f5..f6a2996 100644 --- a/ufund-ui/src/app/components/login/login.component.ts +++ b/ufund-ui/src/app/components/login/login.component.ts @@ -2,12 +2,13 @@ import {Component, OnInit} from '@angular/core'  import {UsersService} from '../../services/users.service';  import {ActivatedRoute, Router} from '@angular/router';  import {BehaviorSubject} from 'rxjs'; +import {AuthService} from '../../services/auth.service';  @Component({ -  selector: 'app-login', -  standalone: false, -  templateUrl: './login.component.html', -  styleUrl: './login.component.css' +    selector: 'app-login', +    standalone: false, +    templateUrl: './login.component.html', +    styleUrl: './login.component.css'  })  export class LoginComponent implements OnInit { @@ -17,7 +18,8 @@ export class LoginComponent implements OnInit {      constructor(          protected usersService: UsersService,          protected router: Router, -        private route: ActivatedRoute +        private route: ActivatedRoute, +        private authService: AuthService      ) {}      ngOnInit() { @@ -31,7 +33,7 @@ export class LoginComponent implements OnInit {              return;          } -        this.usersService.login(username, password).then(() => { +        this.authService.login(username, password).then(() => {              this.router.navigate([next]);          }).catch(ex => {              this.statusText.next("Unable to login: " + friendlyHttpStatus[ex.status]) 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 25f05d6..3a89a20 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,132 +1,138 @@ -import { Component } from '@angular/core'; +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'; +import {UsersService} from '../../services/users.service'; +import {userType} from '../../models/User'; +import {catchError, of} from 'rxjs'; +import {AuthService} from '../../services/auth.service'; +  @Component({ -  selector: 'app-need-list', -  standalone: false, -  templateUrl: './need-list.component.html', -  styleUrl: './need-list.component.css' +    selector: 'app-need-list', +    standalone: false, +    templateUrl: './need-list.component.html', +    styleUrl: './need-list.component.css'  })  export class NeedListComponent { -  needs: Need[] = []; -  searchResults: Need[] = []; +    needs: Need[] = []; +    searchResults: Need[] = []; -  constructor( -    private cupboardService: CupboardService, -    private usersService: UsersService -  ) {} +    constructor( +        private cupboardService: CupboardService, +        private usersService: UsersService, +        private authService: AuthService +    ) {}      refresh() {          this.cupboardService.getNeeds().subscribe(n => this.needs = n)      } -  ngOnInit(): void { -    this.refresh() -    -     this.close(); -  } +    ngOnInit(): void { +        this.refresh() -  private showElement(element: any) { -    if (element){ -      element.style.visibility = 'visible'; -      element.style.position = 'relative'; +        this.close();      } -  } -  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'; +        }      } -  } -  private updateSearchStatus(text: string) { -    let element = document.getElementById('search-status'); -    if (element) { -      element.innerHTML = text; +    private hideElement(element: any) { +        if (element) { +            element.style.visibility = 'hidden'; +            element.style.position = 'absolute'; +        }      } -  } -  open() { -    this.hideElement(document.getElementById('search-button')); -    this.showElement(document.getElementById('search-form')); -  } +    private updateSearchStatus(text: string) { +        let element = document.getElementById('search-status'); +        if (element) { +            element.innerHTML = text; +        } +    } -  close() { -    this.hideElement(document.getElementById('search-form')); -    this.showElement(document.getElementById('search-button')); -    this.hideElement(document.getElementById('search-status')); -  } +    open() { +        this.hideElement(document.getElementById('search-button')); +        this.showElement(document.getElementById('search-form')); +    } -  private searchDelay: any; +    close() { +        this.hideElement(document.getElementById('search-form')); +        this.showElement(document.getElementById('search-button')); +        this.hideElement(document.getElementById('search-status')); +    } -  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 +    private searchDelay: any; -    //remove previous search if it exists -    if (this.searchDelay) { -      clearTimeout(this.searchDelay); -    } +    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 -    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); -        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:"); +        //remove previous search if it exists +        if (this.searchDelay) { +            clearTimeout(this.searchDelay);          } -      }); -    }, 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); -  } - -  isHelper() { -    const type = this.usersService.getCurrentUser()?.type; -    return type === ("HELPER" as unknown as userType); -  } - -  add(need: Need) { -    const currentUser = this.usersService.getCurrentUser(); -    //console.log("get current user in angular:", currentUser) -    if (currentUser) { -      if (!currentUser.basket.includes(need.id)) { -        currentUser.basket.push(need.id); -        this.usersService.updateUser(currentUser).subscribe(() => { -          this.usersService.refreshBasket(); -          error: (err: any) => { -            console.error(err); -          } -        }); -      } else { -        window.alert("This need is already in your basket!") -      } -       +        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); +                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); +    } + +    delete(id: number) { +        this.cupboardService.deleteNeed(id).subscribe(() => { +            this.needs = this.needs.filter(n => n.id !== id) +        })      } -  } +    isManager() { +        const type = this.authService.getCurrentUser()?.type; +        return type === ("MANAGER" as unknown as userType); +    } + +    isHelper() { +        const type = this.authService.getCurrentUser()?.type; +        return type === ("HELPER" as unknown as userType); +    } + +    add(need: Need) { +        const currentUser = this.authService.getCurrentUser(); +        //console.log("get current user in angular:", currentUser) +        if (currentUser) { +            if (!currentUser.basket.includes(need.id)) { +                currentUser.basket.push(need.id); +                this.usersService.updateUser(currentUser) +                    .pipe(catchError((err: any, _) => { +                        console.error(err); +                        return of(); +                    })) +                    .subscribe(() => { +                        this.usersService.refreshBasket(); +                    }); +            } else { +                window.alert("This need is already in your basket!") +            } + -  back() { -    this.searchResults = []; -  } +        } + +    } + +    back() { +        this.searchResults = []; +    }  } diff --git a/ufund-ui/src/app/services/auth.service.ts b/ufund-ui/src/app/services/auth.service.ts new file mode 100644 index 0000000..6bc7145 --- /dev/null +++ b/ufund-ui/src/app/services/auth.service.ts @@ -0,0 +1,57 @@ +import {Injectable} from '@angular/core'; +import {BehaviorSubject, firstValueFrom} from 'rxjs'; +import {User} from '../models/User'; +import {HttpClient, HttpHeaders} from '@angular/common/http'; + +@Injectable({ +    providedIn: 'root' +}) +export class AuthService { + +    private authUrl = "http://localhost:8080/auth" +    private userUrl = "http://localhost:8080/users" + +    private currentUser : BehaviorSubject<User | null> = new BehaviorSubject<User | null>(null); +    private apiKey: string = ""; + +    httpOptions2 = () => ({ +        headers: new HttpHeaders({ +            'Content-Type': 'application/json', +            "jelly-api-key": this.apiKey +        }), +        responseType: "text" as "json" // don't ask me how or why this works, bc i have no clue... +        // see the relevant angular bug report https://github.com/angular/angular/issues/18586 +    }); + +    constructor( +        private http: HttpClient +    ) {} + +    async login(username: string, password: string) { +        let res = this.http.post<string>(this.authUrl, {username: username, password: password}, this.httpOptions2()); +        this.apiKey = await firstValueFrom(res); +        console.log("apikey: "+this.apiKey) +        let res2 = this.http.get<User>(`${this.userUrl}/${username}`, { +            headers: new HttpHeaders({ +                'Content-Type': 'application/json', +                "jelly-api-key": this.apiKey +            }) +        }) +        let currentU = await firstValueFrom(res2); +        this.currentUser.next(currentU); +        // this.currentUser.subscribe(r => console.log("currentUser: "+r.username)) +    } + +    getCurrentUserSubject() { +        return this.currentUser; +    } + +    getCurrentUser() { +        return this.currentUser.getValue() +    } + +    getApiKey() { +        return this.apiKey; +    } + +} diff --git a/ufund-ui/src/app/services/cupboard.service.ts b/ufund-ui/src/app/services/cupboard.service.ts index 9e14106..9232c0c 100644 --- a/ufund-ui/src/app/services/cupboard.service.ts +++ b/ufund-ui/src/app/services/cupboard.service.ts @@ -2,6 +2,7 @@ import {Injectable} from '@angular/core';  import {HttpClient, HttpHeaders} from '@angular/common/http';  import {Need} from '../models/Need';  import {Observable} from 'rxjs'; +import {AuthService} from './auth.service';  @Injectable({      providedIn: 'root' @@ -9,35 +10,44 @@ import {Observable} from 'rxjs';  export class CupboardService {      private url = "http://localhost:8080/cupboard" -    private httpOptions = { -        headers: new HttpHeaders({'Content-Type': 'application/json'}) -    }; + +    httpOptions = () => ({ +        headers: new HttpHeaders({ +            'Content-Type': 'application/json', +            "jelly-api-key": this.authService.getApiKey() +        }) +    });      constructor( -        private http: HttpClient +        private http: HttpClient, +        private authService: AuthService      ) {}      createNeed(need: Need): Observable<boolean> { -        return this.http.post<boolean>(this.url, need, this.httpOptions) +        return this.http.post<boolean>(this.url, need, this.httpOptions())      }      getNeeds(): Observable<Need[]> { -        return this.http.get<Need[]>(this.url, this.httpOptions) +        return this.http.get<Need[]>(this.url, this.httpOptions())      }      searchNeeds(name: String): Observable<Need[]> { -        return this.http.get<Need[]>(`${this.url}/?name=${name}`, this.httpOptions) +        return this.http.get<Need[]>(`${this.url}/?name=${name}`, this.httpOptions())      }      getNeed(id: number): Observable<Need> { -        return this.http.get<Need>(`${this.url}/${id}`, this.httpOptions) +        return this.http.get<Need>(`${this.url}/${id}`, this.httpOptions())      }      updateNeed(id: number, data: Need): Observable<boolean> { -        return this.http.put<boolean>(`${this.url}/${id}`, data, this.httpOptions) +        return this.http.put<boolean>(`${this.url}/${id}`, data, this.httpOptions())      }      deleteNeed(id: number): Observable<boolean> { -        return this.http.delete<boolean>(`${this.url}/${id}`, this.httpOptions) +        return this.http.delete<boolean>(`${this.url}/${id}`, this.httpOptions()) +    } + +    checkoutNeed(id: number, quantity: number) { +        return this.http.put(`${this.url}/checkout`, {needID: id, amount: quantity}, this.httpOptions())      }  } diff --git a/ufund-ui/src/app/services/users.service.ts b/ufund-ui/src/app/services/users.service.ts index 6671440..4080ebf 100644 --- a/ufund-ui/src/app/services/users.service.ts +++ b/ufund-ui/src/app/services/users.service.ts @@ -4,36 +4,27 @@ import {BehaviorSubject, catchError, firstValueFrom, Observable, of} from 'rxjs'  import {User} from '../models/User';  import { Need } from '../models/Need';  import { CupboardService } from './cupboard.service'; +import {AuthService} from './auth.service';  @Injectable({    providedIn: 'root'  })  export class UsersService { -    private currentUser : BehaviorSubject<User | null> = new BehaviorSubject<User | null>(null); -    private apiKey: string = "";      private basket = new BehaviorSubject<Need[]>([]); -      private url = "http://localhost:8080/users" -    private authUrl = "http://localhost:8080/auth" -    private httpOptions = () => ({ + +    httpOptions = () => ({          headers: new HttpHeaders({              'Content-Type': 'application/json', -            "jelly-api-key": this.apiKey +            "jelly-api-key": this.authService.getApiKey()          })      }); -    private httpOptions2 = () => ({ -        headers: new HttpHeaders({ -            'Content-Type': 'application/json', -            "jelly-api-key": this.apiKey -        }), -        responseType: "text" as "json" // don't ask me how or why this works, bc i have no clue... -        // see the relevant angular bug report https://github.com/angular/angular/issues/18586 -    });      constructor(          private http: HttpClient,          private cupboardService: CupboardService, +        private authService: AuthService      ) {}      async createUser(username:string, password:string) { @@ -46,38 +37,15 @@ export class UsersService {      updateUser(user: User): Observable<User> {          console.log(`${this.url}/${user.username}`, user, this.httpOptions) -        return this.http.put<User>(`${this.url}/${user.username}`, user, this.httpOptions2()) // This line is causing issues as the key is not properly being passed +        return this.http.put<User>(`${this.url}/${user.username}`, user, this.httpOptions())      }      deleteUser(id: number): Observable<boolean> {          return this.http.delete<boolean>(`${this.url}/${id}`, this.httpOptions())      } -    getCurrentUserSubject() { -        return this.currentUser; -    } - -    getCurrentUser() { -        return this.currentUser.getValue() -    } - -    async login(username: string, password: string) { -        let res = this.http.post<string>(this.authUrl, {username: username, password: password}, this.httpOptions2()); -        this.apiKey = await firstValueFrom(res); -        console.log("apikey: "+this.apiKey) -        let res2 = this.http.get<User>(`${this.url}/${username}`, { -            headers: new HttpHeaders({ -                'Content-Type': 'application/json', -                "jelly-api-key": this.apiKey -            }) -        }) -        let currentU = await firstValueFrom(res2); -        this.currentUser.next(currentU); -        // this.currentUser.subscribe(r => console.log("currentUser: "+r.username)) -    } -      refreshBasket() { -        let promiseArr = this.getCurrentUser()!.basket.map(async needID => { +        let promiseArr = this.authService.getCurrentUser()!.basket.map(async needID => {              return await firstValueFrom(this.cupboardService.getNeed(needID));          })          Promise.all(promiseArr).then(r => this.basket.next(r)); @@ -86,10 +54,10 @@ export class UsersService {      removeNeed(id: number) {          let newArr = this.basket.getValue().filter(v => v.id != id);          this.basket.next(newArr); -        this.getCurrentUser()!.basket = newArr.map(need => need.id); -        this.updateUser(this.getCurrentUser()!) +        this.authService.getCurrentUser()!.basket = newArr.map(need => need.id); +        this.updateUser(this.authService.getCurrentUser()!)              .pipe( -                catchError((err: any, ob) => { +                catchError((err: any, _) => {                      console.error(err);                      return of();                  })  | 
