diff --git a/frontend/src/MainLayout.tsx b/frontend/src/MainLayout.tsx index 9ddf7fc..d625e06 100644 --- a/frontend/src/MainLayout.tsx +++ b/frontend/src/MainLayout.tsx @@ -1,6 +1,6 @@ import { useUserContext } from './contexts/UserContext' import { Route, Switch } from 'react-router' -import { Link, useHistory } from 'react-router-dom' +import { Link, Redirect, useHistory } from 'react-router-dom' import { Dashboard } from './pages/Dashboard' import { NewUser } from './pages/NewUser' import { TransactionList } from './pages/TransactionList' @@ -38,7 +38,8 @@ export const MainLayout = () => { - + + )} diff --git a/frontend/src/contexts/UserContext.tsx b/frontend/src/contexts/UserContext.tsx index 3aa6c92..228534c 100644 --- a/frontend/src/contexts/UserContext.tsx +++ b/frontend/src/contexts/UserContext.tsx @@ -5,6 +5,7 @@ import { User } from '../types' import { useAppContext } from './AppContext' import { useEffect } from 'react' import { useRef } from 'react' +import axios from 'axios' type Props = { children: React.ReactNode @@ -48,17 +49,18 @@ export const UserContextProvider = ({ children }: Props) => { const handleLogin = async (username: string, password: string) => { try { - const { key } = await api.current.post( - '/dj-rest-auth/login/', + const res = await axios.post<{ key: string }>( + 'http://localhost:8000/dj-rest-auth/login/', { username, password, }, ) - if (!key) throw new Error('Problem logging in!') - window.localStorage.setItem('cash-stacks-token', key) + if (!res.data.key) throw new Error('Problem logging in!') + + window.localStorage.setItem('cash-stacks-token', res.data.key) + const user = await api.current.get(`/dj-rest-auth/user/`) - console.log('user', user) setUser(user) } catch (err) { message.error('Login Failed!') diff --git a/frontend/src/hooks/getMany/useAccounts.ts b/frontend/src/hooks/getMany/useAccounts.ts index 7b99941..d1bc343 100644 --- a/frontend/src/hooks/getMany/useAccounts.ts +++ b/frontend/src/hooks/getMany/useAccounts.ts @@ -1,4 +1,5 @@ import { Account } from '../../types' import { useGet } from '../util/useGet' -export const useAccounts = () => useGet(`/accounts/`) +export const useAccounts = () => + useGet(`/accounts/`, { mode: 'list' }) diff --git a/frontend/src/hooks/getMany/useStacks.ts b/frontend/src/hooks/getMany/useStacks.ts index 81477d5..66b1ca4 100644 --- a/frontend/src/hooks/getMany/useStacks.ts +++ b/frontend/src/hooks/getMany/useStacks.ts @@ -1,4 +1,4 @@ import { Stack } from '../../types' import { useGet } from '../util/useGet' -export const useStacks = () => useGet(`/stacks/`) +export const useStacks = () => useGet(`/stacks/`, { mode: 'list' }) diff --git a/frontend/src/hooks/getMany/useTransactions.ts b/frontend/src/hooks/getMany/useTransactions.ts index 031faa3..6d47633 100644 --- a/frontend/src/hooks/getMany/useTransactions.ts +++ b/frontend/src/hooks/getMany/useTransactions.ts @@ -1,5 +1,4 @@ import { Transaction } from '../../types' import { useGet } from '../util/useGet' -export const useTransactions = (accountId: string) => - useGet(`/transactions/`) +export const useTransactions = () => useGet(`/transactions/`) diff --git a/frontend/src/hooks/getOne/useAccount.ts b/frontend/src/hooks/getOne/useAccount.ts new file mode 100644 index 0000000..ed541f1 --- /dev/null +++ b/frontend/src/hooks/getOne/useAccount.ts @@ -0,0 +1,4 @@ +import { Account } from '../../types' +import { useGet } from '../util/useGet' + +export const useAccount = (id: string) => useGet(`/accounts/${id}/`) diff --git a/frontend/src/hooks/util/useGet.ts b/frontend/src/hooks/util/useGet.ts index bab732c..64b628d 100644 --- a/frontend/src/hooks/util/useGet.ts +++ b/frontend/src/hooks/util/useGet.ts @@ -1,16 +1,24 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { useAppContext } from '../../contexts/AppContext' -export const useGet = (path: string) => { +type Config = { + mode: 'list' +} + +export const useGet = (path: string, config?: Config) => { const appContext = useRef(useAppContext()) const [data, setData] = useState(null) const get = useCallback(async () => { const data = await appContext.current.get(path) if (!data) return - // @ts-ignore - setData(data.results) - }, [path]) + if (config?.mode === 'list') { + // @ts-ignore + setData(data.results) + } else { + setData(data) + } + }, [path, config]) useEffect(() => { get() diff --git a/frontend/src/layout/Page/index.tsx b/frontend/src/layout/Page/index.tsx new file mode 100644 index 0000000..f26258e --- /dev/null +++ b/frontend/src/layout/Page/index.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import './style.scss' + +type Props = { + children: React.ReactNode +} + +export const Page = ({ children }: Props) => { + return
{children}
+} diff --git a/frontend/src/layout/Page/style.scss b/frontend/src/layout/Page/style.scss new file mode 100644 index 0000000..d2d3ed6 --- /dev/null +++ b/frontend/src/layout/Page/style.scss @@ -0,0 +1,3 @@ +.dank-page { + padding: 1rem; +} diff --git a/frontend/src/pages/AccountList/index.tsx b/frontend/src/pages/AccountList/index.tsx index b746c1b..4dc1297 100644 --- a/frontend/src/pages/AccountList/index.tsx +++ b/frontend/src/pages/AccountList/index.tsx @@ -1,7 +1,13 @@ import { useAccounts } from '../../hooks/getMany/useAccounts' +import { Page } from '../../layout/Page' export const AccountList = () => { const accounts = useAccounts() - return
Account Count: {accounts.data?.length}
+ return ( + +

Account List

+

Count: {accounts.data?.length}

+
+ ) } diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index 2558ed5..5490831 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -1,19 +1,25 @@ import { FundBar } from '../../widgets/FundBar' -import { useStacks } from '../../hooks/getMany/useStacks' +import { Page } from '../../layout/Page' +import './style.scss' +import { useAccounts } from '../../hooks/getMany/useAccounts' export const Dashboard = () => { - const stacks = useStacks() - - if (!stacks.data) return
loading...
+ const accounts = useAccounts() + if (!accounts.data) return
loading...
return ( - <> +

Remaining Balances

-
- {stacks.data.map((stack, i) => ( - - ))} -
- + {accounts.data?.map((account) => ( +
+

{account.name}

+
+ {account.stacks.map((stack) => ( + + ))} +
+
+ ))} +
) } diff --git a/frontend/src/pages/Dashboard/style.scss b/frontend/src/pages/Dashboard/style.scss new file mode 100644 index 0000000..cfa50cf --- /dev/null +++ b/frontend/src/pages/Dashboard/style.scss @@ -0,0 +1,19 @@ +@import '../../scss/variables.scss'; + +.account-overview { + display: flex; + border: 1px solid $color-grey; + flex-direction: column; + align-items: center; + text-align: center; + margin: 1rem 0; + padding: 1rem; + background: $color-alt; + + .funds { + display: flex; + justify-content: center; + flex-direction: row; + flex-wrap: wrap; + } +} diff --git a/frontend/src/pages/TransactionList/index.tsx b/frontend/src/pages/TransactionList/index.tsx index 3e5e1da..649d96b 100644 --- a/frontend/src/pages/TransactionList/index.tsx +++ b/frontend/src/pages/TransactionList/index.tsx @@ -1,18 +1,26 @@ +import { useTransactions } from '../../hooks/getMany/useTransactions' +import { Page } from '../../layout/Page' import './style.scss' export const TransactionList = () => { + const transactions = useTransactions() + return ( - <> +

Transactions

+
- {[].map((account, i) => { + {transactions.data?.map((tx, i) => { return ( -
-

{account}

+
+

+ {tx.details}: ${tx.amount} +

+

on: {tx.created_at}

) })}
- + ) } diff --git a/frontend/src/pages/TransactionList/style.scss b/frontend/src/pages/TransactionList/style.scss index 127ed7b..4873858 100644 --- a/frontend/src/pages/TransactionList/style.scss +++ b/frontend/src/pages/TransactionList/style.scss @@ -1,21 +1,10 @@ +@import '../../scss/variables.scss'; + .transactions { - .column { - h3 { - text-align: center; - text-decoration: underline; - } - margin: 2ch; + .dank-transaction { + border: 1px solid $color-dark; + margin: 1rem 0; background: #fff1; - padding: 0 2ch 1ch; - border-radius: 1ch; - } - - .transaction-item { - display: flex; - flex-direction: row; - justify-content: space-between; - .details { - padding-left: 1ch; - } + padding: 1rem; } } diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index df6e57e..e030bed 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -20,6 +20,7 @@ export type Account = { details: string income: number expenses: number + stacks: Stack[] } export type Stack = { diff --git a/frontend/src/widgets/FundBar/index.tsx b/frontend/src/widgets/FundBar/index.tsx index 292fdb7..f92d138 100644 --- a/frontend/src/widgets/FundBar/index.tsx +++ b/frontend/src/widgets/FundBar/index.tsx @@ -1,27 +1,27 @@ import { Stack } from '../../types' import './style.scss' +import _ from 'lodash' type Props = { - col: number stack: Stack } -export const FundBar = ({ stack, col }: Props) => { - const amount = 0 - +export const FundBar = ({ stack }: Props) => { + const amount = _.sumBy(stack.transactions, 'amount') + console.log('amount', stack.id, amount) const max = stack.amount const current = max - amount const percent = Math.max(current / max, 0) const hue = percent * 120 return ( - <> +
console.log(`adding transaction to => ${stack.name}`)} >
{

{stack.name}

${Math.floor(current)} / ${max}
- +
) } diff --git a/frontend/src/widgets/FundBar/style.scss b/frontend/src/widgets/FundBar/style.scss index 61bb7a3..dd0aa25 100644 --- a/frontend/src/widgets/FundBar/style.scss +++ b/frontend/src/widgets/FundBar/style.scss @@ -1,32 +1,37 @@ +@import '../../scss/variables.scss'; + .fundbar { cursor: pointer; - border-radius: 1ch; text-align: center; - margin: auto 2ch 0 2ch; + margin: 1rem; + display: grid; + grid-template: 1fr / 1fr; - &.totals { + .totals { pointer-events: none; - margin-top: 2ch; + margin-top: 1rem; } h3 { margin: auto auto 0 auto; } - &.front { + .front { + grid-area: 1/1/2/2; + border-radius: 1ch; pointer-events: none; transition: all 0.2s ease-out; - border: 2px solid #222a; + border: 2px solid $color-dark; display: flex; flex-direction: column; padding: 2ch; text-shadow: 2px 2px #2223, -1px -1px #fffa; } - &.back { + .back { + grid-area: 1/1/2/2; background: #222; - + border-radius: 1ch; border: 4px solid #3334; - height: 50vh; } }