fix: delayed displaying of messages, transactions using signals
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, signal } from '@angular/core';
|
import { Component, inject, OnInit, signal } from '@angular/core';
|
||||||
import { RouterOutlet, RouterLinkWithHref, Router, NavigationEnd } from '@angular/router';
|
import { RouterOutlet, RouterLinkWithHref, Router, NavigationEnd } from '@angular/router';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import {
|
import {
|
||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
NgbNavLinkBase,
|
NgbNavLinkBase,
|
||||||
} from '@ng-bootstrap/ng-bootstrap/nav';
|
} from '@ng-bootstrap/ng-bootstrap/nav';
|
||||||
import { filter } from 'rxjs';
|
import { filter } from 'rxjs';
|
||||||
|
import { APIService } from './services/api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@@ -17,6 +18,7 @@ import { filter } from 'rxjs';
|
|||||||
})
|
})
|
||||||
export class App implements OnInit{
|
export class App implements OnInit{
|
||||||
protected readonly title = signal('client');
|
protected readonly title = signal('client');
|
||||||
|
protected api = inject(APIService);
|
||||||
active = '/';
|
active = '/';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -24,6 +26,7 @@ export class App implements OnInit{
|
|||||||
){}
|
){}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.api.checkAuthStatus().subscribe();
|
||||||
this.router.events
|
this.router.events
|
||||||
.pipe(filter(event => event instanceof NavigationEnd))
|
.pipe(filter(event => event instanceof NavigationEnd))
|
||||||
.subscribe(() =>{
|
.subscribe(() =>{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-primary w-100 mb-3"
|
class="btn btn-primary w-100 mb-3"
|
||||||
>
|
>
|
||||||
@if (loading) {
|
@if (loading()) {
|
||||||
<span> Signing In... </span>
|
<span> Signing In... </span>
|
||||||
}@else {
|
}@else {
|
||||||
<span>Sign In</span>
|
<span>Sign In</span>
|
||||||
@@ -57,13 +57,13 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- Error Alert -->
|
<!-- Error Alert -->
|
||||||
@if (error) {
|
@if (error()) {
|
||||||
<ngb-alert
|
<ngb-alert
|
||||||
type="danger"
|
type="danger"
|
||||||
(closed)="error = null"
|
(closed)="error.set(null)"
|
||||||
[dismissible]="true"
|
[dismissible]="true"
|
||||||
>
|
>
|
||||||
{{ error }}
|
{{ error() }}
|
||||||
</ngb-alert>
|
</ngb-alert>
|
||||||
}
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component } from '@angular/core';
|
import { Component, signal } from '@angular/core';
|
||||||
import { Validators, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Form } from '@angular/forms';
|
import { Validators, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Form } from '@angular/forms';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
@@ -15,9 +15,9 @@ import { GenericMessage } from '@message/Message';
|
|||||||
export class ScreenLogin {
|
export class ScreenLogin {
|
||||||
loginForm: FormGroup;
|
loginForm: FormGroup;
|
||||||
submitted = false;
|
submitted = false;
|
||||||
loading = false;
|
loading = signal(false);
|
||||||
showPassword = false;
|
showPassword = false;
|
||||||
error: string | null = null;
|
error = signal<string|null>(null);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private api: APIService,
|
private api: APIService,
|
||||||
@@ -33,8 +33,8 @@ export class ScreenLogin {
|
|||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.submitted = true;
|
this.submitted = true;
|
||||||
this.error = null;
|
this.error.set(null);
|
||||||
this.loading = true;
|
this.loading.set(true)
|
||||||
|
|
||||||
this.api.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({
|
this.api.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
@@ -42,10 +42,9 @@ export class ScreenLogin {
|
|||||||
this.router.navigateByUrl(returnUrl);
|
this.router.navigateByUrl(returnUrl);
|
||||||
},
|
},
|
||||||
error: (resp) => {
|
error: (resp) => {
|
||||||
//FIXME error message displaying delayed, display message from server response
|
|
||||||
let msg: GenericMessage = resp.error;
|
let msg: GenericMessage = resp.error;
|
||||||
this.error = msg.message || 'Login failed. Please try again.';
|
this.error.set(msg.message || 'Login failed. Please try again.');
|
||||||
this.loading = false;
|
this.loading.set(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<!-- Transaction Item -->
|
<!-- Transaction Item -->
|
||||||
@for (transaction of transactions; track $index) {
|
@for (transaction of transactions(); track $index) {
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@empty {<p class="text-muted">No transactions yet</p>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CommonModule, CurrencyPipe, DatePipe } from '@angular/common';
|
import { CommonModule, CurrencyPipe, DatePipe } from '@angular/common';
|
||||||
import { Component, inject, OnInit } from '@angular/core';
|
import { Component, inject, OnInit, signal } from '@angular/core';
|
||||||
import { APIService } from '../../services/api';
|
import { APIService } from '../../services/api';
|
||||||
import Transaction from '@model/transaction';
|
import Transaction from '@model/transaction';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
@@ -14,7 +14,7 @@ export class ScreenProfile implements OnInit{
|
|||||||
// TODO display real data
|
// TODO display real data
|
||||||
username = 'John Doe';
|
username = 'John Doe';
|
||||||
balance = 200;
|
balance = 200;
|
||||||
transactions!: Transaction[];
|
transactions = signal<Transaction[]>([])
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected api: APIService,
|
protected api: APIService,
|
||||||
@@ -22,10 +22,9 @@ export class ScreenProfile implements OnInit{
|
|||||||
){}
|
){}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
// FIXME transactions displaying delayed (only on second nav click)
|
|
||||||
this.api.getTransactions().subscribe({
|
this.api.getTransactions().subscribe({
|
||||||
next: (transactions) => {
|
next: (transactions) => {
|
||||||
this.transactions = transactions;
|
this.transactions.set(transactions);
|
||||||
},
|
},
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
console.error('Error fetching transactions:', err);
|
console.error('Error fetching transactions:', err);
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { CanActivateFn, Router } from '@angular/router';
|
import { CanActivateFn, Router } from '@angular/router';
|
||||||
import { APIService } from './api';
|
import { APIService } from './api';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
export const authGuard: CanActivateFn = (route, state) => {
|
export const authGuard: CanActivateFn = (route, state) => {
|
||||||
const api = inject(APIService);
|
const api = inject(APIService);
|
||||||
const router = inject(Router);
|
const router = inject(Router);
|
||||||
|
|
||||||
return api.checkAuthStatus().pipe(
|
return api.isAuthenticated$.pipe(
|
||||||
|
take(1),
|
||||||
map((isAuthenticated) => {
|
map((isAuthenticated) => {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user