-
Notifications
You must be signed in to change notification settings - Fork 1
Feature/#294 user 관련 supabase api 추가 #192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
f56fc0b
ecab381
3d46bf7
af056e9
3732439
c5bd256
9dbe123
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| export type Json = | ||
| export type Json = | ||
| | string | ||
| | number | ||
| | boolean | ||
|
|
@@ -101,7 +101,7 @@ export type Database = { | |
| Row: { | ||
| approval_period: number | null; | ||
| approved_count: number; | ||
| capacity: number | null; | ||
| capacity: number; | ||
| cover_image_url: string | null; | ||
| created_at: string; | ||
| genre: string; | ||
|
|
@@ -116,7 +116,7 @@ export type Database = { | |
| Insert: { | ||
| approval_period?: number | null; | ||
| approved_count: number; | ||
| capacity?: number | null; | ||
| capacity: number; | ||
| cover_image_url?: string | null; | ||
| created_at?: string; | ||
| genre: string; | ||
|
|
@@ -131,7 +131,7 @@ export type Database = { | |
| Update: { | ||
| approval_period?: number | null; | ||
| approved_count?: number; | ||
| capacity?: number | null; | ||
| capacity?: number; | ||
| cover_image_url?: string | null; | ||
| created_at?: string; | ||
| genre?: string; | ||
|
|
@@ -209,6 +209,39 @@ export type Database = { | |
| }, | ||
| ]; | ||
| }; | ||
| users: { | ||
| Row: { | ||
| created_at: string; | ||
| email: string; | ||
| favorite: string; | ||
| id: number; | ||
| image: string | null; | ||
| last_seen_at: string | null; | ||
| name: string; | ||
| updated_at: string | null; | ||
| }; | ||
| Insert: { | ||
| created_at?: string; | ||
| email: string; | ||
| favorite: string; | ||
| id?: number; | ||
| image?: string | null; | ||
| last_seen_at?: string | null; | ||
| name: string; | ||
| updated_at?: string | null; | ||
| }; | ||
| Update: { | ||
| created_at?: string; | ||
| email?: string; | ||
| favorite?: string; | ||
| id?: number; | ||
| image?: string | null; | ||
| last_seen_at?: string | null; | ||
| name?: string; | ||
| updated_at?: string | null; | ||
| }; | ||
| Relationships: []; | ||
| }; | ||
|
Comment on lines
+212
to
+244
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }; | ||
| Views: { | ||
| [_ in never]: never; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| 'use server'; | ||
| import { | ||
| SignUpRequest, | ||
| SigninRequest, | ||
| UserInfoResponse, | ||
| } from '@/api/auth/type'; | ||
| import instanceBaaS from '@/api/instanceBaaS'; | ||
| import { cookies } from 'next/headers'; | ||
|
|
||
| export const createUser = async (user: SignUpRequest) => { | ||
| const { data, error } = await instanceBaaS.auth.signUp({ | ||
| email: user.email, | ||
| password: user.password, | ||
| options: { | ||
| data: { | ||
| name: user.name, | ||
| favorite: user.favorite, | ||
| }, | ||
| }, | ||
| }); | ||
| await instanceBaaS.from('users').insert({ | ||
| email: user.email, | ||
| name: user.name, | ||
| favorite: user.favorite, | ||
| image: null, | ||
| }); | ||
| if (error) { | ||
| throw new Error(error.message); | ||
| } | ||
| return data; | ||
| }; | ||
|
|
||
| export const signin = async (user: SigninRequest) => { | ||
| const { data, error } = await instanceBaaS.auth.signInWithPassword({ | ||
| email: user.email, | ||
| password: user.password, | ||
| }); | ||
| if (error) { | ||
| throw new Error(error.message); | ||
| } | ||
| const cookieStore = await cookies(); | ||
| cookieStore.set('access_token', data.session.access_token); | ||
| cookieStore.set('refresh_token', data.session.refresh_token); | ||
| return data; | ||
| }; | ||
|
|
||
| export const signout = async () => { | ||
| const cookieStore = await cookies(); | ||
| cookieStore.delete('access_token'); | ||
| cookieStore.delete('refresh_token'); | ||
| }; | ||
|
Comment on lines
+47
to
+51
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| export const getUserInfo = async (): Promise<UserInfoResponse | null> => { | ||
| const cookieStore = await cookies(); | ||
| const accessToken = cookieStore.get('access_token'); | ||
| const refreshToken = cookieStore.get('refresh_token'); | ||
| if (!accessToken || !refreshToken) { | ||
| return null; | ||
| } | ||
| const { data, error } = await instanceBaaS.auth.getUser(accessToken.value); | ||
| const { data: user, error: userError } = await instanceBaaS | ||
| .from('users') | ||
| .select('*') | ||
| .eq('email', data.user?.email ?? '') | ||
| .single(); | ||
| if (error) { | ||
| throw new Error(error.message); | ||
| } | ||
| if (userError) { | ||
| throw new Error(userError.message); | ||
| } | ||
|
Comment on lines
+27
to
+71
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분들도 변경된 에러 처리 방식을 적용해주시면 감사하겠습니다! |
||
| return { | ||
| id: user.id, | ||
| name: user.name, | ||
| email: user.email, | ||
| favorite: user.favorite, | ||
| image: user.image ?? '', | ||
| }; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,9 @@ | |
| import { useGetMyInfo } from '@/hooks/api/auth/useGetMyInfo'; | ||
| import { createContext, useContext } from 'react'; | ||
| import { AuthContextValue, AuthProviderClientProps } from './type'; | ||
| import { getUserInfo } from '@/lib/supabase/repositories/users'; | ||
| import { useQuery } from '@tanstack/react-query'; | ||
| import { UserInfoResponse } from '@/api/auth/type'; | ||
|
|
||
| const AuthContext = createContext<AuthContextValue | undefined>(undefined); | ||
|
|
||
|
|
@@ -12,12 +15,18 @@ const AuthProviderClient = ({ | |
| isSignIn, | ||
| }: AuthProviderClientProps) => { | ||
| const { data: myInfo, ...rest } = useGetMyInfo(accessToken ?? ''); | ||
| const { data: userInfo } = useQuery<UserInfoResponse | null>({ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타입 추론 에러가 발생해서 제네릭을 사용해주신 걸까요? |
||
| queryKey: ['userInfo'], | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| queryFn: () => getUserInfo(), | ||
| enabled: !!accessToken, | ||
| }); | ||
|
|
||
| return ( | ||
| <AuthContext.Provider | ||
| value={{ | ||
| isSignIn, | ||
| myInfo, | ||
| userInfo, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 반환하는 데이터의 네이밍이 |
||
| queryMethods: rest, | ||
| }} | ||
| > | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| import { getCookie } from '@/api/cookies'; | ||
| import { MyInfoResponse } from '@/api/auth/type'; | ||
| import { UserInfoResponse } from '@/api/auth/type'; | ||
| import { getQueryClient } from '@/lib/queryClinet'; | ||
| import { QUERY_KEY } from '@/constants/queryKey'; | ||
| import { AuthProviderServerState } from './type'; | ||
| import { getMyInfo } from '@/api/auth/api'; | ||
|
|
||
| import handleError from '@/utils/error'; | ||
| import { getUserInfo } from '@/lib/supabase/repositories/users'; | ||
|
|
||
| const getMyInfoOnServer = async () => { | ||
| const queryClient = getQueryClient(); | ||
| const accessToken = await getCookie('accessToken'); | ||
| const accessToken = await getCookie('access_token'); | ||
|
|
||
| const initialState: AuthProviderServerState = { | ||
| myInfo: undefined, | ||
|
|
@@ -22,9 +23,16 @@ const getMyInfoOnServer = async () => { | |
| } | ||
|
|
||
| try { | ||
| const data = await queryClient.fetchQuery<MyInfoResponse>({ | ||
| const data = await queryClient.fetchQuery<UserInfoResponse>({ | ||
| queryKey: [QUERY_KEY.MY_INFO], | ||
| queryFn: () => getMyInfo(accessToken), | ||
| queryFn: async () => { | ||
| const data = await getUserInfo(); | ||
| if (!data) { | ||
| throw new Error('User not found'); | ||
| } | ||
|
Comment on lines
+30
to
+32
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에러 처리 로직을 위해서 명헌님께서 개발해주신 |
||
| return data; | ||
| }, | ||
| //getMyInfo(accessToken), | ||
| }); | ||
| return { | ||
| ...initialState, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋아하는 작품? 창작물? 이라는 의미까지 변수명/필드명에 담기면 더욱 명시적일 것 같습니다! (favoriteWorks, favoriteCreations, favoriteContents, ... 등)