Skip to content

Commit

Permalink
Added connection to firebase but
Browse files Browse the repository at this point in the history
  • Loading branch information
joesumargo committed Apr 26, 2024
1 parent 25b137f commit 3b90f61
Showing 1 changed file with 161 additions and 48 deletions.
209 changes: 161 additions & 48 deletions src/pages/dashboard/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => (
<div style={{ padding: ".75rem", width: "100%" }}>
<div className={`tile card ${isDragging ? "dragging" : ""}`}
style={{ width: "100%", height: "100%" }} >
{data.text} {isDragging ? "DRAGGING" : null}
</div>
</div>
);
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<transactionPoint[][]>([[]]);
const [authResolved, setAuthResolved] = useState(false);
const [fetchResolved, setFetchResolved] = useState(false);
const [showCSVModal, setShowCSVModal] = useState(false);
const [showTransactionModal, setShowTransactionModal] = useState(false);

return <>
<div className="vh-100 d-flex flex-column">
<Header/>
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 */}
<div>

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

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<typeof transactionTiles[0]> = ({ data, isDragging }) => (
<div style={{padding: ".75rem", width: "100%"}}>
<div className={`tile card ${isDragging ? "dragging" : ""}`}
style={{width: "100%", height: "100%"}}>
{data.d.isGraph() ? <Graphs data={data.d.forceGetGraph()}/> : data.d.forceGetTSX()()}
</div>
</div>
);

return (
<div className="vh-100 d-flex flex-column">
<Header/>
<div>
<Button variant="primary" onClick={() => setShowCSVModal(true)}>Upload CSV</Button>
<CSVUpload show={showCSVModal} setShow={setShowCSVModal} />
<CSVUpload show={showCSVModal} setShow={setShowCSVModal}/>

<Button variant="primary" onClick={() => setShowTransactionModal(true)}>Add Transaction</Button>
<InputTransaction show={showTransactionModal} setShow={setShowTransactionModal} />
<InputTransaction show={showTransactionModal} setShow={setShowTransactionModal}/>
</div>
<Sidebar>
<div className="App ps-5 pe-5 mt-3">
<h1>Testing Tiles</h1>
<p><Link to={"/"}>Go back</Link></p>
<TilesContainer
data={props.tiles}
renderTile={render}
tileSize={tileSize}
ratio={1}
columns={columns}
/>
</div>
</Sidebar>
</div>
</>
<div className="App ps-5 pe-5 mt-3">
<button onClick={() => {
console.log(transactionPoints)
}}>Console Log Transactions
</button>
{balance}
<TilesContainer
data={transactionTiles}
renderTile={renderFirebase}
tileSize={tileSize}
ratio={1}
columns={columns}
></TilesContainer>
</div>
</div>
);
}

0 comments on commit 3b90f61

Please sign in to comment.