user info stored in state; to do, handle refresh/redirect on state change, after login/logout

This commit is contained in:
Mikayla Dobson
2022-10-07 17:24:54 -05:00
parent 8de4af52ea
commit 2d8304dd26
12 changed files with 156 additions and 75 deletions

View File

@@ -1,31 +1,63 @@
// react imports
import { BrowserRouter, Route, Routes } from 'react-router-dom' import { BrowserRouter, Route, Routes } from 'react-router-dom'
import Home from './components/Home/Home' import { useEffect, useState } from 'react'
import Register from './components/User/Register'
import { SupabaseProvider, getSupabaseClient, useSupabase } from './supabase/SupabaseContext'
import './App.css'
import { useEffect } from 'react'
import Login from './components/User/Login'
function App() { // components
import Register from './components/Auth/Register'
import Login from './components/Auth/Login'
import Home from './components/Home'
// util
import { SupabaseProvider, getSupabaseClient, useSupabase } from './supabase/SupabaseContext'
import { initialState } from './util/initialState'
import { AppState } from './util/types'
import './App.css'
import Navbar from './components/Nav/Navbar'
export default function App() {
const [state, setState] = useState<AppState>(initialState);
const supabase = useSupabase(); const supabase = useSupabase();
useEffect(() => { useEffect(() => {
console.log(supabase); setState((prev: AppState) => {
let newUser;
let newSession;
if (supabase) {
newSession = supabase.auth.session();
newUser = supabase.auth.user();
}
return {
...prev,
supabase: supabase,
user: newUser ?? prev.user,
session: newSession ?? prev.session
}
})
}, [supabase]) }, [supabase])
useEffect(() => {
console.log(state);
}, [state]);
return ( return (
<SupabaseProvider value={getSupabaseClient()}> <SupabaseProvider value={getSupabaseClient()}>
<BrowserRouter> <BrowserRouter>
<div className="App"> <div className="App">
<Navbar />
<Routes> <Routes>
{/* Top level route */}
<Route path="/" element={<Home />} /> <Route path="/" element={<Home />} />
{/* Second level routes */}
<Route path="/register" element={<Register />} /> <Route path="/register" element={<Register />} />
<Route path="/login" element={<Login />} /> <Route path="/login" element={<Login />} />
</Routes> </Routes>
</div> </div>
</BrowserRouter> </BrowserRouter>
</SupabaseProvider> </SupabaseProvider>
) )
} }
export default App

View File

@@ -1,33 +1,15 @@
import { useState } from "react" import { FormInput, getSession, handleLogin } from "../../util/authHelpers";
import { useSupabase } from "../../supabase/SupabaseContext"; import { useSupabase } from "../../supabase/SupabaseContext";
import { useState } from "react"
interface FormInput {
email: string
password: string
}
export default function Login() { export default function Login() {
const [input, setInput] = useState<FormInput>({ email: "", password: "" }); const [input, setInput] = useState<FormInput>({ email: "", password: "" });
const supabase = useSupabase(); const supabase = useSupabase();
const handleLogin = async () => {
if (typeof supabase === "string") return;
if (!input.email || !input.password) return;
console.log(input);
const { user, session, error } = await supabase.auth.signIn({ email: input.email, password: input.password });
if (error) throw error;
console.log(user, session);
return { user, session };
}
const getSession = async () => {
if (typeof supabase === "string") return;
console.log(supabase.auth.session());
}
return ( return (
<section> <section>
<h1>Login</h1>
<form> <form>
<div> <div>
<label>Email:</label> <label>Email:</label>
@@ -39,8 +21,8 @@ export default function Login() {
</div> </div>
</form> </form>
<button onClick={handleLogin}>Login</button> <button onClick={() => handleLogin(supabase, input)}>Login</button>
<button onClick={getSession}>Session</button> <button onClick={() => getSession(supabase)}>Session</button>
</section> </section>
) )
} }

View File

@@ -1,5 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { useSupabase } from "../../supabase/SupabaseContext"; import { useSupabase } from "../../supabase/SupabaseContext";
import { getSession, handleRegister } from "../../util/authHelpers";
interface FormInput { interface FormInput {
email: string email: string
@@ -10,27 +11,6 @@ export default function Register() {
const [input, setInput] = useState<FormInput>({email: "", password: ""}); const [input, setInput] = useState<FormInput>({email: "", password: ""});
const supabase = useSupabase(); const supabase = useSupabase();
const handleClick = async () => {
if (typeof supabase === "string") return;
const { email, password } = input;
if (email && password) {
const { user, session, error} = await supabase.auth.signUp({ email, password });
if (error) throw error;
console.log(user, session);
}
}
const getSession = async () => {
if (typeof supabase === "string") return;
console.log(supabase.auth.session());
}
const checkSupabase = () => {
if (supabase) console.log(supabase);
}
return ( return (
<section> <section>
<h1>Register</h1> <h1>Register</h1>
@@ -46,9 +26,8 @@ export default function Register() {
</div> </div>
</form> </form>
<button onClick={handleClick}>Register</button> <button onClick={() => handleRegister(supabase, input)}>Register</button>
<button onClick={checkSupabase}>Supabase?</button> <button onClick={() => getSession(supabase)}>Session</button>
<button onClick={getSession}>Session</button>
</section> </section>
) )
} }

View File

@@ -0,0 +1,17 @@
import { useNavigate } from "react-router-dom"
export default function Home() {
const navigate = useNavigate();
return (
<div>
<h1>Vite + React + Supabase</h1>
<p>Check out the user stuff below:</p>
<div>
<button onClick={() => navigate('/login')}>Login</button>
<button onClick={() => navigate('/register')}>Register</button>
</div>
</div>
)
}

View File

@@ -1,9 +0,0 @@
export default function Home() {
return (
<div>
<h1>Vite + React + Supabase</h1>
<p>Check out the user stuff below:</p>
<a href="/register">User stuff</a>
</div>
)
}

View File

@@ -0,0 +1,4 @@
#navbar-section {
display: flex;
align-items: baseline;
}

View File

@@ -0,0 +1,35 @@
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useSupabase } from "../../supabase/SupabaseContext"
import "./Navbar.css";
export default function Navbar() {
const [view, setView] = useState<JSX.Element>(<p>Loading...</p>);
const supabase = useSupabase();
const navigate = useNavigate();
const handleLogout = async () => {
await supabase?.auth.signOut();
}
useEffect(() => {
const user = supabase?.auth.user();
setView(
<section id="navbar-section">
<h1>Express Spice Market</h1>
<div className="user-data">
{
user?.email && <p>{user.email}</p>
}
{
user ? <button onClick={handleLogout}>Log Out</button> : <button onClick={() => navigate('/login')}>Log In</button>
}
</div>
</section>
)
}, [supabase]);
return view;
}

View File

@@ -1,10 +1,5 @@
import React from 'react'
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
import App from './App' import App from './App'
import './index.css' import './index.css'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);
<React.StrictMode>
<App />
</React.StrictMode>
)

View File

@@ -16,6 +16,6 @@ export const SupabaseProvider: FC<{children: ReactNode, value: SupabaseClient}>
} }
export const useSupabase = () => { export const useSupabase = () => {
const context = useContext(SupabaseContext); const context = useContext(SupabaseContext) || undefined;
return context || "Context currently undefined"; return context;
} }

View File

@@ -0,0 +1,32 @@
import { SupabaseClient } from "@supabase/supabase-js";
export interface FormInput {
email: string
password: string
}
export const handleLogin = async (supabase: SupabaseClient | undefined, input: FormInput) => {
if (!supabase || !input.email || !input.password) return;
console.log(input);
const { user, session, error } = await supabase.auth.signIn({ email: input.email, password: input.password });
if (error) throw error;
console.log(user, session);
return { user, session };
}
export const handleRegister = async (supabase: SupabaseClient | undefined, input: FormInput) => {
if (!supabase) return;
const { email, password } = input;
if (email && password) {
const { user, session, error} = await supabase.auth.signUp({ email, password });
if (error) throw error;
console.log(user, session);
}
}
export const getSession = async (supabase: SupabaseClient | undefined) => {
if (!supabase) return;
console.log(supabase.auth.session());
}

View File

@@ -0,0 +1,7 @@
import { AppState } from "./types";
export const initialState: AppState = {
supabase: undefined,
session: undefined,
user: undefined
}

7
client/src/util/types.ts Normal file
View File

@@ -0,0 +1,7 @@
import { Session, SupabaseClient, User } from "@supabase/supabase-js";
export interface AppState {
supabase?: SupabaseClient
session?: Session
user?: User
}