Skip to content

Commit

Permalink
feat(client): logout
Browse files Browse the repository at this point in the history
  • Loading branch information
sripwoud committed Sep 6, 2024
1 parent b591011 commit 012e665
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 56 deletions.
34 changes: 16 additions & 18 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@ import { Footer } from 'c/Footer'
import { Header } from 'c/Header'
import { Landing } from 'c/Landing'
import { Login } from 'c/Login'
import { ProtectedRoute } from 'c/ProtectedRoute'
import { X } from 'c/X'
import { Navigate, Route, Routes } from 'react-router-dom'

function App() {
return (
<div className='flex flex-col min-h-screen'>
<Header />
<main className='flex-grow px-4'>
<Routes>
<Route path='/login' element={<Login />} />
export const App = () => (
<div className='flex flex-col min-h-screen'>
<Header />
<main className='flex-grow px-4'>
<Routes>
<Route path='/login' element={<Login />} />
<Route element={<ProtectedRoute />}>
<Route path='/x' element={<X />} />
<Route path='/' element={<Landing />} />
{/* Catch-all route to redirect unknown paths to the home page */}
<Route path='*' element={<Navigate replace to='/' />} />
</Routes>
</main>
<Footer />
</div>
)
}

export default App
</Route>
<Route path='/' element={<Landing />} />
<Route path='*' element={<Navigate replace to='/' />} />
</Routes>
</main>
<Footer />
</div>
)
13 changes: 12 additions & 1 deletion client/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useAuthorized } from 'h/useAuthorized'
import { config } from 'l/config'
import { useNavigate } from 'react-router-dom'
export const Header = () => {
const navigate = useNavigate()
const { logout } = useAuthorized()

return (
<header className='navbar flex justify-between items-center p-4'>
<div className='flex items-center'>
Expand All @@ -25,7 +28,15 @@ export const Header = () => {
</button>
</li>
<li>
<button type='button'>Logout</button>
<button
onClick={() => {
logout()
navigate('/')
}}
type='button'
>
Logout
</button>
</li>
</ul>
</nav>
Expand Down
17 changes: 17 additions & 0 deletions client/src/components/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useAuthorized } from 'h/useAuthorized'
import type { FC } from 'react'
import { Navigate, Outlet } from 'react-router-dom'

export const ProtectedRoute: FC = () => {
const { auth, loading } = useAuthorized()

if (loading)
return null

if (auth === false) {
alert('Nice try! But we need to verify your age first.')
return <Navigate replace to='/' />
}

return <Outlet />
}
39 changes: 16 additions & 23 deletions client/src/components/X.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
import { useAuthorized } from 'h/useAuthorized'

export function X() {
useAuthorized()
return (
<div className='flex flex-col items-center justify-center'>
<h1 className='text-3xl font-bold text-center text-violet'>Gallery</h1>
<div className='w-full max-w-5xl'>
{/* Adjust max-w-5xl as needed */}
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 justify-items-center'>
{[0, 1, 2].map((index) => (
<div key={index} className='bg-wisteria p-4 rounded-lg shadow-lg w-full max-w-xs'>
{/* Adjust max-w-xs as needed */}
<img
src={`/dog${index}.avif`}
alt={`Dog eating corndog AI generated drawing ${index + 1}`}
className='w-full h-auto rounded object-cover'
/>
</div>
))}
</div>
export const X = () => (
<div className='flex flex-col items-center justify-center'>
<h1 className='text-3xl font-bold text-center text-violet'>Gallery</h1>
<div className='w-full max-w-5xl'>
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 justify-items-center'>
{[0, 1, 2].map((index) => (
<div key={index} className='bg-wisteria p-4 rounded-lg shadow-lg w-full max-w-xs'>
<img
src={`/dog${index}.avif`}
alt={`Dog eating corndog AI generated drawing ${index + 1}`}
className='w-full h-auto rounded object-cover'
/>
</div>
))}
</div>
</div>
)
}
</div>
)
23 changes: 10 additions & 13 deletions client/src/hooks/useAuthorized.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import { useStore } from 'h/useStore'
import Cookies from 'js-cookie'
import { config } from 'l/config'
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useEffect, useState } from 'react'

export const useAuthorized = () => {
const { setProof } = useStore()
const navigate = useNavigate()

useEffect(() => {
if (Cookies.get(config.cookie.name) !== 'true') {
// FIXME this renders twice
alert('Nice try! But we need to verify your age first (try clicking the Login button)')
navigate('/')
}
}, [navigate])
const { auth, setAuth, setProof } = useStore()
const [loading, setLoading] = useState(true)

const logout = () => {
setAuth(false)
setProof(null)
Cookies.remove(config.cookie.name)
}

return { logout }
useEffect(() => {
setAuth(Cookies.get(config.cookie.name) === 'true')
setLoading(false)
}, [setAuth])

return { auth, loading, logout }
}
2 changes: 2 additions & 0 deletions client/src/hooks/useStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useStoreActions, useStoreState } from 'l/store'

export const useStore = () => ({
auth: useStoreState(state => state.auth.data),
proof: useStoreState(state => state.proof.data),
setAuth: useStoreActions(actions => actions.auth.set),
setProof: useStoreActions(actions => actions.proof.set),
})
11 changes: 11 additions & 0 deletions client/src/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@ import type { OpenPassport1StepInputs } from '@openpassport/sdk'
import { type Action, action, createStore, createTypedHooks } from 'easy-peasy'

interface StoreModel {
auth: {
data: boolean | null
set: Action<{ data: boolean | null }, boolean | null>
}

proof: {
data: OpenPassport1StepInputs | null
set: Action<{ data: OpenPassport1StepInputs | null }, OpenPassport1StepInputs | null>
}
}

const store = createStore<StoreModel>({
auth: {
data: null,
set: action((state, payload) => {
state.data = payload
}),
},
proof: {
data: null,
set: action((state, payload) => {
Expand Down
2 changes: 1 addition & 1 deletion client/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { store } from 'l/store'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter as Router } from 'react-router-dom'
import App from './App.tsx'
import { App } from './App.tsx'
import './assets/index.css'

createRoot(document.getElementById('root')!).render(
Expand Down

0 comments on commit 012e665

Please sign in to comment.