types: improved component typing

This commit is contained in:
wonderlandpark 2021-05-18 11:16:48 +09:00
parent 74fa828189
commit 3b52e4c386
43 changed files with 236 additions and 235 deletions

View File

@ -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 || []

View File

@ -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 {

View File

@ -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
} }

View File

@ -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 {

View File

@ -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}/>
} }

View File

@ -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>

View File

@ -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'} ${

View File

@ -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'>

View File

@ -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

View File

@ -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

View File

@ -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
} }

View File

@ -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'>

View File

@ -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='권한이 없습니다' />

View File

@ -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} />
} }

View File

@ -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 />
} }

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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, () => {

View File

@ -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>

View File

@ -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
} }

View File

@ -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()

View File

@ -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'>

View File

@ -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

View File

@ -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`}

View File

@ -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}

View File

@ -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'>

View File

@ -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

View File

@ -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>

View File

@ -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'>

View File

@ -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 = [

View File

@ -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}</>
} }

View File

@ -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(() => {

View File

@ -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>

View File

@ -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>

View File

@ -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('')

View File

@ -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}`}

View File

@ -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'>

View File

@ -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

View File

@ -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'

View File

@ -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'>

View File

@ -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