diff --git a/package-lock.json b/package-lock.json
index 90d2aac..3be9923 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"axios": "^1.3.5",
"bootstrap": "^5.2.3",
"chart.js": "^4.2.1",
+ "ng2-charts": "^4.1.1",
"react": "^18.0.0",
"react-bootstrap": "^2.7.4",
"react-bootstrap-validation": "^0.1.11",
@@ -4436,41 +4437,6 @@
"tslib": "^2.4.0"
}
},
- "node_modules/@testing-library/dom": {
- "version": "9.2.0",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz",
- "integrity": "sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA==",
- "peer": true,
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "^5.0.0",
- "chalk": "^4.1.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@testing-library/dom/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "peer": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
"node_modules/@testing-library/jest-dom": {
"version": "5.16.5",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz",
@@ -12915,6 +12881,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -13260,6 +13231,22 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
+ "node_modules/ng2-charts": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-4.1.1.tgz",
+ "integrity": "sha512-iHwXDbmX86lfeH8VRcsaW2tJATsuAZo4kvvC/Yk2l35zOHjevja1qBvO6BAibiDazi9r9aS6ZRJOqWPsz1pP2w==",
+ "dependencies": {
+ "lodash-es": "^4.17.15",
+ "tslib": "^2.3.0"
+ },
+ "peerDependencies": {
+ "@angular/cdk": ">=14.0.0",
+ "@angular/common": ">=14.0.0",
+ "@angular/core": ">=14.0.0",
+ "chart.js": "^3.4.0 || ^4.0.0",
+ "rxjs": "^6.5.3 || ^7.4.0"
+ }
+ },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
@@ -17328,19 +17315,6 @@
"is-typedarray": "^1.0.0"
}
},
- "node_modules/typescript": {
- "version": "4.9.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
- "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
- "peer": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
diff --git a/package.json b/package.json
index 195b87b..ca93a5f 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"axios": "^1.3.5",
"bootstrap": "^5.2.3",
"chart.js": "^4.2.1",
+ "ng2-charts": "^4.1.1",
"react": "^18.0.0",
"react-bootstrap": "^2.7.4",
"react-bootstrap-validation": "^0.1.11",
diff --git a/src/components/CategorizedExpenses.js b/src/components/CategorizedExpenses.js
index f45bc98..53ff2c1 100644
--- a/src/components/CategorizedExpenses.js
+++ b/src/components/CategorizedExpenses.js
@@ -1,6 +1,7 @@
import { Doughnut } from "react-chartjs-2";
import { Chart as ChartJS, ArcElement, Tooltip, Legend, defaults } from 'chart.js';
+
import { AppProvider } from "../context/AppContext";
import { useState, useEffect } from 'react'
import { calculateValue, getSessionKey } from '../utils/utils.js'
diff --git a/src/components/ExpenseList.js b/src/components/ExpenseList.js
index 520667b..468de76 100644
--- a/src/components/ExpenseList.js
+++ b/src/components/ExpenseList.js
@@ -2,21 +2,103 @@ import React, { useContext, useState, useEffect } from 'react';
import ExpenseItem from './ExpenseItem';
import { AppContext } from '../context/AppContext';
+
+
const ExpenseList = () => {
- const { expenses } = useContext(AppContext);
+ const [whole, setWhole] = useState('');
+ const [decimal, setDecimal] = useState('');
+ const [transaction, setTransactions] = useState('');
+ const [category, setCategories] = useState('');
+
+ function getSessionKey() {
+ var cookies = document.cookie.split(';');
+ for (let i = 0; i < cookies.length; i++) {
+ const cookie = cookies[i].trim(); // Remove any leading or trailing whitespace
+ if (cookie.startsWith('session=')) {
+ return cookie.substring('session='.length, cookie.length); // Extract the value of the cookie
+ }
+ }
+ return null;
+ }
+
+
+
+ async function getTransactionsBalance() {
+ try {
+ const response = await fetch('https://api.bb.gabefarrell.com/w/transactions/recent', {
+ method: 'GET',
+ headers: {
+ 'x-session-key': getSessionKey(),
+ },
+ });
+ const data = await response.json();
+ let whole = data.transactions.map((item)=>item.amount.whole);
+ let decimal = data.transactions.map((item)=>item.amount.decimal);
+ let balance = [];
+ for (let i = 0; i < whole.length; i++) {
+ let expense_balance = whole[i] + '.' + decimal[i];
+ balance.push(expense_balance);
+ }
+
+ //console.log(whole + decimal + "<- total recent transacations");
+ //console.log(whole, decimal, balance);
+ //const transactions_balance = whole + '.' + decimal;
+ //console.log(whole, decimal, category);
+ return balance;
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ async function getTransactionsCategory() {
+ try {
+ const response = await fetch('https://api.bb.gabefarrell.com/w/transactions/recent', {
+ method: 'GET',
+ headers: {
+ 'x-session-key': getSessionKey(),
+ },
+ });
+ const data = await response.json();
+ const category = data.transactions.map((item)=>item.category);
+
+ //console.log(category);
+ return category;
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ async function buildTable(data1, data2){
+ var table = document.getElementById('myTable')
+
+ for (var i = 0; i < data1.length; i++){
+ var row = `
+ | ${data1[i]} |
+ ${data2[i]} |
+
`
+ table.innerHTML += row
+
+
+ }
+ }
+
+ buildTable(category, transaction);
+
+ async function fetchTransactions() {
+ const categories = await getTransactionsCategory();
+ const transaction_balance = await getTransactionsBalance();
+
+
- const [filteredExpenses, setfilteredExpenses] = useState(expenses || []);
+ setCategories(categories);
+ setTransactions(transaction_balance);
+ }
+
useEffect(() => {
- setfilteredExpenses(expenses);
- }, [expenses]);
+ fetchTransactions(); //b36efa01-7824-4f61-a274-63131b58d8fe
+ }, [])
- const handleChange = (event) => {
- const searchResults = expenses.filter((filteredExpense) =>
- filteredExpense.name.toLowerCase().includes(event.target.value)
- );
- setfilteredExpenses(searchResults);
- };
return (
@@ -26,16 +108,14 @@ const ExpenseList = () => {
placeholder='Type to search...'
onChange={handleChange}
/> */}
-
Expenses
-
- {filteredExpenses.map((expense) => (
-
- ))}
-
+
+
Recent Transactions
+ {/*
{category}
+
{transaction}
*/}
+
+
);
};
diff --git a/src/components/Remaining.js b/src/components/Remaining.js
index 77d5117..370dfcc 100644
--- a/src/components/Remaining.js
+++ b/src/components/Remaining.js
@@ -1,23 +1,124 @@
-import React, { useContext } from 'react';
-import { AppContext } from '../context/AppContext';
-import logo from './widget_logos/budget_logo.png';
-import './css/Remaining.css'
+import React, {useState, useEffect} from 'react';
+import './css/ViewBudget.css'
+import logo from './widget_logos/current_balance_logo.png';
-const RemainingBudget = () => {
- const { expenses, budget } = useContext(AppContext);
+export default function Remaining() {
+ const [budget, setBudget] = useState('');
+ const [whole, setWhole] = useState('');
+ const [decimal, setDecimal] = useState('');
- const totalExpenses = expenses.reduce((total, item) => {
- return (total += item.cost);
- }, 0);
+ function getSessionKey() {
+ var cookies = document.cookie.split(';');
+ for (let i = 0; i < cookies.length; i++) {
+ const cookie = cookies[i].trim(); // Remove any leading or trailing whitespace
+ if (cookie.startsWith('session=')) {
+ return cookie.substring('session='.length, cookie.length); // Extract the value of the cookie
+ }
+ }
+ return null;
+ }
- const alertType = totalExpenses > budget ? 'alert-danger' : 'alert-success';
+ async function getBudget() {
+ try {
+ const response = await fetch('https://api.bb.gabefarrell.com/w/budget', {
+ method: 'GET',
+ headers: {
+ 'x-session-key': getSessionKey(),
+ },
+ });
+ const data = await response.json();
+ const whole = data.budget.whole;
+ const decimal = data.budget.decimal;
+ const budget_balance = whole + '.' + decimal;
+ console.log(budget_balance);
+ return budget_balance;
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ async function getMonthlyExpenses() {
+ try {
+ const response = await fetch('https://api.bb.gabefarrell.com/w/expenses/month', {
+ method: 'GET',
+ headers: {
+ 'x-session-key': getSessionKey(),
+ },
+ });
+ const data = await response.json();
+ const whole = data.whole;
+ const decimal = data.decimal;
+ const total_expenses = whole + '.' + decimal;
+ console.log(total_expenses + "<- Total Expenses");
+ return total_expenses;
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ async function fetchBudget() {
+ const name = await getBudget();
+ const expenses = await getMonthlyExpenses();
+ const budget_remaining = (name - expenses).toFixed(2);
+ setBudget(budget_remaining);
+ }
+ useEffect(() => {
+
+ fetchBudget();
+ }, [])
+
+ function handleSubmit(event) {
+ event.preventDefault();
+ const budget = whole.split('.')
+ if (budget.length < 2)
+ budget.push(0);
+ else if (budget[1].length < 1)
+ budget.push(0);
+
+ var details = {
+ // 'currency' : currency,
+ 'whole' : budget[0],
+ 'decimal' : budget[1]
+ };
+ var formBody = []
+ for (var property in details) {
+ var encodedKey = encodeURIComponent(property);
+ var encodedValue = encodeURIComponent(details[property]);
+ formBody.push(encodedKey + "=" + encodedValue);
+ }
+ formBody = formBody.join("&");
+
+ fetch('https://api.bb.gabefarrell.com/w/budget', {
+ method: 'POST',
+ body: formBody,
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
+ 'x-session-key': getSessionKey()
+ }
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data)
+ if (data.status == 200)
+ fetchBudget();
+ });
+ }
return (
-
-

-
Budget Remaining: ${budget - totalExpenses}
-
+ <>
+ {/*
+ Current Balance: ${data} */}
+ {/* */}
+ {budget}
+
+ >
+
);
-};
-
-export default RemainingBudget;
+};
\ No newline at end of file
diff --git a/src/components/ViewBudget.js b/src/components/ViewBudget.js
index 31fe56b..c53ee6a 100644
--- a/src/components/ViewBudget.js
+++ b/src/components/ViewBudget.js
@@ -1,11 +1,12 @@
-import React, {useState, useEffect} from 'react';
+import React, {useState, useEffect, useRef} from 'react';
import './css/ViewBudget.css'
import logo from './widget_logos/current_balance_logo.png';
export default function FetchAPI() {
const [whole, setWhole] = useState('');
- const [decimal, setDecimal] = useState('')
+ const [decimal, setDecimal] = useState('');
const [balance, setBalance] = useState('');
+ const [error, setError] = useState(false);
function getSessionKey() {
var cookies = document.cookie.split(';');
@@ -41,19 +42,36 @@ export default function FetchAPI() {
setBalance(name);
}
useEffect(() => {
-
fetchBalance();
}, [])
-
+
+ const handleBlur = (event) => {
+
+ const handleBlur = (event) => {
+ if (event.target.validity.patternMismatch) {
+ setError(true);
+ }
+ };
+ };
+
function handleSubmit(event) {
// const form = document.getElementById('form');
event.preventDefault();
// const payload = new FormData(form);
- const balance = whole.split('.')
- if (balance.length < 2)
- balance.push(0);
- else if (balance[1].length < 1)
- balance.push(0);
+ console.log(whole);
+ const balance = whole.split('.')
+ console.log(balance)
+ if (balance.length < 2) {
+ balance.push('0');
+ }
+ else if (balance[1].length > 2) {
+ console.log("TEST SUCCESS")
+ }
+ else if (balance[1].length < 1) {
+ balance.push('0');
+ }
+
+
// console.log([...payload])
// const formData = new FormData();
// formData.append('whole', whole);
@@ -86,6 +104,7 @@ export default function FetchAPI() {
fetchBalance();
});
}
+
return (
<>
{/*
@@ -98,8 +117,13 @@ export default function FetchAPI() {
className="form-control"
placeholder="Enter Balance"
value={whole}
+ maxLength="10"
+ pattern="^[+]?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?"
+ title="Please enter the balance with two decimal places for cents. Please enter a balance 999999999.99"
onChange={(event) => setWhole(event.target.value)}
required />
+
+
>
diff --git a/src/context/AppContext.js b/src/context/AppContext.js
index 10761f0..b409ccc 100644
--- a/src/context/AppContext.js
+++ b/src/context/AppContext.js
@@ -49,4 +49,4 @@ export const AppProvider = (props) => {
{props.children}
);
-};
+};
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 94660bc..af99b24 100644
--- a/src/index.js
+++ b/src/index.js
@@ -9,13 +9,13 @@ import Main from './Main.js'
function App() {
return (
-
+ // COMMENTED OUT BY CHRIS TO FIX MULTIPLE TABLE DISPLAYED IN RECENT TRANSACTION
-
+ // praying I didn't break the project tbh
);
}
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index 3190118..723da7a 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -3,7 +3,7 @@ import { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import { AppProvider } from '../context/AppContext';
-import FetchAPI from '../components/Budget';
+import FetchAPI from '../components/budget';
import ExpenseTotal from '../components/ExpenseTotal';
import ExpenseList from '../components/ExpenseList';
import AddExpenseForm from '../components/AddExpenseForm';
@@ -24,11 +24,11 @@ export default function Dashboard() {
-