user info stored in state; to do, handle refresh/redirect on state change, after login/logout
This commit is contained in:
@@ -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
|
|
||||||
|
|||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
17
client/src/components/Home.tsx
Normal file
17
client/src/components/Home.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
4
client/src/components/Nav/Navbar.css
Normal file
4
client/src/components/Nav/Navbar.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#navbar-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
35
client/src/components/Nav/Navbar.tsx
Normal file
35
client/src/components/Nav/Navbar.tsx
Normal 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;
|
||||||
|
}
|
||||||
@@ -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>
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
32
client/src/util/authHelpers.ts
Normal file
32
client/src/util/authHelpers.ts
Normal 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());
|
||||||
|
}
|
||||||
7
client/src/util/initialState.ts
Normal file
7
client/src/util/initialState.ts
Normal 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
7
client/src/util/types.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { Session, SupabaseClient, User } from "@supabase/supabase-js";
|
||||||
|
|
||||||
|
export interface AppState {
|
||||||
|
supabase?: SupabaseClient
|
||||||
|
session?: Session
|
||||||
|
user?: User
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user