diff --git a/src/App.tsx b/src/App.tsx index 6bc98f9..c038f2c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,11 +2,13 @@ import './styles/App.css'; import './styles/Tailwind.css'; import './styles/Animations.css'; import { ProjectRoutes } from './routes/Routes'; +import { NewHome } from './pages/NewHome'; function App() { return (
- + {/* */} +
); } diff --git a/src/components/AnimatedLoader.tsx b/src/components/AnimatedLoader.tsx new file mode 100644 index 0000000..bee5636 --- /dev/null +++ b/src/components/AnimatedLoader.tsx @@ -0,0 +1,35 @@ +import { LoadingTransactionItem } from "./core/LoadingTransactionItem" + +export const AnimatedLoader = () => { + return ( +
+
+
+ Total: + sum +
+
+
+

+ + Category +

+

+ + Account +

+
+
+
+
+ + + + +
+ +
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/LoadingComponent.tsx b/src/components/LoadingComponent.tsx index 1ac5116..92b52cc 100644 --- a/src/components/LoadingComponent.tsx +++ b/src/components/LoadingComponent.tsx @@ -1,3 +1,5 @@ +import { AnimatedLoader } from "./AnimatedLoader" + export const LoadingComponent = () => { // fetch url from local storage @@ -23,14 +25,10 @@ export const LoadingComponent = () => { else { return (
-
Loading +
-
- - Loading... +
+
diff --git a/src/components/buttons/AccountFilterButton.tsx b/src/components/buttons/AccountFilterButton.tsx new file mode 100644 index 0000000..0a95f6e --- /dev/null +++ b/src/components/buttons/AccountFilterButton.tsx @@ -0,0 +1,55 @@ +import { Modal } from "flowbite-react" +import { useState } from "react"; +import { AccountFilter } from "../../hooks/AccountFilter"; + +type accountProp = { + currentData: any; + accountC: string; + setAccountC: React.Dispatch>; +} + +export const AccountFilterButton = (accountProps: accountProp) => { + const [openModal, setOpenModal] = useState(); + const props = { openModal, setOpenModal }; + + // listen to escape key + window.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + setOpenModal('false'); + } + }); + + return ( +
+
( + props.setOpenModal('default') + )}> +

+ + Account +

+
+ + props.setOpenModal(undefined)}> + + Select the Account + + +
+ +
+
+ + + + + + +
+
+ ) +} \ No newline at end of file diff --git a/src/components/buttons/CategoryFilterButton.tsx b/src/components/buttons/CategoryFilterButton.tsx new file mode 100644 index 0000000..56955f4 --- /dev/null +++ b/src/components/buttons/CategoryFilterButton.tsx @@ -0,0 +1,56 @@ +import { Modal } from "flowbite-react" +import { useState } from "react"; +import { CategoryFilter } from "../../hooks/CategoryFilter"; + +type categoryProp = { + currentData: any; + categoryC: string; + setCategoryC: React.Dispatch>; +} + +export const CategoryFilterButton = (categoryProps: categoryProp) => { + const [openModal, setOpenModal] = useState(); + const props = { openModal, setOpenModal }; + + // listen to escape key + window.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + setOpenModal('false'); + } + }); + + return ( +
+
( + props.setOpenModal('default') + )}> +

+ + Category +

+
+ + props.setOpenModal(undefined)}> + + Select the Category + + +
+ +
+
+ + + + + +
+
+ ) +} \ No newline at end of file diff --git a/src/components/buttons/RemoveAccountButton.tsx b/src/components/buttons/RemoveAccountButton.tsx new file mode 100644 index 0000000..b573812 --- /dev/null +++ b/src/components/buttons/RemoveAccountButton.tsx @@ -0,0 +1,37 @@ +import { androidColorToHex } from "../../utils/AndroidColorToHex"; + +type removeAccountProp = { + accountC: string; + setAccountC: React.Dispatch>; +} + +export const RemoveAccountButton = (props: removeAccountProp) => { + + // fetch color from theData and set it to the backgroundColor + const data = () => { + const theData = localStorage.getItem('theData'); + if (theData !== null) { + const parsedData = JSON.parse(theData); + console.log(parsedData) + const account = parsedData.accounts.filter((item: any) => item.name === props.accountC); + return account[0].color + } + + return '' + + } + + // convert android color to hex + const color = androidColorToHex(data()) + + + return ( +

props.setAccountC('')} + className="p-2 px-10 m-1 rounded-full hover:shadow-md cursor-pointer fade-in" + style={{ backgroundColor: color }}> + {props.accountC} + +

+ ) +} \ No newline at end of file diff --git a/src/components/buttons/RemoveCategoryButton.tsx b/src/components/buttons/RemoveCategoryButton.tsx new file mode 100644 index 0000000..598e1dc --- /dev/null +++ b/src/components/buttons/RemoveCategoryButton.tsx @@ -0,0 +1,37 @@ +import { androidColorToHex } from "../../utils/AndroidColorToHex"; + +type removeCategoryProp = { + categoryC: string; + setCategoryC: React.Dispatch>; +} + +export const RemoveCategoryButton = (props: removeCategoryProp) => { + + // fetch color from theData and set it to the backgroundColor + const data = () => { + const theData = localStorage.getItem('theData'); + if (theData !== null) { + const parsedData = JSON.parse(theData); + const category = parsedData.categories.filter((item: any) => item.name === props.categoryC); + return category[0].color + } + + + return '' + + } + + // convert android color to hex + const color = androidColorToHex(data()) + + + return ( +

props.setCategoryC('')} + className="p-2 px-10 m-1 rounded-full hover:shadow-md cursor-pointer fade-in" + style={{ backgroundColor: color }}> + {props.categoryC} + +

+ ) +} \ No newline at end of file diff --git a/src/components/buttons/SettingsButton.tsx b/src/components/buttons/SettingsButton.tsx new file mode 100644 index 0000000..b2e812b --- /dev/null +++ b/src/components/buttons/SettingsButton.tsx @@ -0,0 +1,57 @@ +import { useState } from "react"; +import { Modal } from "flowbite-react"; +import { JSONdata } from "../../services/JSONdata"; +import { ClearData } from "../data/ClearData"; +import DarkModeButton from "../layout/DarkModeButton"; + +export const SettingsButton = () => { + const [openModal, setOpenModal] = useState(); + const props = { openModal, setOpenModal }; + + // listen to escape key + window.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + setOpenModal('false'); + } + }); + + return ( + <> +
( + props.setOpenModal('default') + )}> + +
+ Settings +
+
+ + props.setOpenModal(undefined)}> + + Settings + + +
+
+ +
+
+ +
+
+ +
+
+
+ + + + + +
+ + ) +} \ No newline at end of file diff --git a/src/components/core/Button.tsx b/src/components/core/Button.tsx deleted file mode 100644 index 96f8e80..0000000 --- a/src/components/core/Button.tsx +++ /dev/null @@ -1,15 +0,0 @@ -type buttonProp = { - title: string; - iClass: string; -} - -export const Button = (props: buttonProp) => { - return ( -
-

- - {props.title} -

-
- ) -} \ No newline at end of file diff --git a/src/components/core/LoadingTransactionItem.tsx b/src/components/core/LoadingTransactionItem.tsx new file mode 100644 index 0000000..5f42403 --- /dev/null +++ b/src/components/core/LoadingTransactionItem.tsx @@ -0,0 +1,44 @@ +export const LoadingTransactionItem = () => { + return ( +
+
+

+ March 01 +

+

+ Friday +

+ +
+
+

+ Category +

+
+
+

+ Account +

+
+
+ +

+ title +

+

+ description +

+

+ asds + + asd + +

+
+ +
+ ) +} \ No newline at end of file diff --git a/src/components/layout/DarkModeButton.tsx b/src/components/layout/DarkModeButton.tsx index 129660e..534e74c 100644 --- a/src/components/layout/DarkModeButton.tsx +++ b/src/components/layout/DarkModeButton.tsx @@ -25,10 +25,18 @@ export default function DarkModeButton() { return ( - +
+

Dark Mode

+
+

+ Toggle dark mode {darkSide ? "off" : "on"} +

+ +
+
); } diff --git a/src/components/more/DarkModeSetting.tsx b/src/components/more/DarkModeSetting.tsx deleted file mode 100644 index de60291..0000000 --- a/src/components/more/DarkModeSetting.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import DarkModeButton from "../layout/DarkModeButton" - -export const DarkModeSetting = () => { - - return ( -
-

Dark Mode

-
-

- Toggle dark mode -

- -
-
- ) -} \ No newline at end of file diff --git a/src/constants/DateOptions.tsx b/src/constants/DateOptions.tsx index 42ae1a6..d9b8da5 100644 --- a/src/constants/DateOptions.tsx +++ b/src/constants/DateOptions.tsx @@ -4,7 +4,10 @@ const theData = localStorage.getItem('theData') const uniqueYearsArray = [] -if (theData === undefined) { +// theData is string but convert it to array +const theDataParsed = JSON.parse(theData?.toString() || '[]') + +if (theDataParsed.transactions === null) { const data = () => { const theData = localStorage.getItem('theData') || '' @@ -40,6 +43,7 @@ if (theData === undefined) { return { uniqueTransactions } } + console.log(data()) const uniqueYears = data().uniqueTransactions .reduce((acc: any, current: any) => { diff --git a/src/hooks/AccountFilter.tsx b/src/hooks/AccountFilter.tsx index 826cb38..9ebc12b 100644 --- a/src/hooks/AccountFilter.tsx +++ b/src/hooks/AccountFilter.tsx @@ -1,6 +1,4 @@ -import { useEffect, useState } from "react" import { androidColorToHex } from "../utils/AndroidColorToHex"; -import { accountSum } from "../utils/SumFunction"; type AccountProps = { accountC: string; @@ -9,39 +7,19 @@ type AccountProps = { } export const AccountFilter = (props: AccountProps) => { - const [data, setData] = useState([]) - - useEffect(() => { - const theData = localStorage.getItem('theData') || '' - if (theData !== '') setData(JSON.parse(theData)) - }, []) - - const currentData = props.dataBase !== undefined ? props.dataBase.filter((item: any) => item.type !== "TRANSFER") : [] // show all accounts from local storage const accounts = localStorage.getItem('accountData') !== null ? JSON.parse(localStorage.getItem('accountData') || '') : [] - // find the sum of all transaction in the account - const sum = accountSum(currentData, props.accountC) - return ( -
- {props.accountC === '' ? ( -
- No transactions found -
- ) : ( -
- Total: {sum} {currentData.accountCurrency} -
- )} +
{ accounts.map((item: any) => ( -
( item.name === props.accountC ? props.setAccountC('') : props.setAccountC(item.name) )}> diff --git a/src/hooks/CategoryFilter.tsx b/src/hooks/CategoryFilter.tsx index f01448c..18f3a52 100644 --- a/src/hooks/CategoryFilter.tsx +++ b/src/hooks/CategoryFilter.tsx @@ -1,6 +1,4 @@ -import { useEffect, useState } from "react" import { androidColorToHex } from "../utils/AndroidColorToHex"; -import { categorySum } from "../utils/SumFunction"; type CategoryProps = { categoryC: string; @@ -9,39 +7,19 @@ type CategoryProps = { } export const CategoryFilter = (props: CategoryProps) => { - const [data, setData] = useState([]) - - useEffect(() => { - const theData = localStorage.getItem('theData') || '' - if (theData !== '') setData(JSON.parse(theData)) - }, []) - - const currentData = props.dataBase !== undefined ? props.dataBase.filter((item: any) => item.type !== "TRANSFER") : [] // show all accounts from local storage const categories = localStorage.getItem('categoryData') !== null ? JSON.parse(localStorage.getItem('categoryData') || '') : [] - // find the sum of all transaction in the account - const sum = categorySum(currentData, props.categoryC) - return ( -
- {props.categoryC === '' ? ( -
- No transactions found -
- ) : ( -
- Total: {sum} {data.settings[0].currency} -
- )} +
{ categories.map((item: any) => ( -
( item.name === props.categoryC ? props.setCategoryC('') : props.setCategoryC(item.name) )}> @@ -61,100 +39,4 @@ export const CategoryFilter = (props: CategoryProps) => {
) -} - - -/* -import { useEffect, useState } from 'react' -import { LoadingComponent } from '../components/LoadingComponent' -import { DateFilter } from './DateFilter' -import { TransactionItem } from '../components/core/TransactionItem' -import { androidColorToHex } from '../utils/AndroidColorToHex' - -export const setAccounts = () => { - const [data, setData] = useState([]) - const [account, setAccount] = useState(localStorage.getItem('accountName') || '') - - const [year, setYear] = useState('') - const [month, setMonth] = useState('') - - useEffect(() => { - const theData = localStorage.getItem('theData') || '' - if (theData !== '') setData(JSON.parse(theData)) - }, []) - - // load page after data is fetched - if (data.transactions === undefined) { - return ( - - ) - } - - const currentData1 = data.transactions.filter((item: any) => item.type !== "TRANSFER") - const currentData = currentData1.filter((item: any) => item.transactionMonth.toString() === month.toString() && - item.transactionYear.toString() === year.toString()) - - // show all accounts from local storage - const accounts = localStorage.getItem('accountData') !== null ? JSON.parse(localStorage.getItem('accountData') || '') : [] - - // save function - function save(acName: any) { - localStorage.setItem('accountName', acName) - setAccount(acName) - } - - // find the sum of all transaction in the account - const sum = currentData.filter((item: any) => item.accountName === account) - .reduce((acc: any, item: any) => acc + item.amount, 0) - - - return ( -
- - - {sum === 0 ? ( -
- No transactions found -
- ) : ( - -
- Total: {sum} {data.settings[0].currency} -
- )} -
- { - accounts.map((item: any) => ( -
( - save(item.name) - )}> -

- {item.name} -

-

- {item.sum} {item.currency} -

-
- )) - } -
-
- { - // only show transaction with same account name - currentData.map((item: any) => ( - item.accountName === account && - - )) - } -
-
- ) -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/pages/NewHome.tsx b/src/pages/NewHome.tsx new file mode 100644 index 0000000..fe65ac5 --- /dev/null +++ b/src/pages/NewHome.tsx @@ -0,0 +1,149 @@ +import { useEffect, useState } from 'react' +import { LoadingComponent } from '../components/LoadingComponent' +import { TransactionItem } from '../components/core/TransactionItem' +import { totalSum } from '../utils/SumFunction' +import { AccountFilterButton } from '../components/buttons/AccountFilterButton' +import { CategoryFilterButton } from '../components/buttons/CategoryFilterButton' +import { SettingsButton } from '../components/buttons/SettingsButton' +import { TimeWidget } from '../widgets/Time' +import { RemoveAccountButton } from '../components/buttons/RemoveAccountButton' +import { RemoveCategoryButton } from '../components/buttons/RemoveCategoryButton' +import { AnimatedLoader } from '../components/AnimatedLoader' + +export const NewHome = () => { + const [data, setData] = useState([]) + const [year, setYear] = useState('') + const [month, setMonth] = useState('') + const [account, setAccountC] = useState('') + const [category, setCategoryC] = useState('') + + // FETCH THE LOCALLY SAVED DATA + useEffect(() => { + const theData = localStorage.getItem('theData') || '' + if (theData !== '') setData(JSON.parse(theData)) + }, []) + + // load page after data is fetched + if (data.transactions === undefined) { + return ( +
+
+
+
+ Logo +
+
+
+ + +
+
+ +
+ ) + } + + // dont show any transfer transactions + const currentData1 = data.transactions.filter((item: any) => item.type !== "TRANSFER") + const currentData = currentData1.filter((item: any) => item.transactionMonth.toString() === month.toString() && + item.transactionYear.toString() === year.toString()) + + const sum = totalSum(currentData, account, category) + + // after 2s show ch2 and hide ch1 + setTimeout(() => { + document.getElementById('ch1')!.style.display = 'none' + document.getElementById('ch2')!.style.display = 'block' + }, 2000) + + return ( +
+
+
+
+ Logo +
+
+
+ + +
+
+
+ +
+
+ {sum === 0 ? +
+ No Transactions Found +
+ : +
+ Total: {sum} +
+ } +
+
+ {category === '' ? + + : + + } + {account === '' ? + + : + + } +
+
+
+ {currentData.map((item: any) => ( + // show all transactions in the account and category + account === '' && category === '' ? ( + + ) : ( + // show all transactions in the account + account !== '' && category === '' ? ( + item.accountName === account ? ( + + ) : ( + <> + ) + ) : ( + // show all transactions in the category + account === '' && category !== '' ? ( + item.categoryName === category ? ( + + ) : ( + <> + ) + ) : ( + // show all transactions in the account and category + account !== '' && category !== '' ? ( + item.accountName === account && item.categoryName === category ? ( + + ) : ( + <> + ) + ) : ( + <> + ) + ) + ) + ) + ))} +
+
+
+ ) +} \ No newline at end of file diff --git a/src/widgets/Time.tsx b/src/widgets/Time.tsx index b994815..96a5d28 100644 --- a/src/widgets/Time.tsx +++ b/src/widgets/Time.tsx @@ -31,18 +31,20 @@ export const TimeWidget = (dateProps: dateProp) => { return ( <> -
( props.setOpenModal('default') )}>
{formattedTime}
-
- {weekday} -
-
- {date} +
+
+ {weekday} +
+
+ {date} +
setOpenModal(undefined)}>