import { NextPage } from 'next' import Link from 'next/link' import dynamic from 'next/dynamic' import { useRouter } from 'next/router' import { CsrfContext, ResponseProps, Server, Theme, User } from '@types' import { get } from '@utils/Query' import { parseCookie, checkServerFlag, makeServerURL } from '@utils/Tools' import { ParsedUrlQuery } from 'querystring' import NotFound from 'pages/404' import { getToken } from '@utils/Csrf' import Captcha from '@components/Captcha' import { useEffect, useRef, useState } from 'react' import Fetch from '@utils/Fetch' import Day from '@utils/Day' import { getJosaPicker } from 'josa' import { KoreanbotsEndPoints } from '@utils/Constants' import { NextSeo } from 'next-seo' import SetNotification, { getFCMToken } from '@components/FCM' const Container = dynamic(() => import('@components/Container')) const ServerIcon = dynamic(() => import('@components/ServerIcon')) const Button = dynamic(() => import('@components/Button')) const Tag = dynamic(() => import('@components/Tag')) const Segment = dynamic(() => import('@components/Segment')) const Advertisement = dynamic(() => import('@components/Advertisement')) const Login = dynamic(() => import('@components/Login')) const Message = dynamic(() => import('@components/Message')) const VoteServer: NextPage = ({ data, user, theme, csrfToken }) => { const [votingStatus, setVotingStatus] = useState(0) const [result, setResult] = useState>(null) const fcmTokenRef = useRef('') useEffect(() => { if ('Notification' in window && Notification.permission === 'granted') { getFCMToken().then((token) => { fcmTokenRef.current = token }) } }, []) const router = useRouter() if (!data?.id) return if (!user) return ( ) if ( (checkServerFlag(data.flags, 'trusted') || checkServerFlag(data.flags, 'partnered')) && data.vanity && data.vanity !== router.query.id ) router.push(`/servers/${data.vanity}/vote?csrfToken=${csrfToken}`) return ( {data.state === 'blocked' ? (

해당 서버는 관리자에 의해 삭제되었습니다.

) : ( <> {data.name} {getJosaPicker('로')(data.name)}돌아가기
{data.votes} } dark />

{data.name}

12시간마다 다시 투표하실 수 있습니다.

{votingStatus === 0 ? ( ) : votingStatus === 1 ? ( { const res = await Fetch<{ retryAfter: number; notificationSet: boolean }>( `/servers/${data.id}/vote`, { method: 'POST', body: JSON.stringify({ _csrf: csrfToken, _captcha: key, firebaseToken: fcmTokenRef.current, }), } ) setResult(res) setVotingStatus(2) }} /> ) : result.code === 200 ? ( <>

해당 서버에 투표했습니다!

) : result.code === 429 ? ( <>

이미 해당 서버에 투표하였습니다.

{Day(+new Date() + result.data?.retryAfter).fromNow()} 다시 투표하실 수 있습니다.

) : (

{result.message}

)}
)}
) } export const getServerSideProps = async (ctx: Context) => { const parsed = parseCookie(ctx.req) const data = await get.server.load(ctx.query.id) const user = await get.Authorization(parsed?.token) return { props: { csrfToken: getToken(ctx.req, ctx.res), data, user: await get.user.load(user || ''), }, } } interface VoteServerProps { csrfToken: string vote: boolean data: Server user: User theme: Theme } interface Context extends CsrfContext { query: URLQuery } interface URLQuery extends ParsedUrlQuery { id: string } export default VoteServer