Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0624352
Upgraded the UI for transactions table - combined the features from u…
TebelR Mar 31, 2026
35aa33c
minor fix to account selection logic for creating transactions
TebelR Mar 31, 2026
882c723
Transactions table FOC
TebelR Apr 1, 2026
2d7a47c
Reformatted accounts
TebelR Apr 1, 2026
9ccda9c
Reformatted the projection page - there's a massive issue with saving…
TebelR Apr 1, 2026
761810e
addint unit tests for user input (WIP)
Apr 1, 2026
11902ae
User input bug fixes for tests
Apr 1, 2026
4d6bc2d
FIxed massive savings projections and readded tests for new logic
TebelR Apr 1, 2026
0436837
Merge branch 'data-input-polish' of https://github.com/MeasureOneCode…
TebelR Apr 1, 2026
371b23c
Added import CSV button and removed old files
TebelR Apr 1, 2026
5b0d5c9
Rewrote unit tests to support new logic
TebelR Apr 1, 2026
447a5c4
Fixes the balance input fields
Apr 1, 2026
efb72cc
Turned the sub type input while editing to a selector
Apr 1, 2026
24cc8a5
Updated coding style and cleaned up some directories
TebelR Apr 2, 2026
e906a3b
Merge branch 'data-input-polish' of https://github.com/MeasureOneCode…
TebelR Apr 2, 2026
0c96dc3
Merge branch 'development' into data-input-polish
TebelR Apr 2, 2026
a8907fe
Bug fixes and cleanup for PR
TebelR Apr 2, 2026
2d506be
Bug fixes with savings endpoint
TebelR Apr 2, 2026
67b2142
accounts integration fix
TebelR Apr 2, 2026
66f2cd9
Added a missing function mock in unit tests for transaction logic
TebelR Apr 2, 2026
b77b637
Merge branch 'development' into data-input-polish
TebelR Apr 2, 2026
fdbf8eb
Added load testing to handle 20 users and 200 requests per minute
deep-n-patel Apr 2, 2026
c5e2146
Load tests fixed and should pass on the CI pipeline
deep-n-patel Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/client/Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM oven/bun:1.3.9-slim

WORKDIR /app

COPY package.json bun.lockb .
COPY package.json bun.lockb ./
RUN --mount=type=cache,target=/root/.bun/install/cache \
bun install

Expand Down
3 changes: 1 addition & 2 deletions app/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ function App() {
}
/>


{session && (
<Route element={<AppLayout onLogout={handleLogout} />}>
<Route
Expand All @@ -221,7 +220,7 @@ function App() {
/>
</Route>
)}

<Route path="*" element={<Navigate to="/" replace />} />

{/**Code below is only used for dashboard development purposes */}
Expand Down
130 changes: 42 additions & 88 deletions app/client/src/api/Account.ts
Original file line number Diff line number Diff line change
@@ -1,129 +1,83 @@
import type { updateResponse } from "../types/responseTypes";
import type { Account } from "../types/AccountType";
import type { AuthSession } from "@/types/authTypes";
import { BASE_URL } from "@/utils/constants";

const requestUrl = `${BASE_URL}/api/accounts`;
import { instance } from "./config";
// import { data } from "react-router-dom";

//Sends a request to get different accounts the user has
export async function getUserAccounts(
session: AuthSession,
type?: string,
): Promise<Account[]> {
let url = requestUrl;

//Determine if we're targetting a specific type
if (type) {
url = `${requestUrl}/?type=${type}`;
}

export async function getUserAccounts(type?: string): Promise<Account[]> {
try {
//Sends a http request and waits for a response
const response = await fetch(url, {
method: "GET",
headers: { Authorization: `Bearer ${session.token}` },
});
const response = await instance.get(
`/api/accounts${type ? `?type=${type}` : ""}`,
);

//Determine if we were able to retrieve user's data
if (!response.ok) {
//Failed to retrieve user data, return empty array
console.error(
"Error: Failed to retrieve users accounts ",
response.status,
);
return [];
//determine if we were able to retrieve user's data
if (response.status === 200 || response.status === 201) {
// console.log("Account created:", response.data);
return response.data;
} else {
console.error("Failed to create account", response.status);
throw new Error(`Failed to create account: ${response.statusText}`);
}

return response.json();
} catch (error) {
console.error(error);
console.error("Error creating account:", error);
throw error;
}
}

//Sends a post request to create a user account
export async function postUserAccount(
session: AuthSession,
newAccount: Account,
): Promise<updateResponse> {
try {
//Create post request and wait for response
const response = await fetch(requestUrl, {
method: "POST",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${session.token}`,
},
body: JSON.stringify(newAccount),
});

//Determine if our post was a success
if (response.ok) {
alert("Account " + newAccount.name + " has been created");
const response = await instance.post(`/api/accounts`, newAccount);
if (response.status === 200 || response.status === 201) {
console.log("Account created:", response.data);
return newAccount;
} else {
alert("Failed to create account " + newAccount.name);
console.error(response.status);
console.error("Failed to create account", response.status);
throw new Error(`Failed to create account: ${response.statusText}`);
}

return response.json();
} catch (error) {
console.error(error);
console.error("Error creating account:", error);
throw error;
}
}

//Updates the users account
export async function putUserAccount(
session: AuthSession,
newAccount: Account,
): Promise<updateResponse> {
try {
//Create post request and wait for response
const response = await fetch(requestUrl, {
method: "PUT",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${session.token}`,
},
body: JSON.stringify(newAccount),
});
const response = await instance.put(`/api/accounts`, newAccount);

//Determine if our post was a success
if (response.ok) {
alert("Account " + newAccount.name + " has been updated");
if (response.status === 200) {
console.log("Account updated:", response.data);
return response.data;
} else {
alert("Failed to update account " + newAccount.name);
console.error(response.status);
console.error("Failed to update account", response.status);
throw new Error(`Failed to update account: ${response.statusText}`);
}

return response.json();
} catch (error) {
console.error(error);
console.error("Error updating account:", error);
throw error;
}
}

export async function deleteUserAccount(
session: AuthSession,
userAccount: Account,
) {
const content = JSON.stringify({ id: userAccount.id });
//Create delete request to delete the account
const response = await fetch(requestUrl, {
method: "DELETE",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${session.token}`,
},
body: content,
});
export async function deleteUserAccount(accountId: number): Promise<boolean> {
try {
const id = Number(accountId);
const response = await instance.delete(`/api/accounts?id=${id}`);

if (response.ok) {
alert("Account " + userAccount.name + " has been deleted");
} else {
alert("Failed to delete account " + userAccount.name);
console.error(response.status);
if (response.status === 200) {
console.log("Account deleted successfully");
return true;
} else {
console.error("Failed to delete account", response.status);
return false;
}
} catch (error) {
console.error("Error deleting account:", error);
return false;
}

return response.ok;
}
Loading