Skip to content

Commit

Permalink
Merge pull request #37 from Robert-M-Lucas/dev-SCRUM-45
Browse files Browse the repository at this point in the history
Dev scrum 45
  • Loading branch information
Robert-M-Lucas authored Apr 27, 2024
2 parents 0460adc + 64750a4 commit 6f57bbc
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 117 deletions.
17 changes: 16 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@types/papaparse": "^5.3.14",
"@types/strftime": "^0.9.8",
"bootstrap": "^5.3.3",
"firebase": "^10.11.0",
"lodash": "^4.17.21",
Expand All @@ -23,7 +24,8 @@
"react-router-dom": "^6.23.0",
"react-tiles-dnd": "^0.1.2",
"recharts": "^2.12.5",
"sass": "^1.72.0"
"sass": "^1.72.0",
"strftime": "^0.10.2"
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
Expand Down
2 changes: 1 addition & 1 deletion src/pages/dashboard/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "react-tiles-dnd/esm/index.css";
import { TilesContainer, RenderTileFunction } from "react-tiles-dnd";
import useWindowDimensions from "../../hooks/WindowDimensionsHook.tsx";
import {Header} from "../../components/Header.tsx";
import React, {ReactNode, useEffect, useState} from "react";
import {ReactNode, useEffect, useState} from "react";
import { getTransactionsFilterOrderBy, Transaction } from "../../utils/transaction.ts"
import {auth} from "../../utils/firebase.ts";
import {orderBy} from "firebase/firestore";
Expand Down
15 changes: 8 additions & 7 deletions src/pages/dashboard/GraphUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import {Transaction} from "../../utils/transaction.ts";

type transactionPoint = { date: string; amount: number }

const cumulateTransactions = (points: transactionPoint[]): transactionPoint[] => {
let total = 0;
return points.map(value => {
total += value.amount;
return {date: value.date, amount: total};
})
}
// const cumulateTransactions = (points: transactionPoint[]): transactionPoint[] => {
// let total = 0;
// return points.map(value => {
// total += value.amount;
// return {date: value.date, amount: total};
// })
// }

const getDateString = (timestamp: number): string => {
const date = new Date(timestamp)
const day = date.getDate().toString().padStart(2, '0'); // Ensures two digits
Expand Down
177 changes: 177 additions & 0 deletions src/pages/transactions/TransactionPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import {useState} from "react";
import {auth} from "../../utils/firebase.ts";
import {getTransactionsFilterOrderBy, Transaction} from "../../utils/transaction.ts";
import {FullscreenCenter} from "../../components/FullscreenCenter.tsx";
import {User} from "firebase/auth";
import {Header} from "../../components/Header.tsx";
import {signInWithGoogle} from "../../utils/authentication.ts";
import {limit, orderBy, startAfter} from "firebase/firestore";
import strftime from "strftime";

// CSS
import "./transactionsTable.scss";

export function TransactionPage() {
const [transactions, setTransactions] = useState<Transaction[] | null>(null);
const [currentPage, setCurrentPage] = useState(0);
const [authResolved, setAuthResolved] = useState(false);
const [update, setUpdate] = useState(0);
const [pageStarts, setPageStarts] = useState([Infinity]);
const itemsPerPage = 14;


if (!authResolved) {
auth.authStateReady().then(() => setAuthResolved(true));
return <>
<FullscreenCenter>
<div className="text-center">
<h1>Waiting for Auth</h1>
</div>
</FullscreenCenter>
</>;
}

if (auth.currentUser === null) {
auth.onAuthStateChanged((new_user: User | null) => {
if (new_user !== null) {
setUpdate(update + 1);
}
});
return <>
<Header/>
<FullscreenCenter>
<div className="text-center">
<h1>Not Logged In</h1>
<button type="button" className="login-with-google-btn" onClick={signInWithGoogle}>
Sign in with Google
</button>
</div>
</FullscreenCenter>
</>;
}

if (!transactions) {
getTransactionsFilterOrderBy(auth.currentUser, orderBy("dateTime", "desc"), limit(itemsPerPage), startAfter(pageStarts[pageStarts.length - 1]))
.then((pageTransactions) => {
setTransactions(pageTransactions);
});

return <>
<Header/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Emoji</th>
<th>Date</th>
<th>Amount</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fetching...</td>
<td>Fetching...</td>
<td>Fetching...</td>
<td>Fetching...</td>
<td>Fetching...</td>
<td>Fetching...</td>
</tr>
</tbody>
</table>
</>;
}


// adjusted dylan.s code to use getTransactionPage instead of getTransactions
// useEffect(() => {
// getTransactionsPage(auth.currentUser, itemsPerPage, currentPage)
// .then((pageTransactions) => {
// console.log("Fetched transactions:");
// console.log(pageTransactions);
// setTransactions(pageTransactions);
// });
// }, [currentPage]);

return <>
<Header/>
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Emoji</th>
<th>Date</th>
<th>Amount</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{transactions.map((transaction) => (
<TransactionItem key={transaction.forceGetDocName()} data={transaction}/>
// maps every transaction as a row in the table
))}
</tbody>
</table>
{ transactions.length == 0 &&
<h1 className="vw-100 text-center text-muted">[No More Data]</h1>
}
<div className="pagination p-2">
{/* conditional previous page button, only displayed if page number > 1 */}
{currentPage > 0 && (
<button onClick={() => {
setCurrentPage(currentPage - 1);
pageStarts.pop()
setPageStarts(pageStarts);
setTransactions(null);
}}>
<span>&lt;</span> Previous
</button>
)}
{/* spacers to push buttons to the edges */}
<div className="spacer"></div>
<span className="page-counter">Page {currentPage + 1}</span>
<div className="spacer"></div>
{transactions.length === itemsPerPage &&
<button onClick={() => {
setCurrentPage(currentPage + 1);
pageStarts.push(transactions[transactions.length - 1].dateTime);
setPageStarts(pageStarts);
setTransactions(null);
}}>
Next <span>&gt;</span>
</button>
}
</div>

</div>
</>;
}

function TransactionItem({data}: { data: Transaction }) {
return (
<tr>
<td>{data.name}</td>
<td>{data.category}</td>
<td>{data.emoji}</td>
<td>{strftime("%d/%m/%y - %H:%M", new Date(data.dateTime))}</td>
{data.amount > 0 ?
<td>
<div className="d-flex justify-content-between align-items-center" style={{color: "green"}}>
<span>£</span>
<span>{data.amount.toFixed(2)}</span>
</div>
</td> :
<td>
<div className="d-flex justify-content-between align-items-center" style={{color: "red"}}>
<span>£</span>
<span>{data.amount.toFixed(2)}</span>
</div>
</td>
}
<td className="text-wrap">{data.description}</td>
</tr>
);
}
69 changes: 69 additions & 0 deletions src/pages/transactions/transactionsTable.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/pages/transactions/transactionsTable.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6f57bbc

Please sign in to comment.