aboutsummaryrefslogtreecommitdiff
path: root/ufund-ui
diff options
context:
space:
mode:
Diffstat (limited to 'ufund-ui')
-rw-r--r--ufund-ui/src/app/app-routing.module.ts2
-rw-r--r--ufund-ui/src/app/app.component.html4
-rw-r--r--ufund-ui/src/app/app.component.ts23
-rw-r--r--ufund-ui/src/app/app.module.ts14
-rw-r--r--ufund-ui/src/app/components/dashboard/dashboard.component.html4
-rw-r--r--ufund-ui/src/app/components/dashboard/dashboard.component.ts2
-rw-r--r--ufund-ui/src/app/components/funding-basket/funding-basket.component.ts16
-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/models/Need.ts2
-rw-r--r--ufund-ui/src/app/models/User.ts2
-rw-r--r--ufund-ui/src/app/services/cupboard.service.ts3
-rw-r--r--ufund-ui/src/app/services/users.service.ts48
14 files changed, 207 insertions, 28 deletions
diff --git a/ufund-ui/src/app/app-routing.module.ts b/ufund-ui/src/app/app-routing.module.ts
index d4f14da..4b76654 100644
--- a/ufund-ui/src/app/app-routing.module.ts
+++ b/ufund-ui/src/app/app-routing.module.ts
@@ -12,7 +12,7 @@ const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: 'cupboard', component: CupboardComponent},
{path: 'dashboard', component: DashboardComponent},
- {path: 'funding-basket', component: FundingBasketComponent},
+ {path: 'basket', component: FundingBasketComponent},
{path: 'need/:id', component: NeedPageComponent}
];
diff --git a/ufund-ui/src/app/app.component.html b/ufund-ui/src/app/app.component.html
index cfebc2b..6b9338c 100644
--- a/ufund-ui/src/app/app.component.html
+++ b/ufund-ui/src/app/app.component.html
@@ -1,4 +1,6 @@
-<h1>jelly solutions:</h1>
+<h1>jelly solutions</h1>
+<span>{{currentUser$ | async}}</span>
+<hr>
<router-outlet />
diff --git a/ufund-ui/src/app/app.component.ts b/ufund-ui/src/app/app.component.ts
index 2dbf33c..6f4e1f5 100644
--- a/ufund-ui/src/app/app.component.ts
+++ b/ufund-ui/src/app/app.component.ts
@@ -1,4 +1,6 @@
-import { Component } from '@angular/core';
+import {Component, OnInit} from '@angular/core';
+import {UsersService} from './services/users.service';
+import {BehaviorSubject} from 'rxjs';
@Component({
selector: 'app-root',
@@ -6,6 +8,21 @@ import { Component } from '@angular/core';
standalone: false,
styleUrl: './app.component.css'
})
-export class AppComponent {
- title = 'ufund-ui';
+export class AppComponent implements OnInit {
+ // title = 'ufund-ui';
+ currentUser$: BehaviorSubject<string> = new BehaviorSubject<string>("Logged out.");
+
+ constructor(
+ private userService: UsersService
+ ) {}
+
+ ngOnInit() {
+ this.userService.getCurrentUserSubject().subscribe(r => {
+ this.currentUser$?.next(r
+ ? "Logged in as " + r.username
+ : "Logged out."
+ )
+ })
+ }
+
}
diff --git a/ufund-ui/src/app/app.module.ts b/ufund-ui/src/app/app.module.ts
index d818841..9f525fe 100644
--- a/ufund-ui/src/app/app.module.ts
+++ b/ufund-ui/src/app/app.module.ts
@@ -9,6 +9,11 @@ import {FundingBasketComponent} from './components/funding-basket/funding-basket
import {CupboardComponent} from './components/cupboard/cupboard.component';
import {NeedListComponent} from './components/need-list/need-list.component';
import {HttpClientModule} from '@angular/common/http';
+import {FormsModule} from '@angular/forms';
+import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
+import {DashboardComponent} from './components/dashboard/dashboard.component';
+import {CommonModule} from '@angular/common';
+import {LoginComponent} from './components/login/login.component';
@NgModule({
declarations: [
@@ -17,11 +22,18 @@ import {HttpClientModule} from '@angular/common/http';
HomePageComponent,
FundingBasketComponent,
CupboardComponent,
- NeedListComponent
+ NeedListComponent,
+ DashboardComponent,
+ LoginComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
+ FormsModule,
+ RouterLink,
+ RouterLinkActive,
+ RouterOutlet,
+ CommonModule,
HttpClientModule,
],
providers: [],
diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.html b/ufund-ui/src/app/components/dashboard/dashboard.component.html
index 9c5fce9..c73849f 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>
+<ul>
+ <li><a routerLink="/cupboard">Go to the Cupboard</a></li>
+ <li><a routerLink="/basket">Go to my basket</a></li>
+</ul>
diff --git a/ufund-ui/src/app/components/dashboard/dashboard.component.ts b/ufund-ui/src/app/components/dashboard/dashboard.component.ts
index 6da4013..dd323c4 100644
--- a/ufund-ui/src/app/components/dashboard/dashboard.component.ts
+++ b/ufund-ui/src/app/components/dashboard/dashboard.component.ts
@@ -7,5 +7,5 @@ import { Component } from '@angular/core';
styleUrl: './dashboard.component.css'
})
export class DashboardComponent {
-
+ constructor() {}
}
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 8b12306..c44aa27 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,4 +1,6 @@
-import { Component } from '@angular/core';
+import {Component, OnInit} from '@angular/core';
+import {Router} from '@angular/router';
+import {UsersService} from '../../services/users.service';
@Component({
selector: 'app-funding-basket',
@@ -6,6 +8,16 @@ import { Component } from '@angular/core';
templateUrl: './funding-basket.component.html',
styleUrl: './funding-basket.component.css'
})
-export class FundingBasketComponent {
+export class FundingBasketComponent implements OnInit{
+ constructor(
+ private router: Router,
+ private userService: UsersService
+ ) {}
+
+ ngOnInit() {
+ if (!this.userService.getCurrentUser()) {
+ this.router.navigate(['/login'], {queryParams: {redir: this.router.url}})
+ }
+ }
}
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/models/Need.ts b/ufund-ui/src/app/models/Need.ts
index c0425ec..9e97fd4 100644
--- a/ufund-ui/src/app/models/Need.ts
+++ b/ufund-ui/src/app/models/Need.ts
@@ -1,7 +1,7 @@
export interface Need {
name: string,
id: number,
- filterAttributes: String[],
+ filterAttributes: string[],
type: GoalType;
maxGoal: number;
current: number;
diff --git a/ufund-ui/src/app/models/User.ts b/ufund-ui/src/app/models/User.ts
index 46fe4a1..9149fe7 100644
--- a/ufund-ui/src/app/models/User.ts
+++ b/ufund-ui/src/app/models/User.ts
@@ -2,5 +2,5 @@ import {Need} from './Need';
export interface User {
username: string;
- cupboard: Need[];
+ basket: Need[];
}
diff --git a/ufund-ui/src/app/services/cupboard.service.ts b/ufund-ui/src/app/services/cupboard.service.ts
index c123841..4a2b4b0 100644
--- a/ufund-ui/src/app/services/cupboard.service.ts
+++ b/ufund-ui/src/app/services/cupboard.service.ts
@@ -18,8 +18,7 @@ export class CupboardService {
) {}
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[]> {
diff --git a/ufund-ui/src/app/services/users.service.ts b/ufund-ui/src/app/services/users.service.ts
index 571c004..c570ccf 100644
--- a/ufund-ui/src/app/services/users.service.ts
+++ b/ufund-ui/src/app/services/users.service.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
-import {Observable} from 'rxjs';
+import {BehaviorSubject, firstValueFrom, Observable} from 'rxjs';
import {User} from '../models/User';
@Injectable({
@@ -8,22 +8,35 @@ import {User} from '../models/User';
})
export class UsersService {
- private currentUserID? : number
+ private currentUser : BehaviorSubject<User | null> = new BehaviorSubject<User | null>(null);
+ private apiKey: string = "";
private url = "http://localhost:8080/users"
+ private authUrl = "http://localhost:8080/auth"
private httpOptions = {
- headers: new HttpHeaders({'Content-Type': 'application/json'})
+ headers: new HttpHeaders({
+ 'Content-Type': 'application/json',
+ "jelly-api-key": this.apiKey
+ })
+ };
+ 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
) {}
- createUser(data: User): Observable<User> {
- return this.http.post<User>(this.url, data, this.httpOptions)
+ async createUser(username:string, password:string) {
+ await firstValueFrom(this.http.post<User>(this.url, {username: username, password: password}, this.httpOptions))
}
- getUser(id: number): Observable<User> {
+ getUser(id: string): Observable<User> {
return this.http.get<User>(`${this.url}/${id}`, this.httpOptions)
}
@@ -35,7 +48,26 @@ export class UsersService {
return this.http.delete<boolean>(`${this.url}/${id}`, this.httpOptions)
}
- getCurrentUser(): Observable<User> | undefined {
- return this.currentUserID ? this.getUser(this.currentUserID) : undefined
+ 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))
}
}