Skip to content

Commit 93db523

Browse files
committed
feat: auth
1 parent 94eeef3 commit 93db523

18 files changed

+645
-180
lines changed

.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SUPABASE_AUTH_GITHUB_CLIENT_ID=github-client-id
2+
SUPABASE_AUTH_GITHUB_SECRET=github-secret
3+
SUPABASE_AUTH_GITHUB_REDIRECT_URI=http://localhost:54321/auth/v1/callback

apps/postgres-new/app/globals.css

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
--xxl: 128px;
139139
--content-width-screen-xl: 1128px;
140140
--font-family-body: Inter;
141+
--radius: 0.5rem;
141142
}
142143

143144
[data-theme='dark'],
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { SVGProps } from 'react'
2+
3+
const GitHubIcon = (props: SVGProps<SVGSVGElement>) => (
4+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 96" width="1em" height="1em" {...props}>
5+
<path
6+
fill="currentColor"
7+
fillRule="evenodd"
8+
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
9+
clipRule="evenodd"
10+
/>
11+
</svg>
12+
)
13+
export default GitHubIcon
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
'use client'
2+
3+
/**
4+
* Holds global app data like user.
5+
*/
6+
7+
import { User } from '@supabase/supabase-js'
8+
import {
9+
createContext,
10+
PropsWithChildren,
11+
useCallback,
12+
useContext,
13+
useEffect,
14+
useState,
15+
} from 'react'
16+
import { createClient } from '~/utils/supabase/client'
17+
18+
export type AppProps = PropsWithChildren
19+
20+
export default function AppProvider({ children }: AppProps) {
21+
const [isLoadingUser, setIsLoadingUser] = useState(true)
22+
const [user, setUser] = useState<User>()
23+
24+
const supabase = createClient()
25+
26+
const loadUser = useCallback(async () => {
27+
setIsLoadingUser(true)
28+
try {
29+
const { data, error } = await supabase.auth.getUser()
30+
31+
if (error) {
32+
// TODO: handle error
33+
setUser(undefined)
34+
return
35+
}
36+
37+
const { user } = data
38+
39+
setUser(user)
40+
41+
return user
42+
} finally {
43+
setIsLoadingUser(false)
44+
}
45+
}, [supabase])
46+
47+
useEffect(() => {
48+
loadUser()
49+
}, [loadUser])
50+
51+
const signIn = useCallback(async () => {
52+
const { error } = await supabase.auth.signInWithOAuth({
53+
provider: 'github',
54+
options: {
55+
redirectTo: window.location.toString(),
56+
},
57+
})
58+
59+
if (error) {
60+
// TODO: handle sign in error
61+
}
62+
63+
const user = await loadUser()
64+
return user
65+
}, [supabase, loadUser])
66+
67+
const signOut = useCallback(async () => {
68+
const { error } = await supabase.auth.signOut()
69+
70+
if (error) {
71+
// TODO: handle sign out error
72+
}
73+
74+
setUser(undefined)
75+
}, [supabase])
76+
77+
return (
78+
<AppContext.Provider
79+
value={{
80+
user,
81+
isLoadingUser,
82+
signIn,
83+
signOut,
84+
}}
85+
>
86+
{children}
87+
</AppContext.Provider>
88+
)
89+
}
90+
91+
export type AppContextValues = {
92+
user?: User
93+
isLoadingUser: boolean
94+
signIn: () => Promise<User | undefined>
95+
signOut: () => Promise<void>
96+
}
97+
98+
export const AppContext = createContext<AppContextValues | undefined>(undefined)
99+
100+
export function useApp() {
101+
const context = useContext(AppContext)
102+
103+
if (!context) {
104+
throw new Error('AppContext missing. Are you accessing useApp() outside of an AppProvider?')
105+
}
106+
107+
return context
108+
}

0 commit comments

Comments
 (0)