stuff, with a side of things
This commit is contained in:
parent
c62f88953e
commit
8e7fc05cd1
21663
frontend/package-lock.json
generated
21663
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -6,11 +6,13 @@
|
||||||
"@dank-inc/data-buddy": "^0.2.0",
|
"@dank-inc/data-buddy": "^0.2.0",
|
||||||
"@testing-library/react": "^11.1.0",
|
"@testing-library/react": "^11.1.0",
|
||||||
"@testing-library/user-event": "^12.1.10",
|
"@testing-library/user-event": "^12.1.10",
|
||||||
|
"@types/lodash": "^4.14.171",
|
||||||
"@types/node": "^12.0.0",
|
"@types/node": "^12.0.0",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@types/react-dom": "^17.0.0",
|
"@types/react-dom": "^17.0.0",
|
||||||
"antd": "^4.14.0",
|
"antd": "^4.14.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"node-sass": "^4.0.0",
|
"node-sass": "^4.0.0",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
|
|
|
@ -8,7 +8,7 @@ import './app.scss'
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AppContextProvider>
|
<AppContextProvider baseURL="/api">
|
||||||
<UserContextProvider>
|
<UserContextProvider>
|
||||||
<CoreLayout />
|
<CoreLayout />
|
||||||
</UserContextProvider>
|
</UserContextProvider>
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import { DataBuddy } from '@dank-inc/data-buddy'
|
|
||||||
import { Account, Stack, Transaction, User } from '../../types'
|
|
||||||
|
|
||||||
export const users = new DataBuddy<User>([
|
|
||||||
{
|
|
||||||
id: 'mock-user',
|
|
||||||
name: 'TestUser42',
|
|
||||||
email: 'testuser@email.com',
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
export const accounts = new DataBuddy<Account>([
|
|
||||||
{
|
|
||||||
id: 'home',
|
|
||||||
name: 'Home Expenses',
|
|
||||||
details: 'ya',
|
|
||||||
users: ['42'],
|
|
||||||
income: 1000,
|
|
||||||
expenses: 500,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
export const stacks = new DataBuddy<Stack>([
|
|
||||||
{
|
|
||||||
id: 'ccrap',
|
|
||||||
name: 'crap',
|
|
||||||
account: 'asdf',
|
|
||||||
amount: 200,
|
|
||||||
details: 'for all my crap!',
|
|
||||||
transactions: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'shit',
|
|
||||||
name: 'shit',
|
|
||||||
account: 'home',
|
|
||||||
amount: 500,
|
|
||||||
details: 'for all my shit!',
|
|
||||||
transactions: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'poo',
|
|
||||||
name: 'poo',
|
|
||||||
account: 'home',
|
|
||||||
amount: 800,
|
|
||||||
details: 'for all my poo!',
|
|
||||||
transactions: [],
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
export const transactions = new DataBuddy<Transaction>([])
|
|
|
@ -1,8 +1,7 @@
|
||||||
import Axios, { AxiosInstance } from 'axios'
|
import Axios, { AxiosInstance } from 'axios'
|
||||||
import { Account, Password, Stack, Transaction, User, uuid } from '../types'
|
import { Account, Password, Stack, Transaction, User } from '../types'
|
||||||
import { JWT, setJWT, wipeJWT } from '../utils/jwt'
|
import { JWT, setJWT, wipeJWT } from '../utils/jwt'
|
||||||
import { DataBuddy } from '@dank-inc/data-buddy'
|
import { DataBuddy } from '@dank-inc/data-buddy'
|
||||||
import { users, accounts, stacks, transactions } from './data'
|
|
||||||
|
|
||||||
export type ApiParams = {
|
export type ApiParams = {
|
||||||
baseURL?: string
|
baseURL?: string
|
||||||
|
@ -21,24 +20,10 @@ export interface Api {
|
||||||
export class Api {
|
export class Api {
|
||||||
constructor({ mock, baseURL }: ApiParams) {
|
constructor({ mock, baseURL }: ApiParams) {
|
||||||
this.mock = mock
|
this.mock = mock
|
||||||
this.users = users
|
|
||||||
this.accounts = accounts
|
|
||||||
this.stacks = stacks
|
|
||||||
this.transactions = transactions
|
|
||||||
this.axios = Axios.create({ baseURL })
|
this.axios = Axios.create({ baseURL })
|
||||||
}
|
}
|
||||||
|
|
||||||
login = async (name: string, password: string): Promise<JWT> => {
|
login = async (name: string, password: string): Promise<JWT> => {
|
||||||
if (this.mock) {
|
|
||||||
const jwt = {
|
|
||||||
id: 'mock-user',
|
|
||||||
token: 'token-token-token',
|
|
||||||
exp: +new Date(),
|
|
||||||
}
|
|
||||||
setJWT(jwt)
|
|
||||||
return jwt
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data } = await this.axios.post<JWT>(`/dj-rest-auth/login/`, {
|
const { data } = await this.axios.post<JWT>(`/dj-rest-auth/login/`, {
|
||||||
name,
|
name,
|
||||||
password,
|
password,
|
||||||
|
@ -49,18 +34,15 @@ export class Api {
|
||||||
}
|
}
|
||||||
|
|
||||||
logout = () => {
|
logout = () => {
|
||||||
if (this.mock) return true
|
|
||||||
wipeJWT()
|
wipeJWT()
|
||||||
}
|
}
|
||||||
|
|
||||||
getUser = async (id: uuid) => {
|
getUser = async (id: string) => {
|
||||||
if (this.mock) return this.users.getOne(id)
|
|
||||||
const { data } = await this.axios.get<User>(`users/${id}`)
|
const { data } = await this.axios.get<User>(`users/${id}`)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUser = async (id: uuid, body: Partial<User>) => {
|
updateUser = async (id: string, body: Partial<User>) => {
|
||||||
if (this.mock) return this.users.update(id, body)
|
|
||||||
const { data } = await this.axios.patch<User>(`users/${id}`, body)
|
const { data } = await this.axios.patch<User>(`users/${id}`, body)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
@ -71,17 +53,15 @@ export class Api {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccounts = async () => {
|
getAccounts = async () => {
|
||||||
if (this.mock) return this.accounts.get()
|
|
||||||
const { data } = await this.axios.get<Account[]>('accounts')
|
const { data } = await this.axios.get<Account[]>('accounts')
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccount = async (id: uuid) => {
|
getAccount = async (id: string) => {
|
||||||
if (this.mock) return this.accounts.getOne(id)
|
|
||||||
const data = await this.axios.get<Account>(`accounts/${id}`)
|
const data = await this.axios.get<Account>(`accounts/${id}`)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
updateAccount = async (id: uuid, body: Partial<Account>) => {
|
updateAccount = async (id: string, body: Partial<Account>) => {
|
||||||
const { data } = await this.axios.patch<Account>(`accounts/${id}`, body)
|
const { data } = await this.axios.patch<Account>(`accounts/${id}`, body)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
@ -92,12 +72,11 @@ export class Api {
|
||||||
deleteAccount = async () => {}
|
deleteAccount = async () => {}
|
||||||
|
|
||||||
getStacks = async (): Promise<Stack[]> => {
|
getStacks = async (): Promise<Stack[]> => {
|
||||||
if (this.mock) return this.stacks.get()
|
|
||||||
const { data } = await this.axios.get('stacks')
|
const { data } = await this.axios.get('stacks')
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStack = async (id: uuid, body: Partial<Stack>) => {
|
updateStack = async (id: string, body: Partial<Stack>) => {
|
||||||
const { data } = await this.axios.patch<Stack>(`stacks/${id}`, body)
|
const { data } = await this.axios.patch<Stack>(`stacks/${id}`, body)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
@ -106,12 +85,11 @@ export class Api {
|
||||||
deleteStack = async () => {}
|
deleteStack = async () => {}
|
||||||
|
|
||||||
getTransactions = async () => {
|
getTransactions = async () => {
|
||||||
if (this.mock) return this.transactions.get()
|
|
||||||
const { data } = await this.axios.get('transactions')
|
const { data } = await this.axios.get('transactions')
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTransaction = async (id: uuid, body: Partial<Transaction>) => {
|
updateTransaction = async (id: string, body: Partial<Transaction>) => {
|
||||||
const { data } = await this.axios.patch<Transaction>(
|
const { data } = await this.axios.patch<Transaction>(
|
||||||
`transactions/${id}`,
|
`transactions/${id}`,
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Axios, { AxiosResponse } from 'axios'
|
import axios, { AxiosResponse } from 'axios'
|
||||||
import React, { createContext, useContext } from 'react'
|
import React, { createContext, useContext } from 'react'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -6,7 +6,7 @@ type Props = {
|
||||||
baseURL?: string
|
baseURL?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = {
|
type AppContextInterface = {
|
||||||
get: <T>(path: string) => Promise<T>
|
get: <T>(path: string) => Promise<T>
|
||||||
patch: <T>(path: string, body: Partial<T>) => Promise<T>
|
patch: <T>(path: string, body: Partial<T>) => Promise<T>
|
||||||
post: <T, R = T>(path: string, body: Partial<T>) => Promise<R>
|
post: <T, R = T>(path: string, body: Partial<T>) => Promise<R>
|
||||||
|
@ -14,30 +14,35 @@ type Context = {
|
||||||
destroy: (path: string) => Promise<string>
|
destroy: (path: string) => Promise<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppContext = createContext<Context | null>(null)
|
const AppContext = createContext<AppContextInterface | null>(null)
|
||||||
|
|
||||||
export const AppContextProvider = ({ children, baseURL }: Props) => {
|
export const AppContextProvider = ({ children, baseURL }: Props) => {
|
||||||
const axios = Axios.create({ baseURL })
|
const api = axios.create({ baseURL })
|
||||||
|
|
||||||
|
api.interceptors.request.use((config) => {
|
||||||
|
config.url += '?format=json'
|
||||||
|
return config
|
||||||
|
})
|
||||||
|
|
||||||
async function get<T>(path: string): Promise<T> {
|
async function get<T>(path: string): Promise<T> {
|
||||||
const res = await axios.get<T>(path)
|
const res = await api.get<T>(path)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
async function patch<T>(path: string, body: Partial<T>) {
|
async function patch<T>(path: string, body: Partial<T>) {
|
||||||
const res = await axios.patch<T>(path, body)
|
const res = await api.patch<T>(path, body)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
async function post<T, R = T>(path: string, body: Partial<T>) {
|
async function post<T, R = T>(path: string, body: Partial<T>) {
|
||||||
const res = await axios.post<T, AxiosResponse<R>>(path, body)
|
const res = await api.post<T, AxiosResponse<R>>(path, body)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
async function create<T>(path: string, body: Partial<T>) {
|
async function create<T>(path: string, body: Partial<T>) {
|
||||||
// unauthed POST
|
// unauthed POST
|
||||||
const res = await axios.post<T>(path, body)
|
const res = await api.post<T>(path, body)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
async function destroy(path: string) {
|
async function destroy(path: string) {
|
||||||
const res = await axios.delete<string>(path)
|
const res = await api.delete<string>(path)
|
||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { createContext, useContext, useState } from 'react'
|
import React, { createContext, useContext, useState } from 'react'
|
||||||
import { message } from 'antd'
|
import { message } from 'antd'
|
||||||
import { useHistory } from 'react-router'
|
import { useHistory } from 'react-router'
|
||||||
import { Account, User, uuid } from '../types'
|
import { User } from '../types'
|
||||||
import { useAppContext } from './AppContext'
|
import { useAppContext } from './AppContext'
|
||||||
import { logOut } from '../api'
|
import { logOut } from '../api'
|
||||||
|
|
||||||
|
@ -11,11 +11,8 @@ type Props = {
|
||||||
|
|
||||||
type Context = {
|
type Context = {
|
||||||
user: User | null
|
user: User | null
|
||||||
accounts: Account[] | null
|
|
||||||
selectedAccount: Account | null
|
|
||||||
handleLogin: (name: string, password: string) => void
|
handleLogin: (name: string, password: string) => void
|
||||||
handleLogout: () => void
|
handleLogout: () => void
|
||||||
handleSelectAccount: (id: uuid) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserContext = createContext<Context | null>(null)
|
const UserContext = createContext<Context | null>(null)
|
||||||
|
@ -25,10 +22,10 @@ export const UserContextProvider = ({ children }: Props) => {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
|
|
||||||
const [user, setUser] = useState<User | null>(null)
|
const [user, setUser] = useState<User | null>(null)
|
||||||
const [accounts, setAccounts] = useState<Account[] | null>(null)
|
|
||||||
const [selectedAccount, setSelectedAccount] = useState<Account | null>(null)
|
|
||||||
|
|
||||||
const handleLogin = async (name: string, password: string) => {
|
const handleLogin = async (name: string, password: string) => {
|
||||||
|
console.log('logging in?', name, password)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { id } = await api.post<any, { id: string }>('/login', {
|
const { id } = await api.post<any, { id: string }>('/login', {
|
||||||
name,
|
name,
|
||||||
|
@ -40,9 +37,6 @@ export const UserContextProvider = ({ children }: Props) => {
|
||||||
if (!user) message.error(`Couldn't find user`)
|
if (!user) message.error(`Couldn't find user`)
|
||||||
setUser(user)
|
setUser(user)
|
||||||
|
|
||||||
const accounts = await api.get<Account[]>('/accounts')
|
|
||||||
setAccounts(accounts)
|
|
||||||
|
|
||||||
message.success(`logged in as ${user?.name}`, 0.5)
|
message.success(`logged in as ${user?.name}`, 0.5)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
message.error('Login Failed!')
|
message.error('Login Failed!')
|
||||||
|
@ -56,20 +50,12 @@ export const UserContextProvider = ({ children }: Props) => {
|
||||||
history.push('/')
|
history.push('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSelectAccount = (id: string) => {
|
|
||||||
const account = accounts?.find((account) => account.id === id)
|
|
||||||
if (account) setSelectedAccount(account)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserContext.Provider
|
<UserContext.Provider
|
||||||
value={{
|
value={{
|
||||||
user,
|
user,
|
||||||
accounts,
|
|
||||||
handleLogin,
|
handleLogin,
|
||||||
handleLogout,
|
handleLogout,
|
||||||
selectedAccount,
|
|
||||||
handleSelectAccount,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { Button as AntButton, ButtonProps } from 'antd'
|
import { Button as AntButton, ButtonProps } from 'antd'
|
||||||
import React from 'react'
|
|
||||||
import './style.scss'
|
import './style.scss'
|
||||||
|
|
||||||
type Props = ButtonProps
|
type Props = ButtonProps
|
||||||
|
|
||||||
export const Button = ({ children, htmlType }: Props) => {
|
export const Button = ({ children, ...props }: Props) => {
|
||||||
return (
|
return (
|
||||||
<AntButton className="dank-button" htmlType={htmlType}>
|
<AntButton className="dank-button" {...props}>
|
||||||
{children}
|
{children}
|
||||||
</AntButton>
|
</AntButton>
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,10 @@ import './style.scss'
|
||||||
|
|
||||||
type Props = FormProps
|
type Props = FormProps
|
||||||
|
|
||||||
export const Form = ({ children }: Props) => {
|
export const Form = ({ children, ...props }: Props) => {
|
||||||
return <AntForm className="dank-form">{children}</AntForm>
|
return (
|
||||||
|
<AntForm className="dank-form" {...props}>
|
||||||
|
{children}
|
||||||
|
</AntForm>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Account } from '../../types'
|
import { Account } from '../../types'
|
||||||
import { useGet } from '../util/useGet'
|
import { useGet } from '../util/useGet'
|
||||||
|
|
||||||
export const useAccounts = (userId: string) =>
|
export const useAccounts = () => useGet<Account[]>(`/accounts`)
|
||||||
useGet<Account[]>(`/users/${userId}/accounts`)
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Stack } from '../../types'
|
import { Stack } from '../../types'
|
||||||
import { useGet } from '../util/useGet'
|
import { useGet } from '../util/useGet'
|
||||||
|
|
||||||
export const useStacks = (accountId: string) =>
|
export const useStacks = (accountId: string) => useGet<Stack[]>(`/stacks`)
|
||||||
useGet<Stack[]>(`/accounts/${accountId}/stacks`)
|
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { useAppContext } from '../../contexts/AppContext'
|
import { useAppContext } from '../../contexts/AppContext'
|
||||||
|
|
||||||
type Res<T> = {
|
|
||||||
data: T
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useGet = <T>(path: string) => {
|
export const useGet = <T>(path: string) => {
|
||||||
const appContext = useRef(useAppContext())
|
const appContext = useRef(useAppContext())
|
||||||
const [data, setData] = useState<T | null>(null)
|
const [data, setData] = useState<T | null>(null)
|
||||||
|
|
||||||
const get = useCallback(async () => {
|
const get = useCallback(async () => {
|
||||||
// if (appContext.current.mock) return setData(mockGet[path]?.() || null)
|
const data = await appContext.current.get<T>(path)
|
||||||
|
|
||||||
const data = await appContext.current.get<Res<T>>(path)
|
|
||||||
if (!data) return
|
if (!data) return
|
||||||
|
|
||||||
setData(data.data)
|
setData(data)
|
||||||
}, [path])
|
}, [path])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { FundBar } from '../../widgets/FundBar'
|
||||||
import { useStacks } from '../../hooks/getMany/useStacks'
|
import { useStacks } from '../../hooks/getMany/useStacks'
|
||||||
|
|
||||||
export const Dashboard = () => {
|
export const Dashboard = () => {
|
||||||
const stacks = useStacks('')
|
const stacks = useStacks('42')
|
||||||
|
|
||||||
if (!stacks.data) return <div>loading...</div>
|
if (!stacks.data) return <div>loading...</div>
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,33 @@
|
||||||
import { Input } from 'antd'
|
import { Input } from 'antd'
|
||||||
import FormItem from 'antd/lib/form/FormItem'
|
import FormItem from 'antd/lib/form/FormItem'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { User } from '../../types'
|
|
||||||
import { useUserContext } from '../../contexts/UserContext'
|
|
||||||
import { Form } from '../../elements/Form'
|
import { Form } from '../../elements/Form'
|
||||||
import { Button } from '../../elements/Button'
|
import { Button } from '../../elements/Button'
|
||||||
import { useForm } from 'antd/lib/form/Form'
|
import { useForm } from 'antd/lib/form/Form'
|
||||||
|
import { useAppContext } from '../../contexts/AppContext'
|
||||||
|
import { useStacks } from '../../hooks/getMany/useStacks'
|
||||||
|
|
||||||
type FormValues = Pick<User, 'name'> & { password: string }
|
type FormValues = { email: string; password: string }
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const userContext = useUserContext()
|
const appContext = useAppContext()
|
||||||
|
const stacks = useStacks('')
|
||||||
|
|
||||||
const [form] = useForm<FormValues>()
|
const [form] = useForm<FormValues>()
|
||||||
|
|
||||||
const handleFinish = ({ name, password }: FormValues) => {
|
const handleFinish = async ({ email, password }: FormValues) => {
|
||||||
userContext.handleLogin(name, password)
|
const res = await appContext.post('/dj-rest-auth/login', {
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
})
|
||||||
|
console.log(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="login">
|
<div className="login">
|
||||||
<Form onFinish={handleFinish} form={form}>
|
<Form onFinish={handleFinish} form={form}>
|
||||||
<h1>Log In</h1>
|
<h1>Log In</h1>
|
||||||
<FormItem label="Username" name="username">
|
<FormItem label="email" name="email">
|
||||||
<Input />
|
<Input />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="Password" name="password">
|
<FormItem label="Password" name="password">
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
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
|
|
||||||
password: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Login = () => {
|
|
||||||
const { handleLogin } = useUserContext()
|
|
||||||
const [form] = useForm<Credentials>()
|
|
||||||
|
|
||||||
const handleSubmit = ({ username, password }: Credentials) => {
|
|
||||||
handleLogin(username, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form form={form} onFinish={handleSubmit}>
|
|
||||||
<Form.Item label="username" name="username">
|
|
||||||
<Input />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="password" name="password">
|
|
||||||
<Input type="password" />
|
|
||||||
</Form.Item>
|
|
||||||
<Button type="primary" htmlType="submit">
|
|
||||||
Login!
|
|
||||||
</Button>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ export const NewUser = () => {
|
||||||
const [form] = Form.useForm<NewUserForm>()
|
const [form] = Form.useForm<NewUserForm>()
|
||||||
|
|
||||||
const handleFinish = (user: NewUserForm) => {
|
const handleFinish = (user: NewUserForm) => {
|
||||||
console.log('Asdfdas')
|
|
||||||
if (user.password1 !== user.password2) {
|
if (user.password1 !== user.password2) {
|
||||||
message.error('passwords do not match')
|
message.error('passwords do not match')
|
||||||
return
|
return
|
||||||
|
@ -20,29 +19,23 @@ export const NewUser = () => {
|
||||||
axios.post(`/dj-rest-auth/registration/`, user)
|
axios.post(`/dj-rest-auth/registration/`, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('ASDFUASDJF')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Form form={form} onFinish={handleFinish}>
|
||||||
<Layout.Content>
|
<Form.Item label="username" name="username">
|
||||||
<Form form={form} onFinish={handleFinish}>
|
<Input></Input>
|
||||||
<Form.Item label="username" name="username">
|
</Form.Item>
|
||||||
<Input></Input>
|
<Form.Item label="email" name="email">
|
||||||
</Form.Item>
|
<Input type="email"></Input>
|
||||||
<Form.Item label="email" name="email">
|
</Form.Item>
|
||||||
<Input type="email"></Input>
|
<Form.Item label="password" name="password1">
|
||||||
</Form.Item>
|
<Input minLength={8}></Input>
|
||||||
<Form.Item label="password" name="password1">
|
</Form.Item>
|
||||||
<Input minLength={8}></Input>
|
<Form.Item label="confirm" name="password2">
|
||||||
</Form.Item>
|
<Input></Input>
|
||||||
<Form.Item label="confirm" name="password2">
|
</Form.Item>
|
||||||
<Input></Input>
|
<Button type="primary" htmlType="submit">
|
||||||
</Form.Item>
|
Create
|
||||||
<Button type="primary" htmlType="submit">
|
</Button>
|
||||||
Create
|
</Form>
|
||||||
</Button>
|
|
||||||
</Form>
|
|
||||||
</Layout.Content>
|
|
||||||
</Layout>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
export type uuid = string
|
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
id: uuid
|
id: string
|
||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
// password: string
|
// password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Account = {
|
export type Account = {
|
||||||
id: uuid
|
id: string
|
||||||
users?: uuid[]
|
users?: string[]
|
||||||
name: string
|
name: string
|
||||||
details: string
|
details: string
|
||||||
income: number
|
income: number
|
||||||
|
@ -17,8 +15,8 @@ export type Account = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Stack = {
|
export type Stack = {
|
||||||
id: uuid
|
id: string
|
||||||
account: uuid //'38485982-87f3-4a11-a963-2202983809e3'
|
account: string //'38485982-87f3-4a11-a963-2202983809e3'
|
||||||
name: string // 'House Fund'
|
name: string // 'House Fund'
|
||||||
details: string //'buy furniture'
|
details: string //'buy furniture'
|
||||||
amount: number // '200.00'
|
amount: number // '200.00'
|
||||||
|
@ -26,8 +24,8 @@ export type Stack = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Transaction = {
|
export type Transaction = {
|
||||||
id: uuid
|
id: string
|
||||||
stack: uuid // '0058cece-3ff3-4ee1-b71d-075a0bc73bc0'
|
stack: string // '0058cece-3ff3-4ee1-b71d-075a0bc73bc0'
|
||||||
details: string // 'by ghetto couch off Kijiji'
|
details: string // 'by ghetto couch off Kijiji'
|
||||||
amount: number // '30.44'
|
amount: number // '30.44'
|
||||||
created_at: string // '2021-04-15T00:02:45.096071Z'
|
created_at: string // '2021-04-15T00:02:45.096071Z'
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { message } from 'antd'
|
import { message } from 'antd'
|
||||||
import { useUserContext } from '../../contexts/UserContext'
|
|
||||||
|
|
||||||
import './style.scss'
|
import './style.scss'
|
||||||
import { Button } from '../../elements/Button'
|
import { Button } from '../../elements/Button'
|
||||||
|
import { useAccounts } from '../../hooks/getMany/useAccounts'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
selectProfile: (id: string) => void
|
selectProfile: (id: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AccountSelect = ({ selectProfile }: Props) => {
|
export const AccountSelect = ({ selectProfile }: Props) => {
|
||||||
const { accounts } = useUserContext()
|
const accounts = useAccounts()
|
||||||
|
|
||||||
const handleSelect = (id: string) => {
|
const handleSelect = (id: string) => {
|
||||||
selectProfile(id)
|
selectProfile(id)
|
||||||
|
@ -21,16 +20,14 @@ export const AccountSelect = ({ selectProfile }: Props) => {
|
||||||
<>
|
<>
|
||||||
<h1>Select Account</h1>
|
<h1>Select Account</h1>
|
||||||
<div className="account-select">
|
<div className="account-select">
|
||||||
{accounts?.length
|
{accounts.data?.map((account) => (
|
||||||
? accounts.map((account) => (
|
<Button
|
||||||
<Button
|
key={`account-${account.name}`}
|
||||||
key={`account-${account.name}`}
|
onClick={() => handleSelect(account.id)}
|
||||||
onClick={() => handleSelect(account.id)}
|
>
|
||||||
>
|
{account.name}
|
||||||
{account.name}
|
</Button>
|
||||||
</Button>
|
))}
|
||||||
))
|
|
||||||
: ''}
|
|
||||||
<Link to="/account/new">Create New Budget!</Link>
|
<Link to="/account/new">Create New Budget!</Link>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1784,6 +1784,11 @@
|
||||||
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
|
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
|
||||||
"version" "0.0.29"
|
"version" "0.0.29"
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.171":
|
||||||
|
"integrity" "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg=="
|
||||||
|
"resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz"
|
||||||
|
"version" "4.14.171"
|
||||||
|
|
||||||
"@types/minimatch@*":
|
"@types/minimatch@*":
|
||||||
"integrity" "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
"integrity" "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
||||||
"resolved" "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz"
|
"resolved" "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz"
|
||||||
|
@ -4164,11 +4169,6 @@
|
||||||
"resolved" "https://registry.npmjs.org/date-fns/-/date-fns-2.21.0.tgz"
|
"resolved" "https://registry.npmjs.org/date-fns/-/date-fns-2.21.0.tgz"
|
||||||
"version" "2.21.0"
|
"version" "2.21.0"
|
||||||
|
|
||||||
"dayjs@^1.8.30":
|
|
||||||
"integrity" "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw=="
|
|
||||||
"resolved" "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz"
|
|
||||||
"version" "1.10.4"
|
|
||||||
|
|
||||||
"debug@^2.2.0":
|
"debug@^2.2.0":
|
||||||
"integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
|
"integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
|
||||||
"resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
|
"resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
users:
|
users:
|
||||||
- name: elijah
|
- name: elijah
|
||||||
password: toffee15
|
password: toffee15
|
||||||
- name: toffee
|
- name: ievgen
|
||||||
|
password: toffee15
|
||||||
|
- name: tanner
|
||||||
password: toffee15
|
password: toffee15
|
||||||
|
|
||||||
accounts:
|
accounts:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user