mirror of https://github.com/sylv/micro.git
feat(web): use pandora for ui
This commit is contained in:
parent
97087bf87c
commit
531aeb6a26
|
@ -17,15 +17,19 @@
|
|||
"dependencies": {
|
||||
"@apollo/client": "^3.6.9",
|
||||
"@headlessui/react": "^1.6.1",
|
||||
"@ryanke/pandora": "^0.0.9",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"classnames": "^2.3.1",
|
||||
"concurrently": "^7.2.2",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"dayjs": "^1.11.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"formik": "^2.2.9",
|
||||
"generate-avatar": "1.4.10",
|
||||
"graphql": "^16.5.0",
|
||||
"http-status-codes": "^2.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"nanoid": "^3.3.4",
|
||||
"next": "12.2.0",
|
||||
"postcss": "^8.4.13",
|
||||
|
@ -33,14 +37,12 @@
|
|||
"react": "18.2.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-feather": "^2.0.9",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"swr": "^1.3.0",
|
||||
"tailwindcss": "^3.0.24",
|
||||
"deepmerge": "^4.2.2",
|
||||
"concurrently": "^7.2.2",
|
||||
"lodash": "^4.17.21",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import type { FC } from 'react';
|
||||
import { ArrowLeft } from 'react-feather';
|
||||
import { Link } from './link';
|
||||
|
||||
export const Breadcrumbs: FC<{ to: string; children: string; className?: string }> = ({ to, children, className }) => {
|
||||
const classes = classNames('text-sm text-gray-500 flex items-center gap-1 hover:underline', className);
|
||||
return (
|
||||
<Link href={to} className={classes}>
|
||||
<ArrowLeft className="h-4 w-4" /> {children}
|
||||
</Link>
|
||||
);
|
||||
};
|
|
@ -1,64 +0,0 @@
|
|||
/* eslint-disable react/button-has-type */
|
||||
import classNames from 'classnames';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Link } from './link';
|
||||
import { Spinner } from './spinner';
|
||||
|
||||
export interface ButtonProps extends Omit<HTMLAttributes<HTMLButtonElement | HTMLAnchorElement>, 'prefix' | 'style'> {
|
||||
href?: string;
|
||||
disabled?: boolean;
|
||||
style?: ButtonStyle;
|
||||
loading?: boolean;
|
||||
type?: 'submit' | 'reset' | 'button';
|
||||
}
|
||||
|
||||
export enum ButtonStyle {
|
||||
Primary = 'bg-purple-500 hover:bg-purple-400',
|
||||
Secondary = 'bg-dark-600 hover:bg-dark-900',
|
||||
Disabled = 'bg-dark-300 hover:bg-dark-400',
|
||||
}
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(
|
||||
{ href, disabled, className, type, children, loading, style = ButtonStyle.Primary, onClick, onKeyDown, ...rest },
|
||||
ref
|
||||
) => {
|
||||
if (disabled) style = ButtonStyle.Disabled;
|
||||
const onClickWrap = disabled ? undefined : onClick;
|
||||
const onKeyDownWrap = disabled ? undefined : onKeyDown;
|
||||
const classes = classNames(
|
||||
'flex items-center justify-center gap-2 w-full px-3 py-2 text-sm font-medium transition rounded truncate max-h-[2.65em]',
|
||||
disabled && 'cursor-not-allowed',
|
||||
className,
|
||||
style
|
||||
);
|
||||
|
||||
if (href) {
|
||||
if (ref) {
|
||||
throw new Error('Button cannot have ref and href');
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={href} className={classes} onClick={onClickWrap} onKeyDown={onKeyDownWrap} {...rest}>
|
||||
{children} {loading && <Spinner size="small" />}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
className={classes}
|
||||
disabled={disabled}
|
||||
onClick={onClickWrap}
|
||||
onKeyDown={onKeyDownWrap}
|
||||
style={{ height: '2.5rem' }}
|
||||
{...rest}
|
||||
ref={ref}
|
||||
>
|
||||
{children} {loading && <Spinner size="small" />}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
);
|
|
@ -1,11 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import type { FC, HTMLAttributes } from 'react';
|
||||
|
||||
export const Card: FC<HTMLAttributes<HTMLDivElement>> = ({ className, children, ...rest }) => {
|
||||
const classes = classNames(className, 'p-4 bg-dark-200 rounded');
|
||||
return (
|
||||
<div className={classes} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,30 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
|
||||
export interface ContainerProps {
|
||||
centerX?: boolean;
|
||||
centerY?: boolean;
|
||||
center?: boolean;
|
||||
small?: boolean;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const Container: FC<ContainerProps> = ({
|
||||
center,
|
||||
centerX = center,
|
||||
centerY = center,
|
||||
className,
|
||||
small,
|
||||
children,
|
||||
}) => {
|
||||
const classes = classNames(className, 'px-4 mx-auto', {
|
||||
'sm:max-w-screen-sm md:max-w-screen-md lg:max-w-screen-lg xl:max-w-screen-xl': !small,
|
||||
'flex justify-center flex-col': centerX || centerY,
|
||||
'absolute top-16 bottom-0 right-0 left-0': centerY,
|
||||
'items-center': centerX,
|
||||
'max-w-xs': small,
|
||||
});
|
||||
|
||||
return <div className={classes}>{children}</div>;
|
||||
};
|
|
@ -1,14 +1,11 @@
|
|||
import { Button, ButtonStyle, Container, useAsync, useOnClickOutside } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import { Fragment, memo, useRef, useState } from 'react';
|
||||
import { Crop } from 'react-feather';
|
||||
import { useResendVerificationEmailMutation } from '../../generated/graphql';
|
||||
import { useAsync } from '../../hooks/useAsync';
|
||||
import { useConfig } from '../../hooks/useConfig';
|
||||
import { useOnClickOutside } from '../../hooks/useOnClickOutside';
|
||||
import { usePaths } from '../../hooks/usePaths';
|
||||
import { useUser } from '../../hooks/useUser';
|
||||
import { Button, ButtonStyle } from '../button';
|
||||
import { Container } from '../container';
|
||||
import { Input } from '../input/input';
|
||||
import { Link } from '../link';
|
||||
import { HeaderUser } from './header-user';
|
||||
|
@ -92,7 +89,7 @@ export const Header = memo(() => {
|
|||
<nav className={classes}>
|
||||
<div className="flex items-center">
|
||||
<Link href={paths.home} className="flex">
|
||||
<Crop className="mr-2 text-brand" /> micro
|
||||
<Crop className="mr-2 text-primary" /> micro
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
|
|
|
@ -14,11 +14,11 @@ export const Markdown = memo<{ children: string; className?: string }>(({ childr
|
|||
// remove "" quotes from blockquotes
|
||||
'prose-p:before:content-none prose-p:after:content-none',
|
||||
// make links purple
|
||||
'prose-a:text-brand hover:prose-a:underline prose-a:no-underline',
|
||||
'prose-a:text-primary hover:prose-a:underline prose-a:no-underline',
|
||||
// remove italics from blockquotes
|
||||
'prose-blockquote:font-normal prose-blockquote:not-italic',
|
||||
// make inline `code` blocks purple
|
||||
'prose-code:text-brand',
|
||||
'prose-code:text-primary',
|
||||
className
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Container, Spinner } from '@ryanke/pandora';
|
||||
import type { FC } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { Container } from './container';
|
||||
import { Spinner } from './spinner';
|
||||
import { Title } from '../components/title';
|
||||
|
||||
export const PageLoader: FC<{ title?: string }> = ({ title }) => {
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import type { FC, HTMLAttributes } from 'react';
|
||||
|
||||
export interface SpinnerProps extends HTMLAttributes<SVGElement> {
|
||||
size?: 'small' | 'medium' | 'large';
|
||||
}
|
||||
|
||||
export const Spinner: FC<SpinnerProps> = ({ size, className, ...rest }) => {
|
||||
const classes = classNames('animate-spin', className, {
|
||||
'w-4': size === 'small',
|
||||
'w-6': !size || size === 'medium',
|
||||
'w-9': size === 'large',
|
||||
});
|
||||
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" {...rest} className={classes}>
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
|
||||
<path
|
||||
className="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
|
@ -3,7 +3,7 @@ import type { Language } from 'prism-react-renderer';
|
|||
import { memo } from 'react';
|
||||
import { ChevronDown } from 'react-feather';
|
||||
import languages from '../../data/languages.json';
|
||||
import { useToasts } from '../../hooks/useToasts';
|
||||
import { useToasts } from '@ryanke/pandora';
|
||||
|
||||
export interface SyntaxHighlighterControls {
|
||||
onLanguageChange: (language: Language) => void;
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
import { nanoid } from 'nanoid';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import type { ToastProps } from './toast';
|
||||
import { Toast, TRANSITION_DURATION } from './toast';
|
||||
|
||||
export type ToastContextData = null | ((toast: ToastProps) => void);
|
||||
|
||||
export const ToastContext = React.createContext<ToastContextData>(null);
|
||||
export const ToastWrapper: FC<{ children: ReactNode }> = (props) => {
|
||||
// spread operators on arrays are to fix this
|
||||
// https://stackoverflow.com/questions/56266575/why-is-usestate-not-triggering-re-render
|
||||
const [toasts, setToasts] = useState<(ToastProps & { id: string; timer: NodeJS.Timeout })[]>([]);
|
||||
const createToast = useCallback(
|
||||
(toast: ToastProps) => {
|
||||
if (toasts.some((existing) => existing.text === toast.text)) {
|
||||
// skip duplicate cards
|
||||
return;
|
||||
}
|
||||
|
||||
const timeout = toast.timeout ?? 5000;
|
||||
const id = nanoid(10);
|
||||
const timer = setTimeout(() => {
|
||||
// set removing on toast
|
||||
setToasts((toasts) => {
|
||||
for (const toast of toasts) {
|
||||
if (toast.id !== id) continue;
|
||||
toast.removing = true;
|
||||
}
|
||||
|
||||
return [...toasts];
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// remove toast once transition is complete
|
||||
setToasts((toasts) => toasts.filter((toast) => toast.id !== id));
|
||||
}, TRANSITION_DURATION);
|
||||
}, timeout - TRANSITION_DURATION);
|
||||
|
||||
// create toast
|
||||
setToasts((toasts) => {
|
||||
const data = Object.assign(toast, { id, timer });
|
||||
return [...toasts, data];
|
||||
});
|
||||
},
|
||||
[toasts, setToasts]
|
||||
);
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={createToast}>
|
||||
{props.children}
|
||||
<div className="fixed flex justify-end bottom-5 right-5 left-5">
|
||||
{toasts.map((toast) => (
|
||||
<Toast key={toast.id} removing={toast.removing} {...toast} />
|
||||
))}
|
||||
</div>
|
||||
</ToastContext.Provider>
|
||||
);
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import type { FC } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export interface ToastProps {
|
||||
text: string;
|
||||
error?: boolean;
|
||||
timeout?: number;
|
||||
removing?: boolean;
|
||||
}
|
||||
|
||||
export const TRANSITION_DURATION = 300;
|
||||
export const Toast: FC<ToastProps> = (props) => {
|
||||
const initialClasses = 'opacity-0 scale-90';
|
||||
const animateClasses = 'opacity-100 translate-x-0';
|
||||
const [transition, setTransition] = useState(initialClasses);
|
||||
const classes = classNames('p-4 transition duration-300 rounded shadow-xl select-none w-96', transition, {
|
||||
'bg-violet-500': !props.error,
|
||||
'bg-red-600': props.error,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (props.removing) setTransition(initialClasses);
|
||||
else {
|
||||
// breaks the browser trying to optimise the transition by skipping it because we add it so fast
|
||||
requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
setTransition(animateClasses);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [props.removing]);
|
||||
|
||||
return <div className={classes}>{props.text}</div>;
|
||||
};
|
|
@ -1,9 +1,8 @@
|
|||
import { Container, Spinner } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { Download } from 'react-feather';
|
||||
import { Container } from '../../components/container';
|
||||
import { Section } from '../../components/section';
|
||||
import { Spinner } from '../../components/spinner';
|
||||
import { Toggle } from '../../components/toggle';
|
||||
import { downloadFile } from '../../helpers/download.helper';
|
||||
import { generateConfig } from '../../helpers/generate-config.helper';
|
||||
|
@ -34,7 +33,7 @@ export const ConfigGenerator = () => {
|
|||
|
||||
return (
|
||||
<Section>
|
||||
<Container className="flex flex-col justify-between dots selection:bg-blue-500 py-8">
|
||||
<Container className="flex flex-col justify-between dots selection:bg-purple-600 py-8">
|
||||
<div className="w-full flex-grow">
|
||||
{!config.data && (
|
||||
<div className="flex items-center justify-center w-full h-full py-10">
|
||||
|
@ -55,7 +54,7 @@ export const ConfigGenerator = () => {
|
|||
>
|
||||
<Toggle
|
||||
selected={embedded}
|
||||
backgroundColour="bg-blue-500"
|
||||
backgroundColour="bg-purple-600"
|
||||
onChange={({ value }) => setEmbedded(value)}
|
||||
options={[
|
||||
{
|
||||
|
@ -75,7 +74,7 @@ export const ConfigGenerator = () => {
|
|||
>
|
||||
<Toggle
|
||||
selected={pasteShortcut}
|
||||
backgroundColour="bg-blue-500"
|
||||
backgroundColour="bg-purple-600"
|
||||
onChange={({ value }) => setPasteShortcut(value)}
|
||||
options={[
|
||||
{
|
||||
|
@ -96,8 +95,8 @@ export const ConfigGenerator = () => {
|
|||
const isSelected = selectedHosts.includes(host.normalised);
|
||||
const classes = classNames(
|
||||
'rounded px-2 py-1 truncate transition border border-transparent',
|
||||
isSelected && 'bg-blue-500 text-white',
|
||||
!isSelected && 'text-gray-400 bg-dark-100 hover:bg-gray-800 hover:text-white'
|
||||
isSelected && 'bg-purple-600 text-white',
|
||||
!isSelected && 'text-gray-400 bg-dark-100 hover:bg-dark-200 hover:text-white'
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -127,7 +126,7 @@ export const ConfigGenerator = () => {
|
|||
onClick={download}
|
||||
className={classNames(
|
||||
'mt-8 ml-auto flex items-center gap-1',
|
||||
downloadable ? 'text-blue-400 hover:underline' : 'text-gray-700 cursor-not-allowed'
|
||||
downloadable ? 'text-purple-400 hover:underline' : 'text-gray-700 cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
download config <Download className="h-3.5 w-3.5" />
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Breadcrumbs, Card } from '@ryanke/pandora';
|
||||
import type { FC } from 'react';
|
||||
import { Fragment } from 'react';
|
||||
import { Breadcrumbs } from '../../components/breadcrumbs';
|
||||
import { Card } from '../../components/card';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
import { Toggle } from '../../components/toggle';
|
||||
import { useGetFilesQuery, useGetPastesQuery } from '../../generated/graphql';
|
||||
|
@ -29,7 +28,7 @@ export const FileList: FC = () => {
|
|||
<Fragment>
|
||||
<div className="flex justify-between gap-2 mb-6">
|
||||
<div>
|
||||
<Breadcrumbs to="/">Home</Breadcrumbs>
|
||||
<Breadcrumbs href="/">Home</Breadcrumbs>
|
||||
<h2 className="capitalize font-bold text-2xl">My {filter}</h2>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useRouter } from 'next/router';
|
|||
import type { FC } from 'react';
|
||||
import { Fragment, useCallback, useEffect } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { Button } from '../components/button';
|
||||
import { Button } from '@ryanke/pandora';
|
||||
import { Input } from '../components/input/input';
|
||||
import { useUser } from '../hooks/useUser';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Form, Formik } from 'formik';
|
|||
import type { FC } from 'react';
|
||||
import { Fragment, useMemo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { Button } from '../components/button';
|
||||
import { Button } from '@ryanke/pandora';
|
||||
import { Input } from '../components/input/input';
|
||||
import { useConfig } from '../hooks/useConfig';
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
import { useState } from 'react';
|
||||
import { getErrorMessage } from '../helpers/get-error-message.helper';
|
||||
import { useToasts } from './useToasts';
|
||||
|
||||
export function useAsync<T, X extends any[]>(handler: (...params: X) => Promise<T>) {
|
||||
const [promise, setPromise] = useState<Promise<T> | null>(null);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [result, setResult] = useState<T | null>(null);
|
||||
const createToast = useToasts();
|
||||
const running = !!promise;
|
||||
const run = async (...params: X) => {
|
||||
if (promise) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
try {
|
||||
const promise = handler(...params);
|
||||
setPromise(promise);
|
||||
setError(null);
|
||||
const result = await promise;
|
||||
setResult(result);
|
||||
} catch (error: any) {
|
||||
const message = getErrorMessage(error);
|
||||
if (message) {
|
||||
createToast({
|
||||
error: true,
|
||||
text: message,
|
||||
});
|
||||
}
|
||||
|
||||
setError(error);
|
||||
throw error;
|
||||
} finally {
|
||||
setPromise(null);
|
||||
}
|
||||
};
|
||||
|
||||
return [run, running, error, result] as const;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
export function useOnClickOutside(ref: React.MutableRefObject<any>, handler: () => void) {
|
||||
useEffect(() => {
|
||||
const onClick = (event: Event) => {
|
||||
if (!ref.current || ref.current.contains(event.target)) return;
|
||||
handler();
|
||||
};
|
||||
|
||||
const onKeyPress = (event: KeyboardEvent) => {
|
||||
if (event.key !== 'Escape') return;
|
||||
handler();
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', onClick);
|
||||
document.addEventListener('touchstart', onClick);
|
||||
document.addEventListener('keydown', onKeyPress);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', onClick);
|
||||
document.removeEventListener('touchstart', onClick);
|
||||
document.removeEventListener('keydown', onKeyPress);
|
||||
};
|
||||
}, [ref, handler]);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { useContext } from 'react';
|
||||
import { ToastContext } from '../components/toast/toast-wrapper';
|
||||
|
||||
export const useToasts = () => {
|
||||
const createToast = useContext(ToastContext);
|
||||
if (!createToast) {
|
||||
// todo: this should be an error, but it seems like it can be undefined.
|
||||
// maybe due to concurrent rendering? idk shit about fuck.
|
||||
return () => undefined;
|
||||
}
|
||||
|
||||
return createToast;
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
import { useAsync } from '@ryanke/pandora';
|
||||
import Router, { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
import { resetClient } from '../apollo';
|
||||
import { useGetUserQuery } from '../generated/graphql';
|
||||
import { http } from '../helpers/http.helper';
|
||||
import { useAsync } from './useAsync';
|
||||
|
||||
interface LoginData {
|
||||
username: string;
|
||||
|
|
|
@ -4,7 +4,7 @@ import Head from 'next/head';
|
|||
import { useApollo } from '../apollo';
|
||||
import { Header } from '../components/header/header';
|
||||
import { Title } from '../components/title';
|
||||
import { ToastWrapper } from '../components/toast/toast-wrapper';
|
||||
import { ToastProvider } from '@ryanke/pandora';
|
||||
import '../styles/globals.css';
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
|
@ -17,12 +17,12 @@ export default function App({ Component, pageProps }: AppProps) {
|
|||
<meta property="og:site_name" content="micro" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
</Head>
|
||||
<ToastWrapper>
|
||||
<ToastProvider>
|
||||
<Header />
|
||||
<div className="py-4 md:py-16">
|
||||
<Component {...pageProps} />
|
||||
</div>
|
||||
</ToastWrapper>
|
||||
</ToastProvider>
|
||||
</ApolloProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Container } from '../components/container';
|
||||
import { Container } from '@ryanke/pandora';
|
||||
import { Link } from '../components/link';
|
||||
import { Title } from '../components/title';
|
||||
import { getErrorMessage } from '../helpers/get-error-message.helper';
|
||||
|
@ -26,7 +26,7 @@ export default function Error(props: ErrorProps) {
|
|||
<Title>{message}</Title>
|
||||
<h1 className="mb-4 text-4xl font-fold">{lenny}</h1>
|
||||
<p className="text-lg">{message}</p>
|
||||
<Link className="text-brand" href={paths.home}>
|
||||
<Link className="text-primary" href={paths.home}>
|
||||
Go Home
|
||||
</Link>
|
||||
</Container>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Container } from '../../components/container';
|
||||
import { Container } from '@ryanke/pandora';
|
||||
import { FileList } from '../../containers/file-list/file-list';
|
||||
import { useUser } from '../../hooks/useUser';
|
||||
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import { Container } from '../../components/container';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
|
||||
import { Breadcrumbs } from '../../components/breadcrumbs';
|
||||
import { Breadcrumbs, Container, useAsync } from '@ryanke/pandora';
|
||||
import { Input } from '../../components/input/input';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
import { Title } from '../../components/title';
|
||||
import { ConfigGenerator } from '../../containers/config-generator/config-generator';
|
||||
import { useRefreshTokenMutation } from '../../generated/graphql';
|
||||
import { useAsync } from '../../hooks/useAsync';
|
||||
import { useConfig } from '../../hooks/useConfig';
|
||||
import { useUser } from '../../hooks/useUser';
|
||||
|
||||
|
@ -29,7 +26,7 @@ export default function Preferences() {
|
|||
return (
|
||||
<Container>
|
||||
<Title>Preferences</Title>
|
||||
<Breadcrumbs to="/dashboard" className="mb-4">
|
||||
<Breadcrumbs href="/dashboard" className="mb-4">
|
||||
Dashboard
|
||||
</Breadcrumbs>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Container, Spinner, useAsync, useToasts } from '@ryanke/pandora';
|
||||
import classNames from 'classnames';
|
||||
import copyToClipboard from 'copy-to-clipboard';
|
||||
import type { GetServerSidePropsContext } from 'next';
|
||||
|
@ -6,16 +7,12 @@ import type { FC, ReactNode } from 'react';
|
|||
import { useState } from 'react';
|
||||
import { Download, Share, Trash } from 'react-feather';
|
||||
import { addStateToPageProps, initializeApollo } from '../../apollo';
|
||||
import { Container } from '../../components/container';
|
||||
import { Embed } from '../../components/embed/embed';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
import { Spinner } from '../../components/spinner';
|
||||
import { Title } from '../../components/title';
|
||||
import { ConfigDocument, GetFileDocument, useDeleteFileMutation, useGetFileQuery } from '../../generated/graphql';
|
||||
import { downloadUrl } from '../../helpers/download.helper';
|
||||
import { useAsync } from '../../hooks/useAsync';
|
||||
import { useQueryState } from '../../hooks/useQueryState';
|
||||
import { useToasts } from '../../hooks/useToasts';
|
||||
import ErrorPage from '../_error';
|
||||
|
||||
const FileOption: FC<{ children: ReactNode; className?: string; onClick: () => void }> = ({
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Container } from '../components/container';
|
||||
import { Spinner } from '../components/spinner';
|
||||
import { Spinner, Container } from '@ryanke/pandora';
|
||||
import { useConfig } from '../hooks/useConfig';
|
||||
|
||||
export default function Home() {
|
||||
|
@ -14,7 +13,7 @@ export default function Home() {
|
|||
<p className="mb-2 text-gray-400">
|
||||
An invite-only file sharing and paste service with vanity domains and a ShareX compatible endpoint. Sign in to
|
||||
download a generated ShareX configuration. You can view the source code{' '}
|
||||
<a className="text-brand" href="https://github.com/sylv/micro" target="_blank" rel="noreferrer">
|
||||
<a className="text-primary" href="https://github.com/sylv/micro" target="_blank" rel="noreferrer">
|
||||
here.
|
||||
</a>
|
||||
</p>
|
||||
|
@ -27,7 +26,7 @@ export default function Home() {
|
|||
{config.data && (
|
||||
<p className="text-gray-400">
|
||||
To get an account or get a file taken down, email{' '}
|
||||
<a href={`mailto:${config.data.inquiriesEmail}`} className="text-brand">
|
||||
<a href={`mailto:${config.data.inquiriesEmail}`} className="text-primary">
|
||||
{config.data.inquiriesEmail}
|
||||
</a>
|
||||
.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Container, useAsync, useToasts } from '@ryanke/pandora';
|
||||
import Router, { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
import { Container } from '../../components/container';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
import { Time } from '../../components/time';
|
||||
import { Title } from '../../components/title';
|
||||
|
@ -8,9 +8,7 @@ import type { SignupData } from '../../containers/signup-form';
|
|||
import { SignupForm } from '../../containers/signup-form';
|
||||
import { useCreateUserMutation, useGetInviteQuery } from '../../generated/graphql';
|
||||
import { getErrorMessage } from '../../helpers/get-error-message.helper';
|
||||
import { useAsync } from '../../hooks/useAsync';
|
||||
import { useConfig } from '../../hooks/useConfig';
|
||||
import { useToasts } from '../../hooks/useToasts';
|
||||
import ErrorPage from '../_error';
|
||||
|
||||
export default function Invite() {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Container, useToasts } from '@ryanke/pandora';
|
||||
import { useEffect } from 'react';
|
||||
import { Container } from '../components/container';
|
||||
import { Title } from '../components/title';
|
||||
import { LoginForm } from '../containers/login-form';
|
||||
import { useToasts } from '../hooks/useToasts';
|
||||
|
||||
export default function Login() {
|
||||
const createToast = useToasts();
|
||||
|
@ -17,7 +16,7 @@ export default function Login() {
|
|||
text: 'Your account has been verified.',
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
}, [createToast]);
|
||||
|
||||
return (
|
||||
<Container center small>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { Button, Container } from '@ryanke/pandora';
|
||||
import type { GetServerSidePropsContext } from 'next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { BookOpen, Clock, Trash } from 'react-feather';
|
||||
import { addStateToPageProps, initializeApollo } from '../../apollo';
|
||||
import { Button } from '../../components/button';
|
||||
import { Container } from '../../components/container';
|
||||
import { Embed } from '../../components/embed/embed';
|
||||
import { PageLoader } from '../../components/page-loader';
|
||||
import { Time } from '../../components/time';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Button, Container } from '@ryanke/pandora';
|
||||
import { Form, Formik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import { Button } from '../../components/button';
|
||||
import { Container } from '../../components/container';
|
||||
import { Checkbox } from '../../components/input/checkbox';
|
||||
import { Input } from '../../components/input/input';
|
||||
import { Select } from '../../components/input/select';
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Button, Container } from '@ryanke/pandora';
|
||||
import { Form, Formik } from 'formik';
|
||||
import { useState } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { Button } from '../components/button';
|
||||
import { Container } from '../components/container';
|
||||
import { Input } from '../components/input/input';
|
||||
import { Select } from '../components/input/select';
|
||||
import { useShortenMutation } from '../generated/graphql';
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
import { Button, Card, Container, Spinner, useToasts } from '@ryanke/pandora';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { ChangeEventHandler, DragEventHandler } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { Upload as UploadIcon } from 'react-feather';
|
||||
import { Button } from '../components/button';
|
||||
import { Card } from '../components/card';
|
||||
import { Container } from '../components/container';
|
||||
import { Select } from '../components/input/select';
|
||||
import { PageLoader } from '../components/page-loader';
|
||||
import { Spinner } from '../components/spinner';
|
||||
import { Title } from '../components/title';
|
||||
import { getErrorMessage } from '../helpers/get-error-message.helper';
|
||||
import { http } from '../helpers/http.helper';
|
||||
import { replaceUsername } from '../helpers/replace-username.helper';
|
||||
import { useConfig } from '../hooks/useConfig';
|
||||
import { useToasts } from '../hooks/useToasts';
|
||||
import { useUser } from '../hooks/useUser';
|
||||
|
||||
interface CreateFileResponse {
|
||||
|
@ -138,7 +134,7 @@ export default function Upload() {
|
|||
<Button onClick={handleUpload}>Upload</Button>
|
||||
</div>
|
||||
<span
|
||||
className="mt-4 cursor-pointer text-brand"
|
||||
className="mt-4 cursor-pointer text-primary"
|
||||
onClick={() => {
|
||||
setFile(null);
|
||||
}}
|
||||
|
@ -172,7 +168,7 @@ export default function Upload() {
|
|||
)}
|
||||
</h1>
|
||||
<p className="text-gray-400 select-none">
|
||||
Or <span className="text-brand">click here</span> to select a file.
|
||||
Or <span className="text-primary">click here</span> to select a file.
|
||||
</p>
|
||||
</Card>
|
||||
</Container>
|
||||
|
|
|
@ -2,24 +2,6 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--brand: rgb(167, 139, 250);
|
||||
}
|
||||
|
||||
#__next {
|
||||
@apply h-screen;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply text-white;
|
||||
background-color: #141414;
|
||||
}
|
||||
|
||||
::selection {
|
||||
@apply bg-violet-600;
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background: inherit;
|
||||
height: 14px;
|
||||
|
@ -48,15 +30,6 @@ body {
|
|||
border-color: transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-y: overlay;
|
||||
}
|
||||
|
||||
.dots {
|
||||
background-image: radial-gradient(black 1px, transparent 0);
|
||||
background-size: 40px 40px;
|
||||
}
|
||||
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
white-space: normal !important;
|
||||
|
|
|
@ -1,47 +1,6 @@
|
|||
const pandora = require('@ryanke/pandora/plugin');
|
||||
|
||||
module.exports = {
|
||||
content: ['./src/**/*.tsx'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: 'var(--brand)',
|
||||
gray: {
|
||||
100: '#f5f5f5',
|
||||
200: '#eeeeee',
|
||||
300: '#e0e0e0',
|
||||
400: '#bdbdbd',
|
||||
500: '#9e9e9e',
|
||||
600: '#757575',
|
||||
700: '#616161',
|
||||
800: '#424242',
|
||||
900: '#212121',
|
||||
},
|
||||
dark: {
|
||||
100: '#121212',
|
||||
200: '#1d1d1d',
|
||||
300: '#212121',
|
||||
400: '#242424',
|
||||
500: '#272727',
|
||||
600: '#2c2c2c',
|
||||
700: '#2d2d2d',
|
||||
800: '#333333',
|
||||
900: '#353535',
|
||||
999: '#373737',
|
||||
},
|
||||
blue: {
|
||||
DEFAULT: '#0067F1',
|
||||
50: '#AACEFF',
|
||||
100: '#95C2FF',
|
||||
200: '#6CABFF',
|
||||
300: '#4494FF',
|
||||
400: '#1B7CFF',
|
||||
500: '#0067F1',
|
||||
600: '#004FB9',
|
||||
700: '#003781',
|
||||
800: '#001F49',
|
||||
900: '#000711',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require('@tailwindcss/typography')],
|
||||
content: ['./src/**/*.tsx', pandora.content],
|
||||
plugins: [require('@tailwindcss/typography'), pandora.plugin],
|
||||
};
|
||||
|
|
|
@ -180,6 +180,7 @@ importers:
|
|||
'@graphql-codegen/typescript-operations': 2.4.3
|
||||
'@graphql-codegen/typescript-react-apollo': 3.2.17
|
||||
'@headlessui/react': ^1.6.1
|
||||
'@ryanke/pandora': ^0.0.9
|
||||
'@sylo-digital/scripts': ^1.0.2
|
||||
'@tailwindcss/typography': ^0.5.2
|
||||
'@types/lodash': ^4.14.182
|
||||
|
@ -203,6 +204,7 @@ importers:
|
|||
react: 18.2.0
|
||||
react-dom: ^18.1.0
|
||||
react-feather: ^2.0.9
|
||||
react-icons: ^4.4.0
|
||||
react-markdown: ^8.0.3
|
||||
rehype-raw: ^6.1.1
|
||||
remark-gfm: ^3.0.1
|
||||
|
@ -213,6 +215,7 @@ importers:
|
|||
dependencies:
|
||||
'@apollo/client': 3.6.9_aez2jvt6lsvokp3l4ousdbdxf4
|
||||
'@headlessui/react': 1.6.5_biqbaboplfbrettd7655fr4n2y
|
||||
'@ryanke/pandora': 0.0.9_d3a4q72qanlbr76d5qpg5hrygu
|
||||
'@tailwindcss/typography': 0.5.2_tailwindcss@3.1.4
|
||||
autoprefixer: 10.4.7_postcss@8.4.14
|
||||
classnames: 2.3.1
|
||||
|
@ -232,6 +235,7 @@ importers:
|
|||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
react-feather: 2.0.10_react@18.2.0
|
||||
react-icons: 4.4.0_react@18.2.0
|
||||
react-markdown: 8.0.3_luyos4mouogwq6z3wafb3re4ce
|
||||
rehype-raw: 6.1.1
|
||||
remark-gfm: 3.0.1
|
||||
|
@ -1594,6 +1598,7 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
dev: true
|
||||
|
||||
/@endemolshinegroup/cosmiconfig-typescript-loader/3.0.2_zmjss6mecb4soo3dpdlecld3xa:
|
||||
resolution: {integrity: sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==}
|
||||
|
@ -2349,7 +2354,6 @@ packages:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/@jest/core/28.1.2_ts-node@10.8.2:
|
||||
resolution: {integrity: sha512-Xo4E+Sb/nZODMGOPt2G3cMmCBqL4/W2Ijwr7/mrXlq4jdJwcFQ/9KrrJZT2adQRk2otVBXXOz1GRQ4Z5iOgvRQ==}
|
||||
|
@ -2392,6 +2396,7 @@ packages:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/@jest/create-cache-key-function/27.5.1:
|
||||
resolution: {integrity: sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==}
|
||||
|
@ -2657,6 +2662,7 @@ packages:
|
|||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.0.8
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
dev: true
|
||||
|
||||
/@mikro-orm/cli/5.2.2_4k2cb7nrrwahnwnvazylxfgb44:
|
||||
resolution: {integrity: sha512-IRMcfVFF6edBX2lQsKswMAjw6ILOvwnLT0cMJziknVMuPop/ckaWxlA5r4Uu1BorNtoHf52qB9i3r5YwEe9qAQ==}
|
||||
|
@ -3451,6 +3457,19 @@ packages:
|
|||
colors: 1.2.5
|
||||
string-argv: 0.3.1
|
||||
|
||||
/@ryanke/pandora/0.0.9_d3a4q72qanlbr76d5qpg5hrygu:
|
||||
resolution: {integrity: sha512-MV5LDSS52OkDqmeXqlEF1uRBq51q3kTXBbX9ggF61UIJn83jLGleuy8sLj/K8zWvBmF8K+/yVU/VlvsUnSV/jQ==}
|
||||
peerDependencies:
|
||||
react: ^18.2.0
|
||||
tailwindcss: ^3.1.6
|
||||
dependencies:
|
||||
clsx: 1.2.1
|
||||
nanoid: 4.0.0
|
||||
react: 18.2.0
|
||||
react-feather: 2.0.10_react@18.2.0
|
||||
tailwindcss: 3.1.4
|
||||
dev: false
|
||||
|
||||
/@ryanke/venera/0.0.2_33pkbfq2kwsj5qeeqstpf4i2q4:
|
||||
resolution: {integrity: sha512-EfT55TubMsI3SDLH9S8nDGPsuZlWom0DB9jn+AUdBYQWqZJVKRs5xXtePGo8NDPJ6Jk31q+AM3uNXFkKZXFTHw==}
|
||||
peerDependencies:
|
||||
|
@ -3529,6 +3548,7 @@ packages:
|
|||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-android-arm64/1.2.204:
|
||||
|
@ -3545,6 +3565,7 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-arm64/1.2.204:
|
||||
|
@ -3561,6 +3582,7 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-x64/1.2.204:
|
||||
|
@ -3577,6 +3599,7 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-freebsd-x64/1.2.204:
|
||||
|
@ -3593,6 +3616,7 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm-gnueabihf/1.2.204:
|
||||
|
@ -3609,6 +3633,7 @@ packages:
|
|||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-gnu/1.2.204:
|
||||
|
@ -3625,6 +3650,7 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-musl/1.2.204:
|
||||
|
@ -3641,6 +3667,7 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-gnu/1.2.204:
|
||||
|
@ -3657,6 +3684,7 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-musl/1.2.204:
|
||||
|
@ -3673,6 +3701,7 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-arm64-msvc/1.2.204:
|
||||
|
@ -3689,6 +3718,7 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-ia32-msvc/1.2.204:
|
||||
|
@ -3705,6 +3735,7 @@ packages:
|
|||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-x64-msvc/1.2.204:
|
||||
|
@ -3721,6 +3752,7 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core/1.2.204:
|
||||
|
@ -3760,6 +3792,7 @@ packages:
|
|||
'@swc/core-win32-arm64-msvc': 1.2.208
|
||||
'@swc/core-win32-ia32-msvc': 1.2.208
|
||||
'@swc/core-win32-x64-msvc': 1.2.208
|
||||
dev: true
|
||||
|
||||
/@swc/helpers/0.4.2:
|
||||
resolution: {integrity: sha512-556Az0VX7WR6UdoTn4htt/l3zPQ7bsQWK+HqdG4swV7beUCxo/BqmvbOpUkTIm/9ih86LIf1qsUnywNL3obGHw==}
|
||||
|
@ -3802,7 +3835,7 @@ packages:
|
|||
eslint: 8.19.0
|
||||
eslint-config-galex: 3.6.5_eslint@8.19.0+jest@28.1.2
|
||||
eslint-plugin-es: 4.1.0_eslint@8.19.0
|
||||
jest: 28.1.2_qv5kk3vgcyi3feqo7l5zvvzluy
|
||||
jest: 28.1.2_@types+node@16.11.43
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
|
@ -3866,15 +3899,19 @@ packages:
|
|||
|
||||
/@tsconfig/node10/1.0.9:
|
||||
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node12/1.0.11:
|
||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node14/1.0.3:
|
||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
||||
dev: true
|
||||
|
||||
/@tsconfig/node16/1.0.3:
|
||||
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
|
||||
dev: true
|
||||
|
||||
/@types/accepts/1.3.5:
|
||||
resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==}
|
||||
|
@ -4520,6 +4557,7 @@ packages:
|
|||
/acorn-walk/8.2.0:
|
||||
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: true
|
||||
|
||||
/acorn/7.4.1:
|
||||
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
|
||||
|
@ -4983,6 +5021,7 @@ packages:
|
|||
|
||||
/arg/4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
dev: true
|
||||
|
||||
/arg/5.0.2:
|
||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||
|
@ -5830,6 +5869,11 @@ packages:
|
|||
engines: {node: '>=0.8'}
|
||||
dev: true
|
||||
|
||||
/clsx/1.2.1:
|
||||
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/co/4.6.0:
|
||||
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
|
||||
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
|
||||
|
@ -6035,6 +6079,7 @@ packages:
|
|||
|
||||
/create-require/1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
dev: true
|
||||
|
||||
/cron/1.8.2:
|
||||
resolution: {integrity: sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==}
|
||||
|
@ -6336,6 +6381,7 @@ packages:
|
|||
/diff/4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
dev: true
|
||||
|
||||
/diff/5.1.0:
|
||||
resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
|
||||
|
@ -6976,7 +7022,7 @@ packages:
|
|||
'@typescript-eslint/eslint-plugin': 5.12.0_byxz3mnn3ms3gbtbci7fo4cm6q
|
||||
'@typescript-eslint/utils': 5.29.0_m32fwjepeyylyephxtubzxm4ui
|
||||
eslint: 8.19.0
|
||||
jest: 28.1.2_qv5kk3vgcyi3feqo7l5zvvzluy
|
||||
jest: 28.1.2_@types+node@16.11.43
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
@ -8946,7 +8992,6 @@ packages:
|
|||
- '@types/node'
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/jest-cli/28.1.2_qv5kk3vgcyi3feqo7l5zvvzluy:
|
||||
resolution: {integrity: sha512-l6eoi5Do/IJUXAFL9qRmDiFpBeEJAnjJb1dcd9i/VWfVWbp3mJhuH50dNtX67Ali4Ecvt4eBkWb4hXhPHkAZTw==}
|
||||
|
@ -8974,6 +9019,7 @@ packages:
|
|||
- '@types/node'
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/jest-config/28.1.2_4maxphccb5fztufhofwcslq6fm:
|
||||
resolution: {integrity: sha512-g6EfeRqddVbjPVBVY4JWpUY4IvQoFRIZcv4V36QkqzE0IGhEC/VkugFeBMAeUE7PRgC8KJF0yvJNDeQRbamEVA==}
|
||||
|
@ -9013,6 +9059,7 @@ packages:
|
|||
ts-node: 10.8.2_pbcylixk5f7tclmtradmulh4qa
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/jest-config/28.1.2_@types+node@16.11.43:
|
||||
resolution: {integrity: sha512-g6EfeRqddVbjPVBVY4JWpUY4IvQoFRIZcv4V36QkqzE0IGhEC/VkugFeBMAeUE7PRgC8KJF0yvJNDeQRbamEVA==}
|
||||
|
@ -9051,7 +9098,6 @@ packages:
|
|||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/jest-config/28.1.2_qv5kk3vgcyi3feqo7l5zvvzluy:
|
||||
resolution: {integrity: sha512-g6EfeRqddVbjPVBVY4JWpUY4IvQoFRIZcv4V36QkqzE0IGhEC/VkugFeBMAeUE7PRgC8KJF0yvJNDeQRbamEVA==}
|
||||
|
@ -9091,6 +9137,7 @@ packages:
|
|||
ts-node: 10.8.2_pbcylixk5f7tclmtradmulh4qa
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/jest-diff/28.1.1:
|
||||
resolution: {integrity: sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg==}
|
||||
|
@ -9430,7 +9477,6 @@ packages:
|
|||
- '@types/node'
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/jest/28.1.2_qv5kk3vgcyi3feqo7l5zvvzluy:
|
||||
resolution: {integrity: sha512-Tuf05DwLeCh2cfWCQbcz9UxldoDyiR1E9Igaei5khjonKncYdc6LDfynKCEWozK0oLE3GD+xKAo2u8x/0s6GOg==}
|
||||
|
@ -9450,6 +9496,7 @@ packages:
|
|||
- '@types/node'
|
||||
- supports-color
|
||||
- ts-node
|
||||
dev: true
|
||||
|
||||
/joycon/3.1.1:
|
||||
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
||||
|
@ -9979,6 +10026,7 @@ packages:
|
|||
|
||||
/make-error/1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
dev: true
|
||||
|
||||
/make-fetch-happen/8.0.14:
|
||||
resolution: {integrity: sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==}
|
||||
|
@ -10682,6 +10730,12 @@ packages:
|
|||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/nanoid/4.0.0:
|
||||
resolution: {integrity: sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==}
|
||||
engines: {node: ^14 || ^16 || >=18}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/nanomatch/1.2.13:
|
||||
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -11686,6 +11740,14 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-icons/4.4.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-is/16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
|
@ -13074,6 +13136,7 @@ packages:
|
|||
typescript: 4.7.4
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/ts-node/9.1.1_typescript@4.7.4:
|
||||
resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==}
|
||||
|
@ -13390,6 +13453,7 @@ packages:
|
|||
resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ua-parser-js/0.7.31:
|
||||
resolution: {integrity: sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==}
|
||||
|
@ -13622,6 +13686,7 @@ packages:
|
|||
|
||||
/v8-compile-cache-lib/3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
dev: true
|
||||
|
||||
/v8-compile-cache/2.3.0:
|
||||
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
|
||||
|
@ -13969,6 +14034,7 @@ packages:
|
|||
/yn/3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/yocto-queue/0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
|
|
Loading…
Reference in New Issue