diff --git a/src/pages/dashboard/DashboardPage.tsx b/src/pages/dashboard/DashboardPage.tsx index da27361..03e5549 100644 --- a/src/pages/dashboard/DashboardPage.tsx +++ b/src/pages/dashboard/DashboardPage.tsx @@ -2,65 +2,178 @@ import "./styles.css"; import "react-tiles-dnd/esm/index.css"; import { TilesContainer, RenderTileFunction } from "react-tiles-dnd"; import useWindowDimensions from "../../hooks/WindowDimensionsHook.tsx"; -import {Link} from "react-router-dom"; import {Header} from "../../components/Header.tsx"; -import {Sidebar} from "../../components/Sidebar.tsx"; -import { Button } from "react-bootstrap"; -import { CSVUpload } from "../../components/transactions/CSVUpload.tsx"; -import { InputTransaction } from "../../components/transactions/InputTransaction.tsx"; -import { useState } from "react"; +import React, {ReactNode, useEffect, useState} from "react"; +import { getTransactionsFilterOrderBy, Transaction } from "../../utils/transaction.ts" +import {auth} from "../../utils/firebase.ts"; +import {orderBy} from "firebase/firestore"; +import {getCurrentBalance} from "../../utils/transaction_utils.ts"; +import { User } from "firebase/auth"; +import {FullscreenCenter} from "../../components/FullscreenCenter.tsx"; +import {Button} from "react-bootstrap"; +import {CSVUpload} from "../../components/transactions/CSVUpload.tsx"; +import {InputTransaction} from "../../components/transactions/InputTransaction.tsx"; +import Graphs from "./Graphs.tsx" +import test from "./test.tsx" -// ? Lot of code obtained from here for testing: https://codesandbox.io/p/sandbox/react-tiles-dnd-responsive-bd0ly?file=%2Fsrc%2Findex.tsx +type transactionPoint = { date: string; amount: number } +type tsxContents = ReactNode; -interface Props { - tiles: Array<{ text: string; rows: number; cols: number }> +class TileElement { + private graph?: transactionPoint[]; + private TSX?: () => tsxContents; + + constructor(graph: transactionPoint[] | undefined, TSX: (() => tsxContents) | undefined) { + this.graph = graph; + this.TSX = TSX; + } + + static newGraph(graph: transactionPoint[]): TileElement { + return new TileElement(graph, undefined); + } + static newTSX(TSX: () => tsxContents): TileElement { + return new TileElement(undefined, TSX); + } + + isGraph(): boolean { + return typeof this.graph !== "undefined"; + } + + forceGetGraph(): transactionPoint[] { + return this.graph!; + } + forceGetTSX(): () => tsxContents { + return this.TSX!; + } } -const render: RenderTileFunction<{ text: string; rows: number; cols: number }> = ({ data, isDragging }) => ( -
-
- {data.text} {isDragging ? "DRAGGING" : null} -
-
-); -const tileSize = (tile: { text: string; rows: number; cols: number }) => ({ - colSpan: tile.cols, - rowSpan: tile.rows -}); - -export default function Dashboard(props: Props) { - const {width} = useWindowDimensions(); - const columns = Math.max(Math.floor(width / 200), 1); - +export default function Dashboard() { + const [balance, setBalance] = useState(0); + const [transactionPoints, setPoints] = useState([[]]); + const [authResolved, setAuthResolved] = useState(false); + const [fetchResolved, setFetchResolved] = useState(false); const [showCSVModal, setShowCSVModal] = useState(false); const [showTransactionModal, setShowTransactionModal] = useState(false); - return <> -
-
+ const tileSize = (tile: typeof transactionTiles[0]) => ({ + colSpan: tile.cols, + rowSpan: tile.rows + }); + 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 + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Month is 0-indexed, add 1 + const year = date.getFullYear(); + return `${day}/${month}/${year}`; + } + const splitTransactions = (data: transactionPoint[]): void => { + const moneyIn: transactionPoint[] = [] + const moneyOut: transactionPoint[] = [] + data.forEach(t => { + if (t.amount > 0) { + moneyIn.push(t) + } else { + moneyOut.push(t) + } + }) + setPoints([cumulateTransactions(data), cumulateTransactions(moneyIn), cumulateTransactions(moneyOut)]) + console.log(transactionPoints) + } + const readTransactions = (data: Transaction[]): void => { + const result: transactionPoint[] = [] + data.forEach(t => { + result.push({amount: t.amount, date: getDateString(t.dateTime)}) + }) + splitTransactions(result) + } + const fetchTransactions = async (user: User) => { + try { + const transactions = await getTransactionsFilterOrderBy(user, orderBy("dateTime", "desc")) + readTransactions(transactions) + setFetchResolved(true); + } catch (error) {} + } + + const {width} = useWindowDimensions(); + const columns = Math.max(Math.floor(width / 200), 1); + + // Transaction Loading and Handling + useEffect(() => { + if (auth.currentUser !== null) { + getCurrentBalance(auth.currentUser).then((b) => setBalance(b)); + fetchTransactions(auth.currentUser).then(() => console.log("Fetched Transactions", transactionPoints)); + } + },[auth.currentUser]) - {/* TODO: MOVE TO CORRECT POSITION ON DASHBOARD */} -
+ + if (!authResolved) { + auth.authStateReady().then(() => setAuthResolved(true)); + return <> + +
+

Waiting for Auth

+
+
+ ; + } + if (!fetchResolved) { + auth.authStateReady().then(() => setAuthResolved(true)); + return <> + +
+

Fetching

+
+
+ ; + } + + const transactionTiles = [ + {d: TileElement.newGraph(transactionPoints[0]), cols:5, rows:2}, + {d: TileElement.newGraph(transactionPoints[1]), cols:5, rows:2}, + {d: TileElement.newGraph(transactionPoints[2]), cols:5, rows:2}, + {d: TileElement.newTSX(test), cols:1, rows:1} + ]; + + const renderFirebase: RenderTileFunction = ({ data, isDragging }) => ( +
+
+ {data.d.isGraph() ? : data.d.forceGetTSX()()} +
+
+ ); + + return ( +
+
+
- + - +
- -
-

Testing Tiles

-

Go back

- -
-
-
- +
+ + {balance} + +
+
+ ); } \ No newline at end of file