diff --git a/app/my/page.tsx b/app/my/page.tsx deleted file mode 100644 index d1b0b16..0000000 --- a/app/my/page.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { QuizCard } from '@/components/quiz/quiz-card'; -import quizOptions from '@/services/quiz/options'; -import { createClient } from '@/utils/supabase/server'; -import { - HydrationBoundary, - QueryClient, - dehydrate, -} from '@tanstack/react-query'; -import { cookies } from 'next/headers'; - -export default async function Page() { - const cookieStore = cookies(); - const supabase = createClient(cookieStore); - const { - data: { user }, - } = await supabase.auth.getUser(); - - const queryClient = new QueryClient(); - - const submittedQuiz = await queryClient.fetchQuery( - quizOptions.submitted(user?.id ?? '') - ); - - return ( - <> -

- {user?.user_metadata.user_name} -

-

풀었던 퀴즈

- - {submittedQuiz && submittedQuiz.length ? ( - - ) : ( -

제출한 퀴즈가 없습니다.

- )} -
- - ); -} diff --git a/app/quizzes/[id]/page.tsx b/app/quizzes/[id]/page.tsx index efd33e6..9522746 100644 --- a/app/quizzes/[id]/page.tsx +++ b/app/quizzes/[id]/page.tsx @@ -37,8 +37,7 @@ export default async function Page({ params }: { params: { id: string } }) {

By{' '} - - {/* TODO: 추후 상세 유저 페이지 라우팅 경로로 변경하기 */} + {quiz?.users?.name}

diff --git a/app/user/[id]/_components/quiz-table.tsx b/app/user/[id]/_components/quiz-table.tsx new file mode 100644 index 0000000..2d89af7 --- /dev/null +++ b/app/user/[id]/_components/quiz-table.tsx @@ -0,0 +1,15 @@ +import { columns } from '@/components/quiz/table/columns'; +import DataTable from '@/components/quiz/table/data-table'; +import { QuizTable } from '../../../../libs/models'; + +type QuizTableProps = { + quiz: QuizTable[]; +}; + +export default function QuizTable({ quiz }: QuizTableProps) { + return ( +
+ +
+ ); +} diff --git a/app/user/[id]/_components/user-info.tsx b/app/user/[id]/_components/user-info.tsx new file mode 100644 index 0000000..11f6d80 --- /dev/null +++ b/app/user/[id]/_components/user-info.tsx @@ -0,0 +1,9 @@ +type UserInfoProps = { + userInfo: { + name: string; + }; +}; + +export default function UserInfo({ userInfo }: UserInfoProps) { + return

{userInfo.name}

; +} diff --git a/app/user/[id]/layout.tsx b/app/user/[id]/layout.tsx new file mode 100644 index 0000000..ce3b4fd --- /dev/null +++ b/app/user/[id]/layout.tsx @@ -0,0 +1,16 @@ +import BackHeader from '@/components/common/headers/back-header'; +import React from 'react'; + +type LayoutProps = { + children: React.ReactNode; +}; + +export default function Layout({ children }: LayoutProps) { + return ( + <> + + +
{children}
+ + ); +} diff --git a/app/user/[id]/not-found.tsx b/app/user/[id]/not-found.tsx new file mode 100644 index 0000000..ae28c4d --- /dev/null +++ b/app/user/[id]/not-found.tsx @@ -0,0 +1,20 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import TypeTime from '@/assets/images/type-time.png'; + +export default function NotFound() { + return ( + <> +
+ 로고 +

페이지를 찾을 수 없습니다.

+ + 홈으로 이동하기 + +
+ + ); +} diff --git a/app/user/[id]/page.tsx b/app/user/[id]/page.tsx new file mode 100644 index 0000000..feab581 --- /dev/null +++ b/app/user/[id]/page.tsx @@ -0,0 +1,36 @@ +import { + HydrationBoundary, + QueryClient, + dehydrate, +} from '@tanstack/react-query'; +import quizOptions from '@/services/quiz/options'; +import userOptions from '@/services/user/options'; +import { Separator } from '@/components/ui/separator'; +import UserInfo from './_components/user-info'; +import QuizTable from './_components/quiz-table'; +import NotFound from './not-found'; + +export default async function Page({ params }: { params: { id: string } }) { + const { id } = params; + + const queryClient = new QueryClient(); + + const [userInfo, submittedQuiz] = await Promise.all([ + queryClient.fetchQuery(userOptions.info(id)), + queryClient.fetchQuery(quizOptions.submitted(id)), + ]); + + if (userInfo) { + return ( + + {userInfo && } + + +

제출한 퀴즈

+ +
+ ); + } + + return ; +} diff --git a/components/common/headers/menu.tsx b/components/common/headers/menu.tsx index f2d5154..0c9015a 100644 --- a/components/common/headers/menu.tsx +++ b/components/common/headers/menu.tsx @@ -48,7 +48,7 @@ export default async function Menu() { diff --git a/components/common/headers/profile.tsx b/components/common/headers/profile.tsx index 079070b..3dc6c05 100644 --- a/components/common/headers/profile.tsx +++ b/components/common/headers/profile.tsx @@ -13,7 +13,7 @@ export default async function Profile() { } = await supabase.auth.getUser(); return ( - +
{ diff --git a/services/user/api.ts b/services/user/api.ts new file mode 100644 index 0000000..f8d76d8 --- /dev/null +++ b/services/user/api.ts @@ -0,0 +1,19 @@ +import { createClient } from '@/utils/supabase/client'; +import { SupabaseClient } from '@supabase/supabase-js'; + +const userAPI = { + getUserInfo: async (id: string) => { + const supabase: SupabaseClient = createClient(); + + const { data } = await supabase + .from('users') + .select('name') + .eq('id', id) + .limit(1) + .single(); + + return data; + }, +}; + +export default userAPI; diff --git a/services/user/hook.ts b/services/user/hook.ts new file mode 100644 index 0000000..58b7d52 --- /dev/null +++ b/services/user/hook.ts @@ -0,0 +1,6 @@ +import { useSuspenseQuery } from '@tanstack/react-query'; +import userOptions from './options'; + +export function useGetUserInfo(id: string) { + return useSuspenseQuery(userOptions.info(id)); +} diff --git a/services/user/options.ts b/services/user/options.ts new file mode 100644 index 0000000..46a122c --- /dev/null +++ b/services/user/options.ts @@ -0,0 +1,14 @@ +import { queryOptions } from '@tanstack/react-query'; +import userAPI from './api'; + +const userOptions = { + default: ['users'] as const, + + info: (id: string) => + queryOptions({ + queryKey: [...userOptions.default, 'info', id], + queryFn: () => userAPI.getUserInfo(id), + }), +}; + +export default userOptions;