11import { notFound } from "next/navigation" ;
22import prisma from "@/lib/prisma" ;
3- import { getMdxContent } from "@/lib/mdx" ;
3+ import { compileMDX } from "next-mdx-remote/rsc" ;
4+ import { supabase } from "@/lib/client" ;
5+ import ChessDiagram from "@/components/openings/ChessDiagram" ;
6+ import remarkToc from "remark-toc" ;
7+ import remarkGfm from "remark-gfm" ;
8+ import remarkBreaks from "remark-breaks" ;
9+ import rehypeSlug from "rehype-slug" ;
10+ import rehypeAutolinkHeadings from "rehype-autolink-headings" ;
411
512type OpeningPageProps = {
613 params : Promise < {
714 slugs : string [ ] ;
815 } > ;
916} ;
1017
11- export default async function OpeningPage ( { params } : OpeningPageProps ) {
12- const resolvedParams = await params ;
18+ async function getOpeningFromPath ( openingPath : string ) {
19+ if ( ! prisma ?. opening ) {
20+ console . error ( "Prisma or Opening model is not initialized." ) ;
21+ return null ;
22+ }
1323
14- // 슬러그가 없으면 404
15- if ( ! resolvedParams . slugs ?. length ) {
16- console . log ( "No slugs found in params:" , resolvedParams ) ;
17- return notFound ( ) ;
24+ try {
25+ const opening = await prisma . opening . findFirst ( {
26+ where : { urlName : openingPath } ,
27+ } ) ;
28+
29+ console . log ( "DB query result:" , opening ) ;
30+ return opening ;
31+ } catch ( error ) {
32+ console . error ( "Database query error:" , error ) ;
33+ return null ;
1834 }
35+ }
1936
20- const openingPath = resolvedParams . slugs . join ( "/" ) . toLowerCase ( ) ;
37+ async function getOpeningContent ( mdxPath : string | null ) {
38+ if ( ! mdxPath ) {
39+ return < p > 이 오프닝에 대한 설명이 없습니다.</ p > ;
40+ }
2141
2242 try {
23- // 디버깅을 위한 로그 추가
24- console . log ( "Attempting to find opening with path:" , openingPath ) ;
43+ const { data, error } = await supabase . storage
44+ . from ( "openings" )
45+ . download ( mdxPath ) ;
2546
26- // Check if Prisma is initialized
27- if ( ! prisma || ! prisma . opening ) {
28- console . error ( "Prisma or Opening model is not initialized." ) ;
29- return notFound ( ) ;
47+ if ( error ) {
48+ console . error ( "MDX 파일을 가져오는데 실패했습니다:" , error ) ;
49+ return < p > 오프닝 내용을 불러오는데 실패했습니다.</ p > ;
3050 }
3151
32- // DB에서 오프닝 정보 조회
33- const opening = await prisma . opening . findFirst ( {
34- where : {
35- urlName : openingPath ,
52+ const content = await data . text ( ) ;
53+ const { content : mdxContent } = await compileMDX ( {
54+ source : content ,
55+ components : {
56+ ChessDiagram,
57+ } ,
58+ options : {
59+ mdxOptions : {
60+ remarkPlugins : [ remarkToc , remarkGfm , remarkBreaks ] ,
61+ rehypePlugins : [
62+ rehypeSlug ,
63+ [
64+ rehypeAutolinkHeadings ,
65+ {
66+ properties : {
67+ className : [ "anchor" ] ,
68+ } ,
69+ } ,
70+ ] ,
71+ ] ,
72+ } ,
3673 } ,
37- } ) . catch ( ( error ) => {
38- console . error ( "Database query error:" , error ) ;
39- return null ;
4074 } ) ;
4175
42- console . log ( "DB query result:" , opening ) ;
76+ return mdxContent ;
77+ } catch ( error ) {
78+ console . error ( "MDX 컨텐츠 로딩 에러:" , error ) ;
79+ return < p > 오프닝 내용을 불러오는데 실패했습니다.</ p > ;
80+ }
81+ }
4382
44- if ( ! opening ) {
45- console . error ( `Opening not found in database: ${ openingPath } ` ) ;
46- return notFound ( ) ;
47- }
83+ export default async function OpeningPage ( { params } : OpeningPageProps ) {
84+ const resolvedParams = await params ;
4885
49- // MDX 컨텐츠 로드 (mdx 필드가 없을 경우 대체 로직 추가)
50- let content = null ;
51- if ( opening . mdx ) {
52- content = await getMdxContent ( opening . mdx ) . catch ( ( error ) => {
53- console . error ( "MDX content loading error:" , error ) ;
54- return null ;
55- } ) ;
56- } else {
57- // mdx 필드가 없을 경우 기본 설명 표시
58- content = < p > No description available for this opening.</ p > ;
59- }
86+ if ( ! resolvedParams . slugs ?. length ) {
87+ console . log ( "슬러그를 찾을 수 없습니다:" , resolvedParams ) ;
88+ return notFound ( ) ;
89+ }
6090
61- return (
62- < article className = "max-w-3xl mx-auto py-8 px-4" >
63- < div className = "prose prose-slate dark:prose-invert max-w-none" >
64- { content }
65- </ div >
66- </ article >
67- ) ;
68- } catch ( error ) {
69- console . error ( "Error fetching opening:" , error ) ;
91+ const openingPath = resolvedParams . slugs . join ( "/" ) . toLowerCase ( ) ;
92+ console . log ( "오프닝 경로 검색 중:" , openingPath ) ;
93+
94+ const opening = await getOpeningFromPath ( openingPath ) ;
95+ if ( ! opening ) {
96+ console . error ( `데이터베이스에서 오프닝을 찾을 수 없습니다: ${ openingPath } ` ) ;
7097 return notFound ( ) ;
7198 }
72- }
99+
100+ const content = await getOpeningContent ( opening . mdx ) ;
101+
102+ return (
103+ < article className = "max-w-3xl mx-auto py-8 px-4" >
104+ < div className = "prose prose-slate dark:prose-invert max-w-none" >
105+ { content }
106+ </ div >
107+ </ article >
108+ ) ;
109+ }
0 commit comments