Merge branch 'main' of github.com:dank-inc/mvp-django-react into main

This commit is contained in:
Elijah Lucian 2021-04-14 18:17:09 -06:00
commit 87d8d8e815
8 changed files with 59 additions and 91 deletions

View File

@ -20,11 +20,9 @@ python manage.py createsuperuser --email admin@example.com --username admin --pa
# Frontend # Frontend
- [x] useGet hook
- [x] User context - [x] User context
- [x] auth api - [x] auth api
- [ ] user crud api (new user flow) - [ ] user crud api (new user flow)
- [ ] socket hook
# Backend # Backend

View File

@ -1,14 +1,22 @@
import { BrowserRouter } from 'react-router-dom' import { BrowserRouter } from 'react-router-dom'
import { UserContextProvider } from './contexts/UserContext' import { UserContextProvider } from './contexts/UserContext'
import { CoreLayout } from './app/CoreLayout' import { CoreLayout } from './app/CoreLayout'
import { AppContextProvider } from './contexts/AppContext'
import { Api } from './api'
import { users } from './api/data/users'
import './scss/app.scss' import './scss/app.scss'
const App = () => { const App = () => {
const api = new Api({ mock: true, users })
return ( return (
<BrowserRouter> <BrowserRouter>
<UserContextProvider> <AppContextProvider api={api}>
<CoreLayout /> <UserContextProvider>
</UserContextProvider> <CoreLayout />
</UserContextProvider>
</AppContextProvider>
</BrowserRouter> </BrowserRouter>
) )
} }

View File

@ -1,7 +0,0 @@
import { User } from '../../types'
export const mockUser: User = {
id: '4242-4242-4242-4242',
username: 'TestUser42',
email: 'testuser@email.com',
}

View File

@ -0,0 +1,12 @@
import { DataBuddy } from '@dank-inc/data-buddy'
import { User } from '../../types'
const userRecords: User[] = [
{
id: '42',
username: 'TestUser42',
email: 'testuser@email.com',
},
]
export const users = new DataBuddy(userRecords)

View File

@ -51,7 +51,7 @@ export class Api {
} }
} }
export const logOut = () => { export const logOut = async () => {
wipeJWT() wipeJWT()
// axios -> delete session? // axios -> delete session?
} }

View File

@ -0,0 +1,28 @@
import React, { createContext, useContext } from 'react'
import { Api } from '../api'
type Props = {
children: React.ReactNode
api: Api
}
type Context = {
api: Api
}
// Just find-replace "AppContext" with whatever context name you like. (ie. DankContext)
const AppContext = createContext<Context | null>(null)
export const AppContextProvider = ({ api, children }: Props) => {
return <AppContext.Provider value={{ api }}>{children}</AppContext.Provider>
}
export const useAppContext = () => {
const context = useContext(AppContext)
if (!context)
throw new Error(
'AppContext must be called from within the AppContextProvider',
)
return context
}

View File

@ -11,7 +11,8 @@ import { message } from 'antd'
import { useHistory } from 'react-router' import { useHistory } from 'react-router'
import { User } from '../types' import { User } from '../types'
import { getLoggedInUser, logIn, logOut } from '../api' import { useAppContext } from './AppContext'
import { logOut } from '../api'
type Props = { type Props = {
children: React.ReactNode children: React.ReactNode
@ -27,36 +28,17 @@ type Context = {
const UserContext = createContext<Context | null>(null) const UserContext = createContext<Context | null>(null)
export const UserContextProvider = ({ children }: Props) => { export const UserContextProvider = ({ children }: Props) => {
const { api } = useAppContext()
const history = useHistory() const history = useHistory()
const [user, setUser] = useState<User | null>(null) const [user, setUser] = useState<User | null>(null)
useEffect(() => {
const login = async () => {
try {
// const res = axios.post('/dj-rest-auth/login', {
// email: 'blah',
// password: 'blah',
// })
const user = await getLoggedInUser()
if (!user) throw new Error()
setUser(user)
message.success(`logged in as ${user?.username}`, 0.5)
} catch {
// this can possibly be handled better
message.error('Login Failed')
window.location.reload()
}
}
login()
}, [])
const handleLogin = async (username: string, password: string) => { const handleLogin = async (username: string, password: string) => {
try { try {
const user = await logIn(username, password) const { id } = await api.login(username, password)
if (!user) throw new Error('Problem logging in!') if (!id) throw new Error('Problem logging in!')
const user = await api.getUser(id)
setUser(user) setUser(user)
message.success(`logged in as ${user?.username}`, 0.5) message.success(`logged in as ${user?.username}`, 0.5)
} catch (err) { } catch (err) {

View File

@ -1,53 +0,0 @@
import { useCallback, useEffect, useState } from 'react'
import Axios from 'axios'
import { setHeaders } from '../utils/jwt'
type Options = {
subscribe: boolean
}
export type Response<T> =
| {
data: T
loading: false
error: false
refetch: () => void
}
| {
data: null
loading: false
error: true
refetch: () => void
}
| {
data: null
loading: true
error: false
refetch: () => void
}
export const useGet = <T>(path: string, options?: Options): Response<T> => {
const [data, setData] = useState<T | null>(null)
const [error, setError] = useState(false)
const get = useCallback(async () => {
try {
const { data } = await Axios.get<T>(`/api/${path}`, { ...setHeaders() })
setData(data)
} catch (err) {
setError(true)
}
}, [path])
useEffect(() => {
get()
}, [get])
if (data) {
return { data, loading: false, error: false, refetch: get }
} else if (error) {
return { data: null, loading: false, error: true, refetch: get }
} else {
return { data: null, loading: true, error: false, refetch: get }
}
}