-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from DoughFin/feature/df-98-debug-displays-for…
…-data-for-expenses-and-income Feature/df 98 debug displays for data for expenses and income
- Loading branch information
Showing
15 changed files
with
349 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,41 +5,48 @@ import Dashboard from '../Dashboard/Dashboard' | |
// import transactionsFixtureData from "../sample-data/TransactionsData.json" | ||
// import incomeData from "../sample-data/IncomeData.json" | ||
// import expensesData from "../sample-data/ExpensesData.json" | ||
// import budgetsData from "../sample-data/BudgetsData.json" | ||
import './App.css'; | ||
import { useGetIncomes } from '../apollo-client/queries/getIncomes'; | ||
import { useGetExpenses } from '../apollo-client/queries/getExpenses'; | ||
import { useGetTransactions } from '../apollo-client/queries/getTransactions'; | ||
import { useGetCashFlow } from '../apollo-client/queries/getCashFlow'; | ||
|
||
import { useGetBudgetsByParams } from '../apollo-client/queries/getBudgetsByParams'; | ||
|
||
const App = () => { | ||
const [transactions, setTransactions] = useState([]); | ||
const [totalIncome, setTotalIncome] = useState(0); | ||
const [totalExpenses, setTotalExpenses] = useState(0); | ||
const [cashFlow, setCashFlow] = useState(null); | ||
const [budgets, setBudgets] = useState(null); | ||
|
||
// Hardcoded user, will pull from getUser endpoint soon | ||
const month = "2024-02"; | ||
// const category = "Travel"; | ||
const userName = "Powdered Toast Man"; | ||
const email = "[email protected]" | ||
|
||
localStorage.setItem('email', email); | ||
|
||
const { totalIncomeData } = useGetIncomes(email); | ||
const { totalExpensesData } = useGetExpenses(email); | ||
const { transactionsData } = useGetTransactions(email); | ||
const { cashFlowData } = useGetCashFlow(email); | ||
// const { budgetsData } = useGetBudgetsByParams(month, category, email); | ||
|
||
useEffect(() => { | ||
if (totalIncomeData) { | ||
const totalIncomeCents = Math.round(parseFloat(totalIncomeData) * 100); | ||
const totalIncomeCents = totalIncomeData; | ||
setTotalIncome(totalIncomeCents); | ||
} | ||
if (totalExpensesData) { | ||
const totalExpensesCents = Math.round(parseFloat(totalExpensesData) * 100); | ||
const totalExpensesCents = totalExpensesData; | ||
setTotalExpenses(totalExpensesCents); | ||
} | ||
if (totalExpensesData) setTotalExpenses(totalExpensesData); | ||
if (transactionsData) setTransactions(transactionsData); | ||
if (cashFlowData) setCashFlow(cashFlowData); | ||
}, [totalIncomeData, totalExpensesData, transactionsData, cashFlowData]); | ||
// if (budgetsData) setBudgets(budgetsData); | ||
}, [totalIncomeData, totalExpensesData, transactionsData, cashFlowData]); | ||
|
||
return ( | ||
<main className='app'> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
import * as React from 'react'; | ||
import { PieChart } from '@mui/x-charts/PieChart'; | ||
|
||
const data = [ | ||
// Default data for fallback | ||
const defaultData = [ | ||
{ id: 0, value: 25 }, | ||
{ id: 1, value: 15 }, | ||
{ id: 1, value: 75 }, | ||
]; | ||
|
||
export default function PieActiveArc() { | ||
export default function BasicPie({ data }) { | ||
// Validate incoming data - simple example | ||
const isValidData = data && Array.isArray(data) && data.length > 0 && data.every(d => d.hasOwnProperty('value') && typeof d.value === 'number'); | ||
|
||
// Use incoming data if valid, otherwise use default | ||
const pieData = isValidData ? data : defaultData; | ||
|
||
return ( | ||
<PieChart | ||
series={[ | ||
{ | ||
data, | ||
highlightScope: { faded: 'global', highlighted: 'item' }, | ||
faded: { innerRadius: 30, additionalRadius: -30, color: 'gray' }, | ||
cx: 140, | ||
innerRadius: 60, | ||
outerRadius: 100, | ||
paddingAngle: 5, | ||
cornerRadius: 5, | ||
}, | ||
]} | ||
height={200} | ||
/> | ||
<PieChart | ||
series={[ | ||
{ | ||
data: pieData, | ||
highlightScope: { faded: 'global', highlighted: 'item' }, | ||
faded: { innerRadius: 30, additionalRadius: -30, color: 'gray' }, | ||
cx: 140, | ||
innerRadius: 60, | ||
outerRadius: 100, | ||
paddingAngle: 5, | ||
cornerRadius: 5, | ||
}, | ||
]} | ||
height={200} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,148 @@ | ||
import React from 'react' | ||
import React, { useState, useRef, useEffect, useMemo } from 'react' | ||
import './Budget.css' | ||
import BasicPie from './BasicPie' | ||
import './budgetSelectModal.css' | ||
import DropDownIcon from '../../assets/icons/dropdown-icon.svg' | ||
import EllipsePurple from '../../assets/icons/Ellipse-purple.svg' | ||
import EllipseBlue from '../../assets/icons/Ellipse-blue.svg' | ||
import PlusIcon from '../../assets/icons/plus-icon.svg' | ||
import { useGetBudgetsByParams } from "../apollo-client/queries/getBudgetsByParams"; | ||
import { useGetBudgetCategories } from "../apollo-client/queries/getBudgetCategories"; | ||
|
||
const Budget = () => { | ||
return ( | ||
const email = "[email protected]"; | ||
const { loading: loadingCategories, error: errorCategories, budgetCategoriesData } = useGetBudgetCategories(email); | ||
console.log("Fetched budgetCategoriesData:", budgetCategoriesData); | ||
const categories = loadingCategories || errorCategories ? [] : budgetCategoriesData || []; | ||
|
||
const [category, setCategory] = useState(); | ||
const [month, setMonth] = useState(getCurrentMonth()); | ||
const { loading, error, budgetsData } = useGetBudgetsByParams(month, category, email); | ||
// debugger; | ||
if (error) { | ||
console.error("Error fetching data:", error); | ||
} | ||
console.log("Fetched budgetData:", budgetsData); | ||
const pctRemaining = Math.round(budgetsData?.budgets[0]?.pctRemaining) || 'Loading...'; | ||
const amount = budgetsData?.budgets[0]?.amount || 'Loading...'; | ||
const amountRemaining = Math.round(budgetsData?.budgets[0]?.amountRemaining) || 'Loading...'; | ||
|
||
// State to manage dropdown visibility | ||
const [isDropdownVisible, setIsDropdownVisible] = useState(false); | ||
const [dropDownStyle, setDropdownStyle] = useState({}); // State to hold modal's dynamic style | ||
// references | ||
const dropdownRef = useRef(null); // Ref for the dropdown icon to position the modal | ||
const modalRef = useRef(null); // Add a ref for the modal | ||
|
||
// Handler functions for updating state | ||
const handleCategoryChange = (selectedCategory) => { | ||
setCategory(selectedCategory); | ||
setIsDropdownVisible(false); // Hide the modal | ||
}; | ||
// Handler to toggle dropdown visibility | ||
const toggleDropdownVisibility = () => { | ||
setIsDropdownVisible(!isDropdownVisible); | ||
|
||
if (dropdownRef.current) { | ||
const { bottom, right } = dropdownRef.current.getBoundingClientRect(); | ||
const rightOffset = window.innerWidth - right; // Calculate the right offset from the viewport | ||
|
||
setDropdownStyle({ | ||
position: 'absolute', | ||
top: `${bottom}px`, | ||
right: `${rightOffset}px`, | ||
// Adjustments might be needed based on actual layout and styling | ||
}); | ||
} | ||
}; | ||
const handleMonthChange = (event) => { | ||
setMonth(event.target.value); | ||
}; | ||
// Utility function to get current month, implementation depends on your needs | ||
function getCurrentMonth() { | ||
const date = new Date(); | ||
const year = date.getFullYear(); // Get current year | ||
let month = date.getMonth() + 1; // Get current month (0-11, hence +1) | ||
month = month < 10 ? `0${month}` : month; // Ensure month is in two digits | ||
return `${year}-${month}`; // Concatenate to get "YYYY-MM" format | ||
} | ||
|
||
useEffect(() => { | ||
if (categories.length > 0) { | ||
setCategory(categories[0]); | ||
} | ||
}, [categories]); | ||
|
||
useEffect(() => { | ||
const handleClickOutside = (event) => { | ||
if (modalRef.current && !modalRef.current.contains(event.target) && | ||
dropdownRef.current && !dropdownRef.current.contains(event.target)) { | ||
setIsDropdownVisible(false); | ||
} | ||
}; | ||
|
||
document.addEventListener('mousedown', handleClickOutside); | ||
return () => { | ||
document.removeEventListener('mousedown', handleClickOutside); | ||
}; | ||
}, []); // This effect does not depend on `categories` | ||
|
||
return ( | ||
<aside className='budget'> | ||
<header className='budget-header'> | ||
<h2>Budget</h2> | ||
<img className='budget-dropdown-button' src={DropDownIcon} alt='dropdown icon' /> | ||
</header> | ||
<summary className='budget-pie-chart'> | ||
<BasicPie /> | ||
</summary> | ||
<section className='budget-percentage-breakdown'> | ||
<div className='percentage-container'> | ||
<div className='percentage-description'> | ||
<img src={EllipsePurple} alt='purple ellipse' /> | ||
<p>Daily payment</p> | ||
<h2>{category}</h2> | ||
<div ref={dropdownRef} onClick={toggleDropdownVisibility}> | ||
<img className='budget-dropdown-button' src={DropDownIcon} alt='dropdown icon' /> | ||
</div> | ||
<p className='percentage'>25%</p> | ||
</div> | ||
<div className='percentage-container'> | ||
{/* Conditionally render select dropdown */} | ||
{isDropdownVisible && ( | ||
<div ref={modalRef} className="select-modal" style={dropDownStyle}> | ||
{/* Dynamically generated modal content with options */} | ||
{categories.length > 0 ? ( | ||
categories.map((category, index) => ( | ||
<div key={index} onClick={() => handleCategoryChange(category)}>{category}</div> | ||
)) | ||
) : ( | ||
<div>No categories found.</div> // Or handle the empty state differently | ||
)} | ||
</div> | ||
)} | ||
</header> | ||
<summary className='budget-pie-chart'> | ||
<BasicPie | ||
data={[ | ||
{ id: 0, value: (100 - pctRemaining) }, | ||
{ id: 1, value: pctRemaining }, | ||
]} | ||
/> | ||
</summary> | ||
<section className='budget-percentage-breakdown'> | ||
<div className='percentage-container'> | ||
<div className='percentage-description'> | ||
<img src={EllipsePurple} alt='purple ellipse'/> | ||
<p>Budget Remaining</p> | ||
</div> | ||
<p className='percentage'>{pctRemaining}%</p> | ||
</div> | ||
<div className='percentage-container'> | ||
<div className='percentage-description'> | ||
<img src={EllipseBlue} alt='purple ellipse' /> | ||
<p>Hobby</p> | ||
<p>Budget Used</p> | ||
</div> | ||
<p className='percentage'>15%</p> | ||
<p className='percentage'>{100 - pctRemaining}%</p> | ||
</div> | ||
</section> | ||
<section className='budget-details-container'> | ||
<div className='budget-details'> | ||
<h3 className='budget-details-h3'>Set Budget</h3> | ||
<h3 className='budget-details-h3'>Budgeted Amount</h3> | ||
<div className='budget-details-flex'> | ||
<p className='budget-details-amount'>$200</p> | ||
<p className='budget-details-amount'>${amount}</p> | ||
</div> | ||
</div> | ||
<div className='budget-details'> | ||
<h3 className='budget-details-h3'>Remaining Budget</h3> | ||
<div className='budget-details-flex'> | ||
<p className='budget-details-amount'>$200</p> | ||
<p className='budget-details-amount'>${amountRemaining}</p> | ||
</div> | ||
</div> | ||
</section> | ||
|
@@ -53,7 +153,6 @@ const Budget = () => { | |
</div> | ||
</section> | ||
</aside> | ||
) | ||
} | ||
|
||
export default Budget | ||
) | ||
} | ||
export default Budget |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.select-modal { | ||
cursor: pointer; | ||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||
background-color: rgba(255, 255, 255, 0.77); | ||
padding: 10px 0; | ||
border-radius: 4px; | ||
z-index: 100; /* Ensure it sits above other content */ | ||
} | ||
|
||
.select-modal div { | ||
padding: 7px 7px; /* Apply horizontal padding here for content alignment */ | ||
margin: 0; /* Remove margin to allow hover to fill from edge to edge */ | ||
width: 100%; /* Adjust width to account for padding */ | ||
box-sizing: border-box; /* Ensure padding is included in the width calculation */ | ||
} | ||
|
||
.select-modal div:hover { | ||
background-color: rgba(86, 77, 201, 0.7); /* Updated color for visibility */ | ||
/* Ensures hover effect extends to full width of each option */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.