parent
1af8209b99
commit
2b94223389
35 changed files with 163 additions and 160 deletions
@ -1,31 +1,13 @@ |
||||
# mvp-django-react |
||||
# Cash Dash Stacks |
||||
|
||||
An MVP boilerplate for a django / react app. |
||||
- A simple way to track expenses |
||||
- cash budgeting in digital mode |
||||
|
||||
# Setup |
||||
# Ideas |
||||
|
||||
``` |
||||
python manage.py migrate |
||||
python manage.py createsuperuser --email admin@example.com --username admin --password whatever |
||||
``` |
||||
- put items in your wishlist and track savings to buy big-ticket items |
||||
- view spending trends |
||||
|
||||
# Boilerplate Features |
||||
# Todo |
||||
|
||||
- Authentication |
||||
- User Table (username, email, password) |
||||
|
||||
# Extras |
||||
|
||||
- dockerized |
||||
|
||||
# Frontend |
||||
|
||||
- [x] User context |
||||
- [x] auth api |
||||
- [ ] user crud api (new user flow) |
||||
|
||||
# Backend |
||||
|
||||
- user CRUD |
||||
- login / logout / forgot password |
||||
- serve static index (prod) |
||||
https://github.com/dank-inc/cash-stacks/projects |
||||
|
@ -0,0 +1,38 @@ |
||||
import { useUserContext } from './contexts/UserContext' |
||||
import { Route, Switch } from 'react-router' |
||||
import { Link } from 'react-router-dom' |
||||
import { Dashboard } from './pages/Dashboard' |
||||
import { NewUser } from './pages/NewUser' |
||||
import { TransactionList } from './pages/TransactionList' |
||||
import { AccountForm } from './forms/AccountForm' |
||||
import { Login } from './pages/Login' |
||||
import { AppHeader } from './layout/AppHeader' |
||||
import { AppFooter } from './layout/AppFooter' |
||||
|
||||
export const CoreLayout = () => { |
||||
const { user } = useUserContext() |
||||
|
||||
if (!user) return <Login /> |
||||
|
||||
return ( |
||||
<div className="app"> |
||||
<AppHeader> |
||||
<Link to="/">Home</Link> |
||||
<Link to="/select">Select Budget</Link> |
||||
<Link to="/accounts">Budget Details</Link> |
||||
<Link to="/transactions">Transactions</Link> |
||||
<Link to="/new">New User</Link> |
||||
</AppHeader> |
||||
|
||||
<Switch> |
||||
<Route path="/users/new" component={NewUser} /> |
||||
<Route path="/transactions" component={TransactionList} /> |
||||
<Route path="/accounts/new" component={AccountForm} /> |
||||
<Route path="/accounts" component={AccountForm} /> |
||||
<Route path="/" component={Dashboard} /> |
||||
</Switch> |
||||
|
||||
<AppFooter /> |
||||
</div> |
||||
) |
||||
} |
@ -1,39 +0,0 @@ |
||||
import { useUserContext } from '../contexts/UserContext' |
||||
import { Route, Switch } from 'react-router' |
||||
import { Link } from 'react-router-dom' |
||||
import { Dashboard } from './pages/Dashboard' |
||||
import { UserForm } from './components/UserForm' |
||||
import { TransactionList } from './components/TransactionList' |
||||
import { AccountForm } from './components/AccountForm' |
||||
import { Login } from './components/Login' |
||||
import { AppHeader } from './layout/AppHeader' |
||||
import { AppFooter } from './layout/AppFooter' |
||||
|
||||
export const CoreLayout = () => { |
||||
const { user, selectedAccount } = useUserContext() |
||||
|
||||
if (!user) return <Login /> |
||||
|
||||
return ( |
||||
<div className="app"> |
||||
<AppHeader> |
||||
<Link to="/">Home</Link> |
||||
<Link to="/select">Select Budget</Link> |
||||
<Link to="/account">Budget Details</Link> |
||||
<Link to="/details">Transactions</Link> |
||||
<Link to="/user">Profile</Link> |
||||
</AppHeader> |
||||
|
||||
<Switch> |
||||
<Route path="/user" component={UserForm} /> |
||||
<Route path="/details" component={TransactionList} /> |
||||
<Route path="/account/new" component={AccountForm} /> |
||||
<Route path="/account" component={AccountForm} /> |
||||
<Route path="/" component={Dashboard} /> |
||||
</Switch> |
||||
|
||||
<AppFooter /> |
||||
{/* {showingModal && <TransactionModal account={account} />} */} |
||||
</div> |
||||
) |
||||
} |
@ -1,21 +0,0 @@ |
||||
import { FundBar } from '../components/FundBar' |
||||
import { usePromise } from '@dank-inc/use-get' |
||||
import { useAppContext } from '../../contexts/AppContext' |
||||
|
||||
export const Dashboard = () => { |
||||
const { api } = useAppContext() |
||||
const stacks = usePromise(api.getStacks()) |
||||
|
||||
if (stacks.loading || !stacks.data) return <div>loading...</div> |
||||
|
||||
return ( |
||||
<> |
||||
<h1>Remaining Balances</h1> |
||||
<div className="funds"> |
||||
{stacks.data.map((stack, i) => ( |
||||
<FundBar key={stack.id} stack={stack} col={i + 1} /> |
||||
))} |
||||
</div> |
||||
</> |
||||
) |
||||
} |
@ -0,0 +1,13 @@ |
||||
import { Button as AntButton, ButtonProps } from 'antd' |
||||
import React from 'react' |
||||
import './style.scss' |
||||
|
||||
type Props = ButtonProps |
||||
|
||||
export const Button = ({ children, htmlType }: Props) => { |
||||
return ( |
||||
<AntButton className="dank-button" htmlType={htmlType}> |
||||
{children} |
||||
</AntButton> |
||||
) |
||||
} |
@ -0,0 +1,4 @@ |
||||
.dank-button { |
||||
cursor: pointer; |
||||
// shit here |
||||
} |
@ -0,0 +1,8 @@ |
||||
import { Form as AntForm, FormProps } from 'antd' |
||||
import './style.scss' |
||||
|
||||
type Props = FormProps |
||||
|
||||
export const Form = ({ children }: Props) => { |
||||
return <AntForm className="dank-form">{children}</AntForm> |
||||
} |
@ -0,0 +1,14 @@ |
||||
import React from 'react' |
||||
import './style.scss' |
||||
|
||||
type Props = { |
||||
title: string |
||||
type: 'success' | 'error' |
||||
children: React.ReactNode |
||||
} |
||||
|
||||
export const Toast = (props: Props) => { |
||||
// show me a toast
|
||||
|
||||
return null |
||||
} |
@ -1,4 +1,4 @@ |
||||
.status { |
||||
.dank-toast { |
||||
position: absolute; |
||||
left: 1ch; |
||||
bottom: 4ch; |
@ -0,0 +1,5 @@ |
||||
import { Stack } from '../../types' |
||||
import { useGet } from '../util/useGet' |
||||
|
||||
export const useStacks = (accountId: string) => |
||||
useGet<Stack[]>(`/accounts/${accountId}/stacks`) |
@ -1,4 +1,4 @@ |
||||
import { useUserContext } from '../../../contexts/UserContext' |
||||
import { useUserContext } from '../../contexts/UserContext' |
||||
|
||||
import './style.scss' |
||||
|
@ -0,0 +1,19 @@ |
||||
import { FundBar } from '../../widgets/FundBar' |
||||
import { useStacks } from '../../hooks/getMany/useStacks' |
||||
|
||||
export const Dashboard = () => { |
||||
const stacks = useStacks('') |
||||
|
||||
if (!stacks.data) return <div>loading...</div> |
||||
|
||||
return ( |
||||
<> |
||||
<h1>Remaining Balances</h1> |
||||
<div className="funds"> |
||||
{stacks.data.map((stack, i) => ( |
||||
<FundBar key={stack.id} stack={stack} col={i + 1} /> |
||||
))} |
||||
</div> |
||||
</> |
||||
) |
||||
} |
@ -1,6 +1,7 @@ |
||||
import { Button, Form, Input } from 'antd' |
||||
import { useForm } from 'antd/lib/form/Form' |
||||
import { useUserContext } from '../../contexts/UserContext' |
||||
import './style.scss' |
||||
|
||||
type Credentials = { |
||||
username: string |
@ -1,4 +1,4 @@ |
||||
import '../../scss/transaction-list.scss' |
||||
import './style.scss' |
||||
|
||||
export const TransactionList = () => { |
||||
return ( |
@ -1,5 +1,5 @@ |
||||
import { Stack } from '../../types' |
||||
import '../../scss/fund-bar.scss' |
||||
import './style.scss' |
||||
|
||||
type Props = { |
||||
col: number |
Loading…
Reference in new issue