diff --git a/src/components/AddExpenseForm.js b/src/components/AddExpenseForm.js
new file mode 100644
index 0000000..29081f3
--- /dev/null
+++ b/src/components/AddExpenseForm.js
@@ -0,0 +1,65 @@
+import React, { useContext, useState } from 'react';
+import { AppContext } from '../context/AppContext';
+import { v4 as uuidv4 } from 'uuid';
+
+const AddExpenseForm = (props) => {
+ const { dispatch } = useContext(AppContext);
+
+ const [name, setName] = useState('');
+ const [cost, setCost] = useState('');
+
+ const onSubmit = (event) => {
+ event.preventDefault();
+ const expense = {
+ id: uuidv4(),
+ name,
+ cost: parseInt(cost),
+ };
+
+ dispatch({
+ type: 'ADD_EXPENSE',
+ payload: expense,
+ });
+
+ setName('');
+ setCost('');
+ };
+
+ return (
+
- needed to position the dropdown content */
- .dropdown {
- position: relative;
- display: inline-block;
- }
-
- /* Dropdown Content (Hidden by Default) */
- .dropdown-content {
- display: none;
- position: absolute;
- background-color: #f9f9f9;
- min-width: 160px;
- box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
- z-index: 1;
- }
-
- /* Links inside the dropdown */
- .dropdown-content a {
- color: black;
- padding: 12px 16px;
- text-decoration: none;
- display: block;
- }
-
- /* Change color of dropdown links on hover */
- .dropdown-content a:hover {background-color: #f1f1f1}
-
- /* Show the dropdown menu on hover */
- .dropdown:hover .dropdown-content {
- display: block;
- }
-
- /* Change the background color of the dropdown button when the dropdown content is shown */
- .dropdown:hover .dropbtn {
- background-color: #3e8e41;
- }
\ No newline at end of file
diff --git a/src/components/AddNewBill.js b/src/components/AddNewBill.js
deleted file mode 100644
index 5cd260f..0000000
--- a/src/components/AddNewBill.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react'
-import './AddNewBill.css'
-
-export default function AddNewBill() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
diff --git a/src/components/CurrentBalance.css b/src/components/CurrentBalance.css
deleted file mode 100644
index d9529f9..0000000
--- a/src/components/CurrentBalance.css
+++ /dev/null
@@ -1,23 +0,0 @@
-.current_balance_widget {
- background-color: rgb(223, 245, 229);
-}
-.widget_header {
-}
-
-img {
- float: left;
- height: 40px;
- margin-left: 5%;
-}
-
-.current_balance_widget h1 {
- float: left;
- margin: 0;
- margin-left: 10%;
-}
-.current_balance_widget h6 {
- color: green;
- float: left;
- margin: 0;
- margin-left: 33%;
-}
diff --git a/src/components/CurrentBalance.js b/src/components/CurrentBalance.js
deleted file mode 100644
index 9123602..0000000
--- a/src/components/CurrentBalance.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react'
-import './CurrentBalance.css'
-import logo from '../assets/widget_logos/current_balance_logo.png';
-
-export default function CurrentBalance() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
diff --git a/src/components/EditBudget.js b/src/components/EditBudget.js
new file mode 100644
index 0000000..eff7336
--- /dev/null
+++ b/src/components/EditBudget.js
@@ -0,0 +1,26 @@
+import React, { useState } from 'react';
+
+const EditBudget = (props) => {
+ const [value, setValue] = useState(props.budget);
+ return (
+ <>
+
setValue(event.target.value)}
+ />
+
props.handleSaveClick(value)}
+ >
+ Save
+
+ >
+ );
+};
+
+export default EditBudget;
diff --git a/src/components/ExpenseItem.js b/src/components/ExpenseItem.js
new file mode 100644
index 0000000..5088ede
--- /dev/null
+++ b/src/components/ExpenseItem.js
@@ -0,0 +1,24 @@
+import React, { useContext } from 'react';
+import { AppContext } from '../context/AppContext';
+
+const ExpenseItem = (props) => {
+ const { dispatch } = useContext(AppContext);
+
+ const handleDeleteExpense = () => {
+ dispatch({
+ type: 'DELETE_EXPENSE',
+ payload: props.id,
+ });
+ };
+
+ return (
+
+ {props.name}
+
+ ${props.cost}
+
+
+ );
+};
+
+export default ExpenseItem;
diff --git a/src/components/ExpenseList.js b/src/components/ExpenseList.js
new file mode 100644
index 0000000..91bae9d
--- /dev/null
+++ b/src/components/ExpenseList.js
@@ -0,0 +1,42 @@
+import React, { useContext, useState, useEffect } from 'react';
+import ExpenseItem from './ExpenseItem';
+import { AppContext } from '../context/AppContext';
+
+const ExpenseList = () => {
+ const { expenses } = useContext(AppContext);
+
+ const [filteredExpenses, setfilteredExpenses] = useState(expenses || []);
+
+ useEffect(() => {
+ setfilteredExpenses(expenses);
+ }, [expenses]);
+
+ const handleChange = (event) => {
+ const searchResults = expenses.filter((filteredExpense) =>
+ filteredExpense.name.toLowerCase().includes(event.target.value)
+ );
+ setfilteredExpenses(searchResults);
+ };
+
+ return (
+ <>
+
+
+ {filteredExpenses.map((expense) => (
+
+ ))}
+
+ >
+ );
+};
+
+export default ExpenseList;
diff --git a/src/components/ExpenseTotal.js b/src/components/ExpenseTotal.js
new file mode 100644
index 0000000..3cdd3e7
--- /dev/null
+++ b/src/components/ExpenseTotal.js
@@ -0,0 +1,18 @@
+import React, { useContext } from 'react';
+import { AppContext } from '../context/AppContext';
+
+const ExpenseTotal = () => {
+ const { expenses } = useContext(AppContext);
+
+ const total = expenses.reduce((total, item) => {
+ return (total += item.cost);
+ }, 0);
+
+ return (
+
+ This Month's Expenses: ${total}
+
+ );
+};
+
+export default ExpenseTotal;
diff --git a/src/components/Expenses.css b/src/components/Expenses.css
deleted file mode 100644
index 27c7098..0000000
--- a/src/components/Expenses.css
+++ /dev/null
@@ -1,20 +0,0 @@
-.expenses_widget {
- background-color: rgb(223, 245, 229);
-}
-.widget_header {
-}
-
-img {
- height: 40px;
-}
-
-.expenses_widget h1 {
- float: left;
- margin: 0;
- margin-left: 10%;
-}
-.expenses_widget h6 {
- color: red;
- float: right;
- margin: 0;
-}
diff --git a/src/components/Expenses.js b/src/components/Expenses.js
deleted file mode 100644
index 086b6dd..0000000
--- a/src/components/Expenses.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react'
-import './Expenses.css'
-import logo from '../assets/widget_logos/expenses_logo.png';
-
-export default function Expenses() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
diff --git a/src/components/Income.css b/src/components/Income.css
deleted file mode 100644
index a571360..0000000
--- a/src/components/Income.css
+++ /dev/null
@@ -1,20 +0,0 @@
-.income_widget {
- background-color: rgb(223, 245, 229);
-}
-.widget_header {
-}
-
-img {
- height: 40px;
-}
-
-.income_widget h1 {
- float: left;
- margin: 0;
- margin-left: 10%;
-}
-.income_widget h6 {
- color: green;
- margin: 0;
- float: right;
-}
diff --git a/src/components/Income.js b/src/components/Income.js
deleted file mode 100644
index c1c2112..0000000
--- a/src/components/Income.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react'
-import './Income.css'
-import logo from '../assets/widget_logos/income_logo.png';
-
-export default function Income() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
diff --git a/src/components/RecentTransaction.css b/src/components/RecentTransaction.css
deleted file mode 100644
index 51027a8..0000000
--- a/src/components/RecentTransaction.css
+++ /dev/null
@@ -1,15 +0,0 @@
-.transactions_widget {
- background-color: rgb(223, 245, 229);
-}
-
-.transaction_table {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- grid-template-rows: 30px 30px 30px 30px;
- box-sizing: border-box;
-}
-
-.transaction_table p {
- margin: 0;
- float: left;
-}
\ No newline at end of file
diff --git a/src/components/RecentTransactions.js b/src/components/RecentTransactions.js
deleted file mode 100644
index 49fd46d..0000000
--- a/src/components/RecentTransactions.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react'
-import './RecentTransaction.css'
-
-export default function RecentTransactions() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
diff --git a/src/components/Remaining.js b/src/components/Remaining.js
new file mode 100644
index 0000000..66486c3
--- /dev/null
+++ b/src/components/Remaining.js
@@ -0,0 +1,20 @@
+import React, { useContext } from 'react';
+import { AppContext } from '../context/AppContext';
+
+const RemainingBudget = () => {
+ const { expenses, budget } = useContext(AppContext);
+
+ const totalExpenses = expenses.reduce((total, item) => {
+ return (total += item.cost);
+ }, 0);
+
+ const alertType = totalExpenses > budget ? 'alert-danger' : 'alert-success';
+
+ return (
+
+ Budget Remaining: ${budget - totalExpenses}
+
+ );
+};
+
+export default RemainingBudget;
diff --git a/src/components/SideNav.css b/src/components/SideNav.css
index ab42973..e637b76 100644
--- a/src/components/SideNav.css
+++ b/src/components/SideNav.css
@@ -1,7 +1,3 @@
-.sidebar {
- padding: 0 12px;
-}
-
.sidebar-header {
display: flex;
align-items: center;
diff --git a/src/components/SideNav.js b/src/components/SideNav.js
index ee2142a..72feec3 100644
--- a/src/components/SideNav.js
+++ b/src/components/SideNav.js
@@ -12,7 +12,7 @@ import './SideNav.css'
export default function SideNav() {
return(
-
+
diff --git a/src/components/ViewBudget.js b/src/components/ViewBudget.js
new file mode 100644
index 0000000..05f0639
--- /dev/null
+++ b/src/components/ViewBudget.js
@@ -0,0 +1,14 @@
+import React from 'react';
+
+const ViewBudget = (props) => {
+ return (
+ <>
+
Current Balance: ${props.budget}
+
+ Edit
+
+ >
+ );
+};
+
+export default ViewBudget;
diff --git a/src/components/budget.css b/src/components/budget.css
deleted file mode 100644
index e381257..0000000
--- a/src/components/budget.css
+++ /dev/null
@@ -1,23 +0,0 @@
-.budget_widget {
- background-color: rgb(223, 245, 229);
-}
-.widget_header {
-}
-
-img {
- float: left;
- height: 40px;
- margin-left: 5%;
-}
-
-.budget_widget h1 {
- float: left;
- margin: 0;
- margin-left: 10%;
-}
-.budget_widget h6 {
- color: green;
- float: left;
- margin: 0;
- margin-left: 37%;
-}
diff --git a/src/components/budget.js b/src/components/budget.js
index 4efc95b..834b2a2 100644
--- a/src/components/budget.js
+++ b/src/components/budget.js
@@ -1,17 +1,33 @@
-import React from 'react'
-import './budget.css'
-import logo from '../assets/widget_logos/budget_logo.png';
+import React, { useState, useContext } from 'react';
+import ViewBudget from './ViewBudget';
+import EditBudget from './EditBudget';
+import { AppContext } from '../context/AppContext';
-export default function Budget() {
- return (
- <>
-
- >
-
- )
-}
\ No newline at end of file
+const Budget = () => {
+ const { budget, dispatch } = useContext(AppContext);
+ const [isEditing, setIsEditing] = useState(false);
+
+ const handleEditClick = () => {
+ setIsEditing(true);
+ };
+
+ const handleSaveClick = (value) => {
+ dispatch({
+ type: 'SET_BUDGET',
+ payload: value,
+ });
+ setIsEditing(false);
+ };
+
+ return (
+
+ {isEditing ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+export default Budget;
diff --git a/src/context/AppContext.js b/src/context/AppContext.js
new file mode 100644
index 0000000..b90fc7c
--- /dev/null
+++ b/src/context/AppContext.js
@@ -0,0 +1,56 @@
+import React, { createContext, useReducer } from 'react';
+import { v4 as uuidv4 } from 'uuid';
+
+export const AppReducer = (state, action) => {
+ switch (action.type) {
+ case 'ADD_EXPENSE':
+ return {
+ ...state,
+ expenses: [...state.expenses, action.payload],
+ };
+ case 'DELETE_EXPENSE':
+ return {
+ ...state,
+ expenses: state.expenses.filter(
+ (expense) => expense.id !== action.payload
+ ),
+ };
+ case 'SET_BUDGET':
+ return {
+ ...state,
+ budget: action.payload,
+ };
+
+ default:
+ return state;
+ }
+};
+
+const initialState = {
+ budget: 2000,
+ expenses: [
+ { id: uuidv4(), name: 'Groceries', cost: 50 },
+ { id: uuidv4(), name: 'Leisure', cost: 300 },
+ { id: uuidv4(), name: 'Pet', cost: 70 },
+ { id: uuidv4(), name: 'Gas', cost: 40 },
+ { id: uuidv4(), name: 'Rent', cost: 500 },
+ ],
+};
+
+export const AppContext = createContext();
+
+export const AppProvider = (props) => {
+ const [state, dispatch] = useReducer(AppReducer, initialState);
+
+ return (
+
+ {props.children}
+
+ );
+};
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index f166210..3a3418d 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -1,19 +1,42 @@
- import AddNewBill from '../components/AddNewBill'
- import CurrentBalance from '../components/CurrentBalance'
- import Expenses from '../components/Expenses'
- import Income from '../components/Income'
- import Budget from '../components/budget'
-import RecentTransactions from '../components/RecentTransactions'
-
- export default function Dashboard() {
- return (
- <>
-
-
-
-
-
-
- >
- )
+import React from 'react';
+import 'bootstrap/dist/css/bootstrap.min.css';
+
+import { AppProvider } from '../context/AppContext';
+import Budget from '../components/Budget';
+import ExpenseTotal from '../components/ExpenseTotal';
+import ExpenseList from '../components/ExpenseList';
+import AddExpenseForm from '../components/AddExpenseForm';
+import RemainingBudget from '../components/Remaining';
+
+export default function Dashboard() {
+ return (
+
+
+
My Budget Planner
+
+
Expenses
+
+
Add Expense
+
+
+
+ );
}
\ No newline at end of file
diff --git a/src/styles.css b/src/styles.css
index cd41d76..180297c 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -24,12 +24,12 @@ code {
border-radius: 20px;
padding: 20px 30px;
width: 100vw;
- display: grid;
+ /*display: grid; COMMENTED OUT BY CHRIS FOR PUSH ON WIDGETS, not sure if need for welcome page or not, do not need anymore for widgets
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 125px 250px 100px 100px;
gap: 10px;
padding: 10px;
- box-sizing: border-box;
+ box-sizing: border-box; */
}
.page-display div {