feat: frontend send
This commit is contained in:
@@ -41,6 +41,7 @@ export class ScreenLogin {
|
||||
this.router.navigateByUrl(returnUrl);
|
||||
},
|
||||
error: (err) => {
|
||||
//FIXME error message displaying delayed, display message from server response
|
||||
this.error = err.error?.message || 'Login failed. Please try again.';
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<!-- Note Field -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Note (Optional)</label>
|
||||
<textarea class="form-control" rows="2" [(ngModel)]="note"></textarea>
|
||||
<textarea class="form-control" rows="2" [(ngModel)]="reference"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { APIService } from '../../services/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-screen-send',
|
||||
@@ -10,16 +11,27 @@ import { FormsModule } from '@angular/forms';
|
||||
export class ScreenSend {
|
||||
amount: number = 0;
|
||||
recipient: string = '';
|
||||
note: string = '';
|
||||
reference: string = '';
|
||||
|
||||
constructor(
|
||||
private api: APIService,
|
||||
){}
|
||||
|
||||
sendMoney() {
|
||||
console.log('Sending:', this.amount, 'to', this.recipient);
|
||||
// Add your logic here (e.g., API call)
|
||||
this.api.send(this.amount, this.recipient, this.reference).subscribe({
|
||||
next:()=> {
|
||||
this.cancel()
|
||||
//TODO show success message
|
||||
},
|
||||
error:()=> {
|
||||
//TODO show error message
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.amount = 0;
|
||||
this.recipient = '';
|
||||
this.note = '';
|
||||
this.reference = '';
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, catchError, map, Observable, of, tap } from 'rxjs';
|
||||
import Transaction from '@model/transaction'
|
||||
import { SendRequest, SendResponse } from '@message/Send';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -13,9 +14,6 @@ export class APIService {
|
||||
|
||||
constructor(private http: HttpClient){}
|
||||
|
||||
getTransactions(): Observable<Transaction[]>{
|
||||
return this.http.get<Transaction[]>(`${this.apiUrl}/transactions`);
|
||||
}
|
||||
login(username: string, password: string): Observable<any>{
|
||||
return this.http.post(`${this.apiUrl}/auth/login`,{ 'username': username, 'password': password});
|
||||
}
|
||||
@@ -23,7 +21,7 @@ export class APIService {
|
||||
return this.http.post(`${this.apiUrl}/auth/logout`, {});
|
||||
}
|
||||
checkAuthStatus(): Observable<boolean> {
|
||||
return this.http.get(`${this.apiUrl}/auth/status`, { withCredentials: true}).pipe(
|
||||
return this.http.get(`${this.apiUrl}/auth/status`).pipe(
|
||||
map(() => true),
|
||||
catchError(() => of(false)),
|
||||
tap({
|
||||
@@ -32,4 +30,11 @@ export class APIService {
|
||||
})
|
||||
);
|
||||
}
|
||||
getTransactions(): Observable<Transaction[]>{
|
||||
return this.http.get<Transaction[]>(`${this.apiUrl}/transactions`);
|
||||
}
|
||||
send(amount: number, recipientID: string, reference: string = ""): Observable<SendResponse>{
|
||||
let request: SendRequest = {amount, recipientID, reference};
|
||||
return this.http.post<SendResponse>(`${this.apiUrl}/send`, request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export const authGuard: CanActivateFn = (route, state) => {
|
||||
const api = inject(APIService);
|
||||
const router = inject(Router);
|
||||
|
||||
//TODO check for cookie
|
||||
//FIXME always redirected to login after page load
|
||||
return api.isAuthenticated$.pipe(
|
||||
map((isAuthenticated) => {
|
||||
if (isAuthenticated) {
|
||||
|
||||
9
server/src/messages/Login.ts
Normal file
9
server/src/messages/Login.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class LoginRequest{
|
||||
constructor(
|
||||
username: string,
|
||||
password: string
|
||||
){}
|
||||
}
|
||||
export class LoginResponse{
|
||||
constructor(){}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ import express from 'express';
|
||||
import { logger } from '../util/logging';
|
||||
import User from '../model/user';
|
||||
import { getJWT, requireAuth } from '../util/auth';
|
||||
import { LoginRequest } from '@message/Login';
|
||||
import { SendRequest, SendResponse } from '@message/Send';
|
||||
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -26,7 +29,7 @@ router.post('/login', async (req, res) => {
|
||||
res.json({ message: 'Logged in successfully' });
|
||||
}catch (err) {
|
||||
logger.error('Failed to authenticate:', err);
|
||||
res.status(500).json({ error: 'Failed to authenticate' });
|
||||
res.status(500).json({ message: 'Failed to authenticate' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ const router = express.Router();
|
||||
|
||||
router.get('/', requireAuth, async (req, res) => {
|
||||
try {
|
||||
const transactions = await Transaction.findAll({ limit: 10 });
|
||||
const transactions = await Transaction.findAll({
|
||||
limit: 100,
|
||||
order: [['date', 'DESC']]
|
||||
});
|
||||
res.json(transactions);
|
||||
} catch (err) {
|
||||
logger.error('Failed to fetch transactions:', err);
|
||||
|
||||
Reference in New Issue
Block a user