feat: added danger zone

This commit is contained in:
wonderlandpark 2021-03-28 13:27:56 +09:00
parent 772a0d4ea5
commit 496f53a0f9

View File

@ -1,10 +1,11 @@
import { NextPage, NextPageContext } from 'next'
import { useState } from 'react'
import { useRef, useState } from 'react'
import { useRouter } from 'next/router'
import dynamic from 'next/dynamic'
import Link from 'next/link'
import { Form, Formik } from 'formik'
import { ParsedUrlQuery } from 'node:querystring'
import { getJosaPicker } from 'josa'
import { get } from '@utils/Query'
import { checkUserFlag, cleanObject, makeBotURL, parseCookie, redirectTo } from '@utils/Tools'
@ -29,11 +30,18 @@ const Selects = dynamic(() => import('@components/Form/Selects'))
const Button = dynamic(() => import('@components/Button'))
const Container = dynamic(() => import('@components/Container'))
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
const Tag = dynamic(() => import('@components/Tag'))
const Message = dynamic(() => import('@components/Message'))
const Modal = dynamic(() => import('@components/Modal'))
const Captcha = dynamic(() => import('@components/Captcha'))
const SEO = dynamic(() => import('@components/SEO'))
const ManageBotPage:NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme }) => {
const [ data, setData ] = useState(null)
const [ adminModal, setAdminModal ] = useState(false)
const [ transferModal, setTransferModal ] = useState(false)
const [ deleteModal, setDeleteModal ] = useState(false)
const deleteRef = useRef()
const router = useRouter()
function toLogin() {
localStorage.redirectTo = window.location.href
@ -44,6 +52,13 @@ const ManageBotPage:NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme })
const res = await Fetch(`/bots/${bot.id}`, { method: 'PATCH', body: JSON.stringify(cleanObject<ManageBot>(value)) })
setData(res)
}
async function getUser(id: string) {
const u = await Fetch<User>(`/users/${encodeURIComponent(id)}`)
if(u.code === 200 && u.data) return u.data
else return null
}
if(!bot) return <NotFound />
if(!user) {
toLogin()
@ -147,7 +162,6 @@ const ManageBotPage:NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme })
<Markdown text={values.desc} />
</Segment>
</Label>
<Divider />
<Button type='submit' onClick={() => window.scrollTo({ top: 0 })}>
<>
<i className='far fa-save'/>
@ -156,6 +170,124 @@ const ManageBotPage:NextPage<ManageBotProps> = ({ bot, user, csrfToken, theme })
</Form>
)}
</Formik>
{
(checkUserFlag(user.flags, 'staff') || (bot.owners as User[])[0].id === user.id) && <div className='py-4'>
<Divider />
<h2 className='text-2xl font-semibold pb-2'></h2>
<Segment>
<div className='lg:flex items-center'>
<div className='flex-grow py-1'>
<h3 className='text-lg font-semibold'> </h3>
<p className='text-gray-400'> .</p>
</div>
<Button onClick={() => setAdminModal(true)} className='h-10 bg-red-500 hover:opacity-80 text-white lg:w-1/8'><i className='fas fa-user-cog' /> </Button>
<Modal full header='관리자 수정' isOpen={adminModal} dark={theme === 'dark'} onClose={() => setAdminModal(false)} closeIcon>
<Formik initialValues={{ owners: (bot.owners as User[]), id: '' }} onSubmit={(v) => alert(JSON.stringify(v.owners.map(el => el.id)))}>
{
({ values, setFieldValue }) => <Form>
<Message type='warning'>
<p> . .</p>
</Message>
<div className='py-4'>
<h2 className='text-md my-1'> ID를 .</h2>
<div className='flex flex-wrap'>
{
(values.owners as User[]).map((el, n) => <Tag className='flex items-center' text={<>
<DiscordAvatar userID={el.id} size={128} className='w-6 h-6 mr-1 rounded-full' /> {el.username}#{el.tag}
{
n !== 0 && <button className='ml-0.5 hover:text-red-500' onClick={() => {
setFieldValue('owners', (() => {
const arr = [...values.owners]
arr.splice(n, 1)
return arr
})())
}}>
<i className='fas fa-times' />
</button>
}
</>} key={el.id} />)
}
</div>
<div className='flex'>
<div className='flex-grow pr-2'>
<Input name='id' placeholder='추가할 유저 ID' />
</div>
<Button className='w-16 bg-discord-blurple' onClick={async () => {
const user = await getUser(values.id)
const arr = [...values.owners]
if(!user) return
else {
arr.push(user)
setFieldValue('owners', arr)
setFieldValue('id', '')
}
}}>
<i className='fas fa-user-plus' />
</Button>
</div>
</div>
<Button className='mt-2 bg-red-500 text-white hover:opacity-80' type='submit'><i className='fas fa-save text-sm' /> </Button>
</Form>
}
</Formik>
</Modal>
</div>
<Divider />
<div className='lg:flex items-center'>
<div className='flex-grow py-1'>
<h3 className='text-lg font-semibold'> </h3>
<p className='text-gray-400'> . .</p>
</div>
<Button onClick={() => setTransferModal(true)} className='h-10 bg-red-500 hover:opacity-80 text-white lg:w-1/8'><i className='fas fa-exchange-alt' /> </Button>
<Modal full header={`${bot.name} 소유권 이전하기`} isOpen={transferModal} dark={theme === 'dark'} onClose={() => setTransferModal(false)} closeIcon>
<Formik initialValues={{ ownerID: '', name: '', _captcha: '' }} onSubmit={(v) => alert(JSON.stringify(v))}>
{
({ values, setFieldValue }) => <Form>
<Message type='warning'>
<p> .</p>
</Message>
<div className='py-4'>
<h2 className='text-md my-1'> ID를 .</h2>
<Input name='ownerID' placeholder='이전할 유저 ID' />
<Divider />
<h2 className='text-md my-1'> <strong>{bot.name}</strong>{getJosaPicker('을')(bot.name)} .</h2>
<Input name='name' placeholder={bot.name} />
</div>
<Captcha ref={deleteRef} dark={theme === 'dark'} onVerify={(k) => setFieldValue('_captcha', k)} />
<Button disabled={!values.ownerID || values.name !== bot.name || !values._captcha} className={`mt-4 bg-red-500 text-white ${!values.ownerID ||values.name !== bot.name || !values._captcha ? 'opacity-80' : 'hover:opacity-80'}`} type='submit'><i className='fas fa-exchange-alt' /> </Button>
</Form>
}
</Formik>
</Modal>
</div>
<Divider />
<div className='lg:flex items-center'>
<div className='flex-grow py-1'>
<h3 className='text-lg font-semibold'> </h3>
<p className='text-gray-400'> .</p>
</div>
<Button onClick={() => setDeleteModal(true)} className='h-10 bg-red-500 hover:opacity-80 text-white lg:w-1/8'><i className='fas fa-trash' /> </Button>
<Modal full header={`${bot.name} 삭제하기`} isOpen={deleteModal} dark={theme === 'dark'} onClose={() => setDeleteModal(false)} closeIcon>
<Formik initialValues={{ name: '', _captcha: '' }} onSubmit={(v) => alert(JSON.stringify(v))}>
{
({ values, setFieldValue }) => <Form>
<Message type='warning'>
<p> .<br/> .</p>
<p> <strong>{bot.name}</strong>{getJosaPicker('을')(bot.name)} .</p>
</Message>
<div className='py-4'>
<Input name='name' placeholder={bot.name} />
</div>
<Captcha ref={deleteRef} dark={theme === 'dark'} onVerify={(k) => setFieldValue('_captcha', k)} />
<Button disabled={values.name !== bot.name || !values._captcha} className={`mt-4 bg-red-500 text-white ${values.name !== bot.name || !values._captcha ? 'opacity-80' : 'hover:opacity-80'}`} type='submit'><i className='fas fa-trash' /> </Button>
</Form>
}
</Formik>
</Modal>
</div>
</Segment>
</div>
}
</Container>
}