feat: added Docs

This commit is contained in:
wonderlandpark 2021-03-07 11:40:02 +09:00
parent 2062740869
commit eacf773904
5 changed files with 157 additions and 24 deletions

View File

@ -1,36 +1,78 @@
import dynamic from 'next/dynamic'
import Link from 'next/link'
import { ReactNode } from 'react'
import Container from './Container'
import { DocsData } from '@types'
const Container = dynamic(() => import('@components/Container'))
const Divider = dynamic(() => import('@components/Divider'))
const SEO = dynamic(() => import('@components/SEO'))
const DeveloperLayout = ({ children, enabled }:DeveloperLayout):JSX.Element => {
return <div className='flex h-screen'>
const DeveloperLayout = ({ children, enabled, docs, currentDoc }:DeveloperLayout):JSX.Element => {
return <div className='flex min-h-screen'>
<SEO title='한디리 개발자' description='한국 디스코드봇 리스트 API를 활용하여 봇에 다양한 기능을 추가해보세요.' />
<div className='w-1/8 lg:hidden pt-20 px-2 h-screen text-center bg-little-white dark:bg-discord-black'>
<h2 className='font-black text-koreanbots-blue pb-4'><i className='fas fa-tools'/></h2>
<ul className='text-gray-300'>
<li className={`hover:text-white cursor-pointer py-2 px-4 mb-2 rounded-md ${enabled === 'applications' ? 'bg-discord-blurple text-white' : ''}`}>
<Link href='/developers/applications'><i className='fas fa-robot'/></Link>
</li>
<li className={`hover:text-white cursor-pointer py-2 px-4 my-2 rounded-md ${enabled === 'docs' ? 'bg-discord-blurple text-white' : ''}`}>
<Link href='/developers/docs'><i className='fas fa-book'/></Link>
</li>
</ul>
<div className='w-1/8 block lg:hidden h-screen relative'>
<div className='pt-20 px-2 h-full text-center bg-little-white dark:bg-discord-black fixed'>
<h2 className='font-black text-koreanbots-blue pb-4'><i className='fas fa-tools'/></h2>
<ul className='text-gray-600 dark:text-gray-300'>
<li className={`cursor-pointer py-2 px-4 mb-2 rounded-md ${enabled === 'applications' ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
<Link href='/developers/applications'><i className='fas fa-robot'/></Link>
</li>
<li className={`cursor-pointer py-2 px-4 my-2 rounded-md ${enabled === 'docs' ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
<Link href='/developers/docs'><i className='fas fa-book'/></Link>
</li>
</ul>
</div>
</div>
<div className={'lg:w-1/6 bg-little-white dark:bg-discord-black pt-20 px-6 hidden lg:block h-screen'} >
<h2 className='font-black text-2xl pb-4 text-koreanbots-blue'>DEVELOPERS</h2>
<ul className='text-base text-gray-300'>
<li className={`hover:text-white cursor-pointer py-2 px-4 rounded-md ${enabled === 'applications' ? 'bg-discord-blurple text-white' : ''}`}>
<Link href='/developers/applications'> </Link>
</li>
<li className={`hover:text-white cursor-pointer py-2 px-4 rounded-md ${enabled === 'docs' ? 'bg-discord-blurple text-white' : ''}`}>
<Link href='/developers/docs'></Link>
</li>
</ul>
<div className='hidden lg:block h-screen relative'>
<div className='bg-little-white dark:bg-discord-black pt-20 px-6 fixed h-full w-60'>
<h2 className='font-black text-2xl pb-4 text-koreanbots-blue'>DEVELOPERS</h2>
<ul className='text-base text-gray-600 dark:text-gray-300 mb-6'>
<Link href='/developers/applications'>
<li className={`cursor-pointer py-2 px-4 rounded-md ${enabled === 'applications' ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
</li>
</Link>
<Link href='/developers/docs'>
<li className={`cursor-pointer py-2 px-4 rounded-md ${enabled === 'docs' ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
</li>
</Link>
</ul>
{
enabled === 'docs' && <>
<Divider />
<ul className='text-sm text-gray-600 dark:text-gray-300 px-0.5 mt-6'>
{
docs?.map(el => {
if(el.list) return <>
<ul key={el.name} className='text-sm py-3'>
<span className='text-gray-600 dark:text-gray-100 font-bold my-1'>{el.name}</span>
{
el.list.map(e =>
<Link key={e.name} href={`/developers/docs/${el.name}/${e.name}`}>
<li className={`cursor-pointer px-4 py-2 rounded-md ${currentDoc === e.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
{e.name}
</li>
</Link>
)
}
</ul>
</>
return <Link key={el.name} href={`/developers/docs/${el.name}`}>
<li className={`cursor-pointer py-2 px-4 rounded-md ${currentDoc === el.name ? 'bg-discord-blurple text-white' : 'hover:text-gray-500 dark:hover:text-white'}`}>
{el.name}
</li>
</Link>
})
}
</ul>
</>
}
</div>
</div>
<div className='w-full flex-grow py-24 overflow-y-scroll'>
<div className='w-full py-24 lg:pl-60'>
<Container>
{children}
</Container>
@ -41,6 +83,8 @@ const DeveloperLayout = ({ children, enabled }:DeveloperLayout):JSX.Element => {
interface DeveloperLayout {
children: ReactNode
enabled: 'applications' | 'docs'
docs?: DocsData[]
currentDoc?: string
}
export default DeveloperLayout

View File

@ -0,0 +1,72 @@
import { NextPage } from 'next'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import dynamic from 'next/dynamic'
import { lstat, readdir, readFile } from 'fs/promises'
import { join } from 'path'
import { DocsData } from '@types'
import NotFound from 'pages/404'
const DeveloperLayout = dynamic(() => import('@components/DeveloperLayout'))
const Markdown = dynamic(() => import ('@components/Markdown'))
const docsDir = './api-docs/docs'
const Docs: NextPage<DocsProps> = ({ docs }) => {
const router = useRouter()
const [ document, setDoc ] = useState<DocsData>(null)
useEffect(() => {
let res = docs?.find(el => el.name === router.query.first)
if(router.query.second) res = res?.list?.find(el => el.name === router.query.second)
setDoc(res)
}, [docs, router.query])
if((!document && document !== null) || router.query.docs?.length > 2) return <NotFound />
return <DeveloperLayout enabled='docs' docs={docs} currentDoc={(router.query.second || router.query.first) as string}>
<div className='px-2'>
<Markdown text={document?.text} />
</div>
</DeveloperLayout>
}
export async function getStaticPaths () {
return {
paths: [],
fallback: true
}
}
export async function getStaticProps () {
const docs = await Promise.all((await readdir(docsDir)).map(async el => {
const isDir = (await lstat(join(docsDir, el))).isDirectory()
if(!isDir) {
return {
name: el.split('.').slice(0, -1).join('.'),
text: (await readFile(join(docsDir, el))).toString()
}
}
else {
return {
name: el,
list: await Promise.all((await readdir(join(docsDir, el))).map(async e => {
return {
name: e.split('.').slice(0, -1).join('.'),
text: (await readFile(join(docsDir, el, e))).toString()
}
}))
}
}
}))
return {
props: { docs }
}
}
interface DocsProps {
docs: DocsData[]
}
export default Docs

View File

@ -0,0 +1 @@
export { default, getStaticPaths, getStaticProps } from './[second]'

View File

@ -0,0 +1,10 @@
import { NextPage } from 'next'
import { useRouter } from 'next/router'
const Docs: NextPage = () => {
const router = useRouter()
router.push('/developers/docs/시작하기')
return <></>
}
export default Docs

View File

@ -42,6 +42,12 @@ export interface BotSpec {
token: string
}
export interface DocsData {
name: string
list?: DocsData[]
text?: string
}
export enum UserFlags {
general = 0 << 0,
staff = 1 << 0,