| @@ -1,13 +1,14 @@ | |||||
| import ReactMarkdown from 'react-markdown' | import ReactMarkdown from 'react-markdown' | ||||
| import { Link } from 'react-router-dom' | import { Link } from 'react-router-dom' | ||||
| type Props = { body: string } | |||||
| type Props = { title: string | |||||
| body?: string } | |||||
| export default ({ body }: Props) => ( | |||||
| export default ({ title, body }: Props) => ( | |||||
| <ReactMarkdown components={{ a: ( | <ReactMarkdown components={{ a: ( | ||||
| ({ href, children }) => (['/', '.'].some (e => href?.startsWith (e)) | |||||
| ? <Link to={href!}>{children}</Link> | |||||
| : <a href={href} target="_blank" rel="noopener noreferrer">{children}</a>)) }}> | |||||
| {body} | |||||
| ({ href, children }) => (['/', '.'].some (e => href?.startsWith (e)) | |||||
| ? <Link to={href!}>{children}</Link> | |||||
| : <a href={href} target="_blank" rel="noopener noreferrer">{children}</a>)) }}> | |||||
| {body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} | |||||
| </ReactMarkdown>) | </ReactMarkdown>) | ||||
| @@ -2,8 +2,8 @@ import React, { useState } from 'react' | |||||
| import { cn } from '@/lib/utils' | import { cn } from '@/lib/utils' | ||||
| type TabProps = { name: string | type TabProps = { name: string | ||||
| init?: boolean | |||||
| children: React.ReactNode } | |||||
| init?: boolean | |||||
| children: React.ReactNode } | |||||
| type Props = { children: React.ReactNode } | type Props = { children: React.ReactNode } | ||||
| @@ -20,20 +20,20 @@ export default ({ children }: Props) => { | |||||
| return ( | return ( | ||||
| <div className="mt-4"> | <div className="mt-4"> | ||||
| <div className="flex gap-4"> | |||||
| {tabs.map ((tab, i) => ( | |||||
| <a key={i} | |||||
| href="#" | |||||
| className={cn (i === current && 'font-bold')} | |||||
| onClick={ev => { | |||||
| ev.preventDefault () | |||||
| setCurrent (i) | |||||
| }}> | |||||
| {tab.props.name} | |||||
| </a>))} | |||||
| </div> | |||||
| <div className="mt-2"> | |||||
| {tabs[current]} | |||||
| </div> | |||||
| <div className="flex gap-4"> | |||||
| {tabs.map ((tab, i) => ( | |||||
| <a key={i} | |||||
| href="#" | |||||
| className={cn (i === current && 'font-bold')} | |||||
| onClick={ev => { | |||||
| ev.preventDefault () | |||||
| setCurrent (i) | |||||
| }}> | |||||
| {tab.props.name} | |||||
| </a>))} | |||||
| </div> | |||||
| <div className="mt-2"> | |||||
| {tabs[current]} | |||||
| </div> | |||||
| </div>) | </div>) | ||||
| } | } | ||||
| @@ -129,11 +129,11 @@ export default () => { | |||||
| {loading && 'Loading...'} | {loading && 'Loading...'} | ||||
| <div ref={loaderRef} className="h-12"></div> | <div ref={loaderRef} className="h-12"></div> | ||||
| </Tab> | </Tab> | ||||
| {(wikiPage && wikiPage.body) && ( | |||||
| <Tab name="Wiki" init={!(posts.length)}> | |||||
| <WikiBody body={wikiPage.body} /> | |||||
| {tags.length === 1 && ( | |||||
| <Tab name="Wiki"> | |||||
| <WikiBody body={wikiPage?.body} title={tags[0]} /> | |||||
| <div className="my-2"> | <div className="my-2"> | ||||
| <Link to={`/wiki/${ encodeURIComponent (wikiPage.title) }`}> | |||||
| <Link to={`/wiki/${ encodeURIComponent (tags[0]) }`}> | |||||
| Wiki を見る | Wiki を見る | ||||
| </Link> | </Link> | ||||
| </div> | </div> | ||||
| @@ -123,7 +123,7 @@ export default () => { | |||||
| <div className="prose mx-auto p-4"> | <div className="prose mx-auto p-4"> | ||||
| {wikiPage === undefined | {wikiPage === undefined | ||||
| ? 'Loading...' | ? 'Loading...' | ||||
| : <WikiBody body={wikiPage?.body || `このページは存在しません。[新規作成してください](/wiki/new?title=${ encodeURIComponent (title) })。`} />} | |||||
| : <WikiBody body={wikiPage?.body} title={title} />} | |||||
| </div> | </div> | ||||
| {(!(version) && posts.length > 0) && ( | {(!(version) && posts.length > 0) && ( | ||||