core/pages/panel.tsx
SKINMAKER b421d1ab64
chore: apply prettier (#637)
* chore: apply prettier

* chore: edit ready comment

* chore: move ts comment
2023-11-29 22:04:33 +09:00

138 lines
4.0 KiB
TypeScript

import { NextPage, NextPageContext } from 'next'
import { NextSeo } from 'next-seo'
import { useState } from 'react'
import dynamic from 'next/dynamic'
import { useRouter } from 'next/router'
import { get } from '@utils/Query'
import { parseCookie } from '@utils/Tools'
import { Bot, Server, SubmittedBot, User } from '@types'
import Fetch from '@utils/Fetch'
import { getToken } from '@utils/Csrf'
const Container = dynamic(() => import('@components/Container'))
const ResponsiveGrid = dynamic(() => import('@components/ResponsiveGrid'))
const Button = dynamic(() => import('@components/Button'))
const BotCard = dynamic(() => import('@components/BotCard'))
const ServerCard = dynamic(() => import('@components/ServerCard'))
const SubmittedBotCard = dynamic(() => import('@components/SubmittedBotCard'))
const Login = dynamic(() => import('@components/Login'))
const Panel: NextPage<PanelProps> = ({ logged, user, submits, csrfToken }) => {
const router = useRouter()
const [submitLimit, setSubmitLimit] = useState(8)
if (!logged)
return (
<Login>
<NextSeo title='관리 패널' />
</Login>
)
return (
<Container paddingTop className='pb-10 pt-5'>
<NextSeo title='관리 패널' />
<h1 className='text-4xl font-bold'> </h1>
<h2 className='mt-4 text-2xl font-bold'> </h2>
<p className='mb-2 text-gray-400'> .</p>
<Button
className={`${
user.github ? 'bg-red-600 text-white' : 'bg-gray-200 dark:bg-github-black'
} hover:opacity-80`}
onClick={
user.github
? async () => {
await Fetch(
'/api/auth/github',
{
method: 'DELETE',
body: JSON.stringify({
_csrf: csrfToken,
}),
},
true
)
router.reload()
}
: null
}
href={user.github ? null : '/api/auth/github'}
>
<i className='fab fa-github' /> {user.github ? '취소' : ''}
</Button>
<div className='mt-6'>
<h2 className='text-3xl font-bold'> </h2>
{user.bots.length === 0 ? (
<h2 className='text-xl'> .</h2>
) : (
<ResponsiveGrid>
{(user.bots as Bot[]).map((bot) => (
<BotCard key={bot.id} bot={bot} manage />
))}
</ResponsiveGrid>
)}
</div>
<div className='mt-6'>
<h2 className='text-3xl font-bold'> </h2>
{user.servers.length === 0 ? (
<h2 className='text-xl'> .</h2>
) : (
<ResponsiveGrid>
{(user.servers as Server[]).map((server) => (
<ServerCard key={server.id} server={server} type='manage' />
))}
</ResponsiveGrid>
)}
</div>
<div className='mt-6'>
<h2 className='text-3xl font-bold'> </h2>
{submits.length === 0 ? (
<h2 className='text-xl'> .</h2>
) : (
<>
<p className='text-left text-sm font-medium text-gray-400'>
.
</p>
<div className='mt-12 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4'>
{submits.slice(0, submitLimit).map((el) => (
<SubmittedBotCard
key={el.date}
href={`/pendingBots/${el.id}/${el.date}`}
submit={el}
/>
))}
</div>
{submitLimit < submits.length && (
<div className='pt-4 text-center'>
<Button onClick={() => setSubmitLimit(submitLimit + 8)}></Button>
</div>
)}
</>
)}
</div>
</Container>
)
}
export const getServerSideProps = async (ctx: NextPageContext) => {
const parsed = parseCookie(ctx.req)
const user = (await get.Authorization(parsed?.token)) || ''
const submits = await get.botSubmits.load(user)
return {
props: {
logged: !!user,
user: await get.user.load(user),
submits,
csrfToken: getToken(ctx.req, ctx.res),
},
}
}
interface PanelProps {
logged: boolean
user: User
submits: SubmittedBot[]
csrfToken: string
}
export default Panel