mirror of
https://github.com/koreanbots/core.git
synced 2025-12-15 14:10:22 +00:00
types: improved component typing
This commit is contained in:
parent
74fa828189
commit
3b52e4c386
@ -1,7 +1,7 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import Logger from '@utils/Logger'
|
import Logger from '@utils/Logger'
|
||||||
|
|
||||||
const Advertisement = ({ size = 'short' }: AdvertisementProps): JSX.Element => {
|
const Advertisement: React.FC<AdvertisementProps> = ({ size = 'short' }) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
window.adsbygoogle = window.adsbygoogle || []
|
window.adsbygoogle = window.adsbygoogle || []
|
||||||
|
|||||||
@ -3,15 +3,14 @@ import Link from 'next/link'
|
|||||||
|
|
||||||
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||||
|
|
||||||
const Application = ({ type, id, name }: ApplicationProps): JSX.Element => {
|
const Application: React.FC<ApplicationProps> = ({ type, id, name }) => {
|
||||||
return (
|
return <Link href={`/developers/applications/${type + 's'}/${id}`}>
|
||||||
<Link href={`/developers/applications/${type + 's'}/${id}`}>
|
|
||||||
<div className='relative px-2 py-4 text-center dark:bg-discord-black bg-little-white rounded-lg cursor-pointer transform hover:-translate-y-1 transition duration-100 ease-in'>
|
<div className='relative px-2 py-4 text-center dark:bg-discord-black bg-little-white rounded-lg cursor-pointer transform hover:-translate-y-1 transition duration-100 ease-in'>
|
||||||
<DiscordAvatar userID={id} className='px-2 w-full rounded-xl' />
|
<DiscordAvatar userID={id} className='px-2 w-full rounded-xl' />
|
||||||
<h2 className='pt-2 whitespace-nowrap text-xl font-medium truncate'>{name}</h2>
|
<h2 className='pt-2 whitespace-nowrap text-xl font-medium truncate'>{name}</h2>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApplicationProps {
|
interface ApplicationProps {
|
||||||
|
|||||||
@ -9,9 +9,8 @@ const Divider = dynamic(() => import('@components/Divider'))
|
|||||||
const Tag = dynamic(() => import('@components/Tag'))
|
const Tag = dynamic(() => import('@components/Tag'))
|
||||||
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||||
|
|
||||||
const BotCard = ({ manage = false, bot }: BotProps): JSX.Element => {
|
const BotCard: React.FC<BotCardProps> = ({ manage = false, bot }) => {
|
||||||
return (
|
return <div className='container mb-16 transform hover:-translate-y-1 transition duration-100 ease-in cursor-pointer'>
|
||||||
<div className='container mb-16 transform hover:-translate-y-1 transition duration-100 ease-in cursor-pointer'>
|
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
<div className='container mx-auto'>
|
<div className='container mx-auto'>
|
||||||
<div className='h-full'>
|
<div className='h-full'>
|
||||||
@ -114,10 +113,10 @@ const BotCard = ({ manage = false, bot }: BotProps): JSX.Element => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BotProps {
|
interface BotCardProps {
|
||||||
manage?: boolean
|
manage?: boolean
|
||||||
bot: Bot
|
bot: Bot
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
const Button = ({
|
const Button: React.FC<ButtonProps> = ({
|
||||||
type = 'button',
|
type = 'button',
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
href,
|
href,
|
||||||
disabled=false,
|
disabled=false,
|
||||||
onClick,
|
onClick,
|
||||||
}: ButtonProps): JSX.Element => {
|
}) => {
|
||||||
return href ? (
|
return href ? <Link href={!disabled && href}>
|
||||||
<Link href={!disabled && href}>
|
|
||||||
<a
|
<a
|
||||||
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
||||||
'bg-discord-blurple hover:opacity-80 dark:bg-very-black dark:hover:bg-discord-dark-hover text-white'}`}
|
'bg-discord-blurple hover:opacity-80 dark:bg-very-black dark:hover:bg-discord-dark-hover text-white'}`}
|
||||||
@ -18,8 +17,7 @@ const Button = ({
|
|||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
) : onClick ? (
|
: onClick ? <button
|
||||||
<button
|
|
||||||
type={disabled ? 'button' : type}
|
type={disabled ? 'button' : type}
|
||||||
onClick={disabled ? null : onClick}
|
onClick={disabled ? null : onClick}
|
||||||
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
||||||
@ -27,7 +25,7 @@ const Button = ({
|
|||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
:
|
||||||
<button
|
<button
|
||||||
type={disabled ? 'button' : type}
|
type={disabled ? 'button' : type}
|
||||||
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
className={`cursor-pointer rounded-md px-4 py-2 transition duration-300 ease select-none outline-none foucs:outline-none mr-1.5 ${className ??
|
||||||
@ -35,7 +33,6 @@ const Button = ({
|
|||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonProps {
|
interface ButtonProps {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Ref } from 'react'
|
|||||||
import HCaptcha from '@hcaptcha/react-hcaptcha'
|
import HCaptcha from '@hcaptcha/react-hcaptcha'
|
||||||
|
|
||||||
|
|
||||||
const Captcha = ({ dark, onVerify }:CaptchaProps):JSX.Element => {
|
const Captcha: React.FC<CaptchaProps> = ({ dark, onVerify }) => {
|
||||||
return <HCaptcha sitekey='43e556b4-cc90-494f-b100-378b906bb736' theme={dark ? 'dark' : 'light'} onVerify={onVerify}/>
|
return <HCaptcha sitekey='43e556b4-cc90-494f-b100-378b906bb736' theme={dark ? 'dark' : 'light'} onVerify={onVerify}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const ColorCard = ({ header, first, second, className }: ColorCardProps): JSX.Element => {
|
const ColorCard: React.FC<ColorCardProps> = ({ header, first, second, className }) => {
|
||||||
return (
|
return (
|
||||||
<div className={`rounded-lg p-10 ${className} shadow-lg`}>
|
<div className={`rounded-lg p-10 ${className} shadow-lg`}>
|
||||||
<h2 className='text-2xl font-bold'>{header}</h2>
|
<h2 className='text-2xl font-bold'>{header}</h2>
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
const Container = ({
|
const Container: React.FC<ContainerProps> = ({
|
||||||
ignoreColor,
|
ignoreColor,
|
||||||
className,
|
className,
|
||||||
paddingTop = false,
|
paddingTop = false,
|
||||||
children,
|
children,
|
||||||
}: ContainerProps): JSX.Element => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${ignoreColor ? '' : 'text-black dark:text-gray-100'} ${
|
className={`${ignoreColor ? '' : 'text-black dark:text-gray-100'} ${
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const Container = dynamic(() => import('@components/Container'))
|
|||||||
const Divider = dynamic(() => import('@components/Divider'))
|
const Divider = dynamic(() => import('@components/Divider'))
|
||||||
const SEO = dynamic(() => import('@components/SEO'))
|
const SEO = dynamic(() => import('@components/SEO'))
|
||||||
|
|
||||||
const DeveloperLayout = ({ children, enabled, docs, currentDoc }:DeveloperLayout):JSX.Element => {
|
const DeveloperLayout: React.FC<DeveloperLayout> = ({ children, enabled, docs, currentDoc }:DeveloperLayout) => {
|
||||||
const [ navbarEnabled, setNavbarOpen ] = useState(false)
|
const [ navbarEnabled, setNavbarOpen ] = useState(false)
|
||||||
|
|
||||||
return <div className='flex min-h-screen'>
|
return <div className='flex min-h-screen'>
|
||||||
|
|||||||
@ -3,12 +3,7 @@ import { KoreanbotsEndPoints } from '@utils/Constants'
|
|||||||
import { supportsWebP } from '@utils/Tools'
|
import { supportsWebP } from '@utils/Tools'
|
||||||
import Logger from '@utils/Logger'
|
import Logger from '@utils/Logger'
|
||||||
|
|
||||||
const DiscordAvatar = (props: {
|
const DiscordAvatar: React.FC<DiscordAvatarProps> = props => {
|
||||||
alt?: string
|
|
||||||
userID: string
|
|
||||||
className?: string
|
|
||||||
size? : 128 | 256 | 512
|
|
||||||
}) => {
|
|
||||||
const fallback = '/img/default.png'
|
const fallback = '/img/default.png'
|
||||||
const [ webpUnavailable, setWebpUnavailable ] = useState<boolean>()
|
const [ webpUnavailable, setWebpUnavailable ] = useState<boolean>()
|
||||||
|
|
||||||
@ -46,7 +41,12 @@ const DiscordAvatar = (props: {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DiscordAvatar
|
interface DiscordAvatarProps {
|
||||||
|
alt?: string
|
||||||
|
userID: string
|
||||||
|
className?: string
|
||||||
|
size? : 128 | 256 | 512
|
||||||
|
}
|
||||||
|
|
||||||
interface ImageEvent extends Event {
|
interface ImageEvent extends Event {
|
||||||
target: ImageTarget
|
target: ImageTarget
|
||||||
@ -56,3 +56,5 @@ interface ImageTarget extends EventTarget {
|
|||||||
src: string
|
src: string
|
||||||
onerror: (event: SyntheticEvent<HTMLImageElement, ImageEvent>) => void
|
onerror: (event: SyntheticEvent<HTMLImageElement, ImageEvent>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default DiscordAvatar
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Divider = ({ className }: { className?: string }) => {
|
const Divider: React.FC<DividerProps> = ({ className }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`my-2 px-5 ${className || ''}`}
|
className={`my-2 px-5 ${className || ''}`}
|
||||||
@ -10,4 +10,8 @@ const Divider = ({ className }: { className?: string }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DividerProps {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
export default Divider
|
export default Divider
|
||||||
|
|||||||
@ -2,7 +2,8 @@ import dynamic from 'next/dynamic'
|
|||||||
|
|
||||||
const Container = dynamic(() => import('@components/Container'))
|
const Container = dynamic(() => import('@components/Container'))
|
||||||
const SEO = dynamic(() => import('@components/SEO'))
|
const SEO = dynamic(() => import('@components/SEO'))
|
||||||
const Docs = ({ title, header, description, subheader, children }: DocsProps): JSX.Element => {
|
|
||||||
|
const Docs: React.FC<DocsProps> = ({ title, header, description, subheader, children }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SEO
|
<SEO
|
||||||
@ -32,9 +33,9 @@ const Docs = ({ title, header, description, subheader, children }: DocsProps): J
|
|||||||
export default Docs
|
export default Docs
|
||||||
|
|
||||||
interface DocsProps {
|
interface DocsProps {
|
||||||
header: string | JSX.Element
|
header: string | React.ReactNode
|
||||||
title?: string
|
title?: string
|
||||||
description?: string
|
description?: string
|
||||||
subheader?: string
|
subheader?: string
|
||||||
children: JSX.Element | JSX.Element[]
|
children: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { Theme } from '@types'
|
|||||||
const Container = dynamic(() => import('@components/Container'))
|
const Container = dynamic(() => import('@components/Container'))
|
||||||
const Toggle = dynamic(() => import('@components/Toggle'))
|
const Toggle = dynamic(() => import('@components/Toggle'))
|
||||||
|
|
||||||
const Footer = ({ theme, setTheme }: FooterProps): JSX.Element => {
|
const Footer: React.FC<FooterProps> = ({ theme, setTheme }) => {
|
||||||
return (
|
return (
|
||||||
<div className='releative z-30'>
|
<div className='releative z-30'>
|
||||||
<div className='bottom-0 text-white bg-discord-black py-24'>
|
<div className='bottom-0 text-white bg-discord-black py-24'>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { ErrorText } from '@utils/Constants'
|
|||||||
const SEO = dynamic(() => import('@components/SEO'))
|
const SEO = dynamic(() => import('@components/SEO'))
|
||||||
const Button = dynamic(() => import('@components/Button'))
|
const Button = dynamic(() => import('@components/Button'))
|
||||||
|
|
||||||
const Forbidden = ():JSX.Element => {
|
const Forbidden:React.FC = () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
return <>
|
return <>
|
||||||
<SEO title='권한이 없습니다' />
|
<SEO title='권한이 없습니다' />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Field } from 'formik'
|
import { Field } from 'formik'
|
||||||
|
|
||||||
const CheckBox = ({ name, ...props }: CheckBoxProps): JSX.Element => {
|
const CheckBox: React.FC<CheckBoxProps> = ({ name, ...props }) => {
|
||||||
return <Field type='checkbox' name={name} className='form-checkbox text-koreanbots-blue bg-gray-300 h-4 w-4 rounded' {...props} />
|
return <Field type='checkbox' name={name} className='form-checkbox text-koreanbots-blue bg-gray-300 h-4 w-4 rounded' {...props} />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Field } from 'formik'
|
import { Field } from 'formik'
|
||||||
|
|
||||||
const CsrfToken = ({ token }: CsrfTokenProps): JSX.Element => {
|
const CsrfToken: React.FC<CsrfTokenProps> = ({ token }) => {
|
||||||
return <Field name='_csrf' hidden value={token} readOnly />
|
return <Field name='_csrf' hidden value={token} readOnly />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Field } from 'formik'
|
import { Field } from 'formik'
|
||||||
|
|
||||||
const Input = ({ name, placeholder }: InputProps): JSX.Element => {
|
const Input: React.FC<InputProps> = ({ name, placeholder, ...props }) => {
|
||||||
return (
|
return <Field
|
||||||
<Field
|
{...props}
|
||||||
name={name}
|
name={name}
|
||||||
className='border-grey-light relative px-3 w-full h-10 text-black dark:text-white dark:bg-very-black border dark:border-transparent rounded outline-none'
|
className='border-grey-light relative px-3 w-full h-10 text-black dark:text-white dark:bg-very-black border dark:border-transparent rounded outline-none'
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
/>
|
/>
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InputProps {
|
interface InputProps {
|
||||||
name: string
|
name: string
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Input
|
export default Input
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Label = ({
|
const Label: React.FC<LabelProps> = ({
|
||||||
For,
|
For,
|
||||||
children,
|
children,
|
||||||
label,
|
label,
|
||||||
@ -7,10 +7,8 @@ const Label = ({
|
|||||||
grid = true,
|
grid = true,
|
||||||
short = false,
|
short = false,
|
||||||
required = false,
|
required = false,
|
||||||
}: LabelProps): JSX.Element => {
|
}) => {
|
||||||
return (
|
return <label
|
||||||
<>
|
|
||||||
<label
|
|
||||||
className={grid ? 'grid grid-cols-1 xl:grid-cols-4 gap-2 my-4' : 'inline-flex items-center'}
|
className={grid ? 'grid grid-cols-1 xl:grid-cols-4 gap-2 my-4' : 'inline-flex items-center'}
|
||||||
htmlFor={For}
|
htmlFor={For}
|
||||||
>
|
>
|
||||||
@ -30,8 +28,6 @@ const Label = ({
|
|||||||
<div className='mt-1 text-red-500 text-xs font-light'>{error}</div>
|
<div className='mt-1 text-red-500 text-xs font-light'>{error}</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LabelProps {
|
interface LabelProps {
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import ReactSelect from 'react-select'
|
import ReactSelect from 'react-select'
|
||||||
|
|
||||||
const Select = ({ placeholder, options, handleChange, handleTouch, value }: SelectProps): JSX.Element => {
|
const Select: React.FC<SelectProps> = ({ placeholder, options, handleChange, handleTouch, value }) => {
|
||||||
return (
|
return <ReactSelect
|
||||||
<ReactSelect
|
|
||||||
styles={{
|
styles={{
|
||||||
control: provided => {
|
control: provided => {
|
||||||
return { ...provided, border: 'none' }
|
return { ...provided, border: 'none' }
|
||||||
@ -26,7 +25,6 @@ const Select = ({ placeholder, options, handleChange, handleTouch, value }: Sele
|
|||||||
noOptionsMessage={() => '검색 결과가 없습니다.'}
|
noOptionsMessage={() => '검색 결과가 없습니다.'}
|
||||||
defaultValue={value}
|
defaultValue={value}
|
||||||
/>
|
/>
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SelectProps {
|
interface SelectProps {
|
||||||
|
|||||||
@ -31,7 +31,7 @@ const SortableMultiValueLabel = SortableHandle(props => (
|
|||||||
|
|
||||||
const SortableSelect = SortableContainer(ReactSelect)
|
const SortableSelect = SortableContainer(ReactSelect)
|
||||||
|
|
||||||
const Select = ({ placeholder, options, values, setValues, handleChange, handleTouch }:SelectProps):JSX.Element => {
|
const Select: React.FC<SelectProps> = ({ placeholder, options, values, setValues, handleChange, handleTouch }) => {
|
||||||
const onSortEnd = ({ oldIndex, newIndex }) => {
|
const onSortEnd = ({ oldIndex, newIndex }) => {
|
||||||
const newValue = arrayMove(values, oldIndex, newIndex)
|
const newValue = arrayMove(values, oldIndex, newIndex)
|
||||||
setValues(newValue)
|
setValues(newValue)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import 'emoji-mart/css/emoji-mart.css'
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const TextArea = ({ name, placeholder, theme='auto', setValue, value }:TextAreaProps):JSX.Element => {
|
const TextArea: React.FC<TextAreaProps> = ({ name, placeholder, theme='auto', setValue, value }) => {
|
||||||
const ref = useRef()
|
const ref = useRef()
|
||||||
const [ emojiPickerHidden, setEmojiPickerHidden ] = useState(true)
|
const [ emojiPickerHidden, setEmojiPickerHidden ] = useState(true)
|
||||||
useOutsideClick(ref, () => {
|
useOutsideClick(ref, () => {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ const Container = dynamic(()=> import('@components/Container'))
|
|||||||
const Tag = dynamic(()=> import('@components/Tag'))
|
const Tag = dynamic(()=> import('@components/Tag'))
|
||||||
const Search = dynamic(()=> import('@components/Search'))
|
const Search = dynamic(()=> import('@components/Search'))
|
||||||
|
|
||||||
const Hero = ({ header, description }:HeroProps):JSX.Element => {
|
const Hero:React.FC<HeroProps> = ({ header, description }) => {
|
||||||
return <>
|
return <>
|
||||||
<div className='dark:bg-discord-black bg-discord-blurple text-gray-100 md:p-0 mb-8'>
|
<div className='dark:bg-discord-black bg-discord-blurple text-gray-100 md:p-0 mb-8'>
|
||||||
<Container className='pt-24 pb-16 md:pb-20' ignoreColor>
|
<Container className='pt-24 pb-16 md:pb-20' ignoreColor>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Loader = ({ text, visible = true }: LoaderProps): JSX.Element => {
|
const Loader: React.FC<LoaderProps> = ({ text, visible = true }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
@ -13,7 +13,7 @@ const Loader = ({ text, visible = true }: LoaderProps): JSX.Element => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface LoaderProps {
|
interface LoaderProps {
|
||||||
text: string | JSX.Element
|
text: string | React.ReactNode
|
||||||
visible?: boolean
|
visible?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { redirectTo } from '@utils/Tools'
|
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
|
import { redirectTo } from '@utils/Tools'
|
||||||
|
|
||||||
const Login: React.FC = ({ children }) => {
|
const Login: React.FC = ({ children }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
const LongButton = ({ children, newTab=false, href, onClick, center=false }:LongButtonProps):JSX.Element => {
|
const LongButton: React.FC<LongButtonProps> = ({ children, newTab=false, href, onClick, center=false }) => {
|
||||||
if(href) {
|
if(href) {
|
||||||
if(newTab) return <a href={href} rel='noopener noreferrer'
|
if(newTab) return <a href={href} rel='noopener noreferrer'
|
||||||
target='_blank'>
|
target='_blank'>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { FunctionComponent } from 'react'
|
|||||||
|
|
||||||
import { anchorHeader, customEmoji, twemoji } from '@utils/Tools'
|
import { anchorHeader, customEmoji, twemoji } from '@utils/Tools'
|
||||||
|
|
||||||
const Markdown = ({ text, options={}, allowedTag=[], components={} }: MarkdownProps): JSX.Element => {
|
const Markdown: React.FC<MarkdownProps> = ({ text, options={}, allowedTag=[], components={} }) => {
|
||||||
return (
|
return (
|
||||||
<div className='markdown-body w-full'>
|
<div className='markdown-body w-full'>
|
||||||
<MarkdownView
|
<MarkdownView
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { MessageColor } from '@utils/Constants'
|
import { MessageColor } from '@utils/Constants'
|
||||||
import Markdown from './Markdown'
|
import Markdown from './Markdown'
|
||||||
|
|
||||||
const Message = ({ type, children }: MessageProps): JSX.Element => {
|
const Message: React.FC<MessageProps> = ({ type, children }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${MessageColor[type]} px-6 py-4 rounded-md text-base mx-auto w-full text-left`}
|
className={`${MessageColor[type]} px-6 py-4 rounded-md text-base mx-auto w-full text-left`}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { ReactNode } from 'react'
|
|||||||
import { Modal as ReactModal } from 'react-responsive-modal'
|
import { Modal as ReactModal } from 'react-responsive-modal'
|
||||||
import 'react-responsive-modal/styles.css'
|
import 'react-responsive-modal/styles.css'
|
||||||
|
|
||||||
const Modal = ({ children, isOpen, onClose, closeIcon=false, dark, header, full=false }: ModalProps): JSX.Element => {
|
const Modal: React.FC<ModalProps> = ({ children, isOpen, onClose, closeIcon=false, dark, header, full=false }) => {
|
||||||
return (
|
return (
|
||||||
<ReactModal
|
<ReactModal
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import dynamic from 'next/dynamic'
|
|||||||
const Button = dynamic(() => import('@components/Button'))
|
const Button = dynamic(() => import('@components/Button'))
|
||||||
const Container = dynamic(() => import('@components/Container'))
|
const Container = dynamic(() => import('@components/Container'))
|
||||||
|
|
||||||
const NSFW = ({ onClick, onDisableClick }:NSFWProps): JSX.Element => {
|
const NSFW: React.FC<NSFWProps> = ({ onClick, onDisableClick }) => {
|
||||||
return <Container>
|
return <Container>
|
||||||
<div className='flex items-center h-screen select-none'>
|
<div className='flex items-center h-screen select-none'>
|
||||||
<div className='px-10'>
|
<div className='px-10'>
|
||||||
|
|||||||
@ -3,15 +3,16 @@
|
|||||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
import { redirectTo } from '@utils/Tools'
|
import { redirectTo } from '@utils/Tools'
|
||||||
|
import Fetch from '@utils/Fetch'
|
||||||
import { User, UserCache } from '@types'
|
import { User, UserCache } from '@types'
|
||||||
|
|
||||||
import DiscordAvatar from '@components/DiscordAvatar'
|
const DiscordAvatar = dynamic(() => import('@components/DiscordAvatar'))
|
||||||
import Fetch from '@utils/Fetch'
|
|
||||||
|
|
||||||
const Navbar = ({ token, pwa }:{ token: string, pwa: boolean }): JSX.Element => {
|
const Navbar: React.FC<NavbarProps> = ({ token, pwa }) => {
|
||||||
const [userCache, setUserCache] = useState<UserCache>()
|
const [userCache, setUserCache] = useState<UserCache>()
|
||||||
const [navbarOpen, setNavbarOpen] = useState<boolean>(false)
|
const [navbarOpen, setNavbarOpen] = useState<boolean>(false)
|
||||||
const [dropdownOpen, setDropdownOpen] = useState<boolean>(false)
|
const [dropdownOpen, setDropdownOpen] = useState<boolean>(false)
|
||||||
@ -213,4 +214,9 @@ const Navbar = ({ token, pwa }:{ token: string, pwa: boolean }): JSX.Element =>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NavbarProps {
|
||||||
|
token: string
|
||||||
|
pwa: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export default Navbar
|
export default Navbar
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Notice = ({ header, desc }: NoticeProps) => {
|
const Notice: React.FC<NoticeProps> = ({ header, desc }) => {
|
||||||
return (
|
return (
|
||||||
<div className='mx-auto my-auto px-10 py-48 h-screen text-center'>
|
<div className='mx-auto my-auto px-10 py-48 h-screen text-center'>
|
||||||
<h1 className='text-4xl font-bold'>KOREANBOTS</h1>
|
<h1 className='text-4xl font-bold'>KOREANBOTS</h1>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import DiscordAvatar from '@components/DiscordAvatar'
|
import DiscordAvatar from '@components/DiscordAvatar'
|
||||||
|
|
||||||
const Owner = ({ id, username, tag }: OwnerProps): JSX.Element => {
|
const Owner: React.FC<OwnerProps> = ({ id, username, tag }) => {
|
||||||
return (
|
return (
|
||||||
<Link href={`/users/${id}`}>
|
<Link href={`/users/${id}`}>
|
||||||
<a className='dark:hover:bg-discord-dark-hover flex mb-1 px-4 py-4 text-black dark:text-gray-400 text-base dark:bg-discord-black bg-little-white hover:bg-little-white-hover rounded cursor-pointer'>
|
<a className='dark:hover:bg-discord-dark-hover flex mb-1 px-4 py-4 text-black dark:text-gray-400 text-base dark:bg-discord-black bg-little-white hover:bg-little-white-hover rounded cursor-pointer'>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
const Paginator = ({ currentPage, totalPage, pathname, searchParams }: PaginatorProps): JSX.Element => {
|
const Paginator: React.FC<PaginatorProps> = ({ currentPage, totalPage, pathname, searchParams }) => {
|
||||||
let pages = []
|
let pages = []
|
||||||
if (currentPage < 4)
|
if (currentPage < 4)
|
||||||
pages = [
|
pages = [
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
const PlatformDisplay = ({ osx, children }:PlatformDisplayProps): JSX.Element => {
|
const PlatformDisplay: React.FC<PlatformDisplayProps> = ({ osx, children }:PlatformDisplayProps) => {
|
||||||
const isOSX = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
|
const isOSX = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
|
||||||
return <>{isOSX ? osx ?? children : children}</>
|
return <>{isOSX ? osx ?? children : children}</>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { redirectTo } from '@utils/Tools'
|
|||||||
|
|
||||||
const Container = dynamic(() => import('@components/Container'))
|
const Container = dynamic(() => import('@components/Container'))
|
||||||
|
|
||||||
const Redirect = ({ to, text=true, children }:RedirectProps):JSX.Element => {
|
const Redirect: React.FC<RedirectProps> = ({ to, text=true, children }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
if(!to) throw new Error('No Link')
|
if(!to) throw new Error('No Link')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
import { ReactNode } from 'react'
|
const ResponsiveGrid: React.FC = ({ children }) => {
|
||||||
|
|
||||||
const ResponsiveGrid = ({ children }:{ children: ReactNode }):JSX.Element => {
|
|
||||||
return <div className='grid gap-x-4 grid-rows-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mt-10 -mb-10'>
|
return <div className='grid gap-x-4 grid-rows-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 mt-10 -mb-10'>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
|
|
||||||
const SEO = ({ title, description, image }: SEOProps): JSX.Element => {
|
const SEO: React.FC<SEOProps> = ({ title, description, image }: SEOProps) => {
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<title>{title} - 한국 디스코드봇 리스트</title>
|
<title>{title} - 한국 디스코드봇 리스트</title>
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import DiscordAvatar from '@components/DiscordAvatar'
|
|||||||
import Day from '@utils/Day'
|
import Day from '@utils/Day'
|
||||||
import useOutsideClick from '@utils/useOutsideClick'
|
import useOutsideClick from '@utils/useOutsideClick'
|
||||||
|
|
||||||
const Search = (): JSX.Element => {
|
const Search: React.FC = () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const ref = useRef()
|
const ref = useRef()
|
||||||
const [query, setQuery] = useState('')
|
const [query, setQuery] = useState('')
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
const Segment = ({ children, className = '' }: SegmentProps): JSX.Element => {
|
const Segment: React.FC<SegmentProps> = ({ children, className = '' }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`py-3 px-7 text-black dark:text-white dark:bg-discord-black bg-little-white rounded ${className}`}
|
className={`py-3 px-7 text-black dark:text-white dark:bg-discord-black bg-little-white rounded ${className}`}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Tag from '@components/Tag'
|
|||||||
import { SubmittedBot } from '@types'
|
import { SubmittedBot } from '@types'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
const SubmittedBotCard = ({ href, submit }: SubmittedBotProps): JSX.Element => {
|
const SubmittedBotCard: React.FC<SubmittedBotProps> = ({ href, submit }) => {
|
||||||
return (
|
return (
|
||||||
<Link href={href}>
|
<Link href={href}>
|
||||||
<a className='relative mx-auto px-4 py-5 w-full h-full text-black dark:text-white dark:bg-discord-black bg-little-white rounded-2xl shadow-xl transform hover:-translate-y-1 transition duration-100 ease-in'>
|
<a className='relative mx-auto px-4 py-5 w-full h-full text-black dark:text-white dark:bg-discord-black bg-little-white rounded-2xl shadow-xl transform hover:-translate-y-1 transition duration-100 ease-in'>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
const Tag = ({
|
const Tag: React.FC<LabelProps> = ({
|
||||||
blurple = false,
|
blurple = false,
|
||||||
github = false,
|
github = false,
|
||||||
href,
|
href,
|
||||||
@ -13,7 +13,7 @@ const Tag = ({
|
|||||||
newTab = false,
|
newTab = false,
|
||||||
bigger = false,
|
bigger = false,
|
||||||
...props
|
...props
|
||||||
}: LabelProps): JSX.Element => {
|
}) => {
|
||||||
return href ? (
|
return href ? (
|
||||||
newTab ? (
|
newTab ? (
|
||||||
<a
|
<a
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Toggle = ({ checked, onChange }: ToggleProps): JSX.Element => {
|
const Toggle: React.FC<ToggleProps> = ({ checked, onChange }: ToggleProps) => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className='relative inline-block align-middle mr-2 w-10 outline-none select-none'
|
className='relative inline-block align-middle mr-2 w-10 outline-none select-none'
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
const Tooltip = ({
|
const Tooltip: React.FC<TooltipProps> = ({
|
||||||
href,
|
href,
|
||||||
size = 'small',
|
size = 'small',
|
||||||
children,
|
children,
|
||||||
direction = 'center',
|
direction = 'center',
|
||||||
text,
|
text,
|
||||||
}: TooltipProps): JSX.Element => {
|
}) => {
|
||||||
return href ? (
|
return href ? (
|
||||||
<Link href={href}>
|
<Link href={href}>
|
||||||
<a className='inline'>
|
<a className='inline'>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
const Wave = ({ color, className }: WaveProps): JSX.Element => {
|
const Wave: React.FC<WaveProps> = ({ color, className }) => {
|
||||||
return (
|
return (
|
||||||
<svg viewBox='0 0 1440 320' className={className}>
|
<svg viewBox='0 0 1440 320' className={className}>
|
||||||
<path
|
<path
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user