mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-16 22:46:04 +01:00
refactor: some adjustments
This commit is contained in:
@@ -1,9 +1,30 @@
|
|||||||
{
|
{
|
||||||
"extends": ["next", "next/core-web-vitals", "plugin:prettier/recommended"],
|
"extends": [
|
||||||
"plugins": ["prettier", "simple-import-sort"],
|
"next",
|
||||||
|
"next/core-web-vitals",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
"plugin:import/recommended",
|
||||||
|
"plugin:import/typescript"
|
||||||
|
],
|
||||||
|
"plugins": ["prettier", "import"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"prettier/prettier": "error",
|
"prettier/prettier": "error",
|
||||||
"simple-import-sort/imports": "error",
|
"import/order": [
|
||||||
"simple-import-sort/exports": "error"
|
"error",
|
||||||
|
{
|
||||||
|
"groups": [
|
||||||
|
"builtin",
|
||||||
|
"external",
|
||||||
|
"internal",
|
||||||
|
"parent",
|
||||||
|
"sibling",
|
||||||
|
"index",
|
||||||
|
"object",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"newlines-between": "always"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@next/next/no-page-custom-font": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
package.json
60
package.json
@@ -19,50 +19,50 @@
|
|||||||
"prisma:seed": "prisma db seed"
|
"prisma:seed": "prisma db seed"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^3.6.0",
|
"@prisma/client": "3.6.0",
|
||||||
"axios": "^0.24.0",
|
"axios": "0.24.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"cuid": "^2.1.8",
|
"cuid": "2.1.8",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "10.0.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "4.17.21",
|
||||||
"next": "12.0.7",
|
"next": "12.0.7",
|
||||||
"next-connect": "^0.11.0",
|
"next-connect": "0.11.0",
|
||||||
"nookies": "^2.5.2",
|
"nookies": "2.5.2",
|
||||||
"polished": "^4.1.3",
|
"polished": "4.1.3",
|
||||||
"rc-slider": "^9.7.5",
|
"rc-slider": "9.7.5",
|
||||||
"react": "^17.0.2",
|
"react": "17.0.2",
|
||||||
"react-collapsible": "^2.8.4",
|
"react-collapsible": "2.8.4",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "2.19.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-icons": "^4.3.1",
|
"react-icons": "4.3.1",
|
||||||
"sharp": "^0.29.3",
|
"sharp": "0.29.3",
|
||||||
"styled-components": "^5.3.3"
|
"styled-components": "5.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "15.0.0",
|
"@commitlint/cli": "15.0.0",
|
||||||
"@commitlint/config-conventional": "15.0.0",
|
"@commitlint/config-conventional": "15.0.0",
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "2.4.2",
|
||||||
"@types/jsonwebtoken": "^8.5.6",
|
"@types/jsonwebtoken": "8.5.6",
|
||||||
"@types/lodash": "^4.14.178",
|
"@types/lodash": "4.14.178",
|
||||||
"@types/node": "^17.0.0",
|
"@types/node": "17.0.0",
|
||||||
"@types/react": "17.0.37",
|
"@types/react": "17.0.37",
|
||||||
"@types/react-color": "^3.0.6",
|
"@types/react-color": "3.0.6",
|
||||||
"@types/styled-components": "^5.1.18",
|
"@types/styled-components": "5.1.18",
|
||||||
"babel-plugin-styled-components": "^2.0.2",
|
"babel-plugin-styled-components": "2.0.2",
|
||||||
"eslint": "8.5.0",
|
"eslint": "8.5.0",
|
||||||
"eslint-config-next": "12.0.7",
|
"eslint-config-next": "12.0.7",
|
||||||
"eslint-config-prettier": "8.3.0",
|
"eslint-config-prettier": "8.3.0",
|
||||||
|
"eslint-plugin-import": "2.25.3",
|
||||||
"eslint-plugin-prettier": "4.0.0",
|
"eslint-plugin-prettier": "4.0.0",
|
||||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
|
||||||
"husky": "7.0.4",
|
"husky": "7.0.4",
|
||||||
"lint-staged": "12.1.3",
|
"lint-staged": "12.1.3",
|
||||||
"prettier": "2.5.1",
|
"prettier": "2.5.1",
|
||||||
"pretty-quick": "3.1.2",
|
"pretty-quick": "3.1.2",
|
||||||
"prisma": "^3.6.0",
|
"prisma": "3.6.0",
|
||||||
"react-is": "^17.0.2",
|
"react-is": "17.0.2",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "10.4.0",
|
||||||
"typescript": "^4.5.4"
|
"typescript": "4.5.4"
|
||||||
},
|
},
|
||||||
"prisma": {
|
"prisma": {
|
||||||
"seed": "ts-node prisma/seed.ts"
|
"seed": "ts-node prisma/seed.ts"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ async function main() {
|
|||||||
name: 'John Doe',
|
name: 'John Doe',
|
||||||
description:
|
description:
|
||||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquam consectetur, nisl nunc aliquet nunc, euismod aliquam nunc nisl euismod.',
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquam consectetur, nisl nunc aliquet nunc, euismod aliquam nunc nisl euismod.',
|
||||||
font: '"Roboto", sans-serif',
|
font: 'oswald',
|
||||||
buttonBorderRadius: '4',
|
buttonBorderRadius: '4',
|
||||||
colors: {
|
colors: {
|
||||||
texts: '#e11d48',
|
texts: '#e11d48',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useData } from '../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
|
|
||||||
import { Wrapper } from './styles'
|
import { Wrapper } from './styles'
|
||||||
|
|
||||||
export function Avatar() {
|
export function Avatar() {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ type ButtonProps = {
|
|||||||
backgroundColor?: string
|
backgroundColor?: string
|
||||||
borderColor?: string
|
borderColor?: string
|
||||||
borderRadius?: string
|
borderRadius?: string
|
||||||
font?: string
|
|
||||||
size?: 'small' | 'medium'
|
size?: 'small' | 'medium'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +14,6 @@ export const Button = styled.button.attrs((props: ButtonProps) => ({
|
|||||||
backgroundColor: props.backgroundColor || '#e11d48',
|
backgroundColor: props.backgroundColor || '#e11d48',
|
||||||
borderColor: props.borderColor || '#e11d48',
|
borderColor: props.borderColor || '#e11d48',
|
||||||
borderRadius: props.borderRadius || 8,
|
borderRadius: props.borderRadius || 8,
|
||||||
font: props.font || 'inherit',
|
|
||||||
size: props.size || 'medium'
|
size: props.size || 'medium'
|
||||||
}))<ButtonProps>`
|
}))<ButtonProps>`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -23,7 +21,6 @@ export const Button = styled.button.attrs((props: ButtonProps) => ({
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
font-family: ${({ font }) => font};
|
|
||||||
color: ${({ labelColor }) => labelColor};
|
color: ${({ labelColor }) => labelColor};
|
||||||
background: ${({ backgroundColor }) => backgroundColor};
|
background: ${({ backgroundColor }) => backgroundColor};
|
||||||
border-radius: ${({ borderRadius }) => borderRadius}px;
|
border-radius: ${({ borderRadius }) => borderRadius}px;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { BlockPicker } from 'react-color'
|
import { BlockPicker } from 'react-color'
|
||||||
|
|
||||||
import { useData } from '../../../hooks/useData'
|
import { colors } from 'constants/colors'
|
||||||
import { colors } from '../../../styles/colors'
|
import { useData } from 'hooks/useData'
|
||||||
|
|
||||||
type ColorPickerProps = {
|
type ColorPickerProps = {
|
||||||
prop:
|
prop:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ColorPicker } from '../ColorPicker'
|
import { ColorPicker } from 'components/Dash/ColorPicker'
|
||||||
|
|
||||||
export function ColorsSettings() {
|
export function ColorsSettings() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import 'rc-slider/assets/index.css'
|
|||||||
|
|
||||||
import Slider from 'rc-slider'
|
import Slider from 'rc-slider'
|
||||||
|
|
||||||
import { useData } from '../../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
import { DescriptionInput } from '../DescriptionInput'
|
import { DescriptionInput } from 'components/Dash/DescriptionInput'
|
||||||
import { FontsSelect } from '../FontsSelect'
|
import { FontsSelect } from 'components/Dash/FontsSelect'
|
||||||
import { NameInput } from '../NameInput'
|
import { NameInput } from 'components/Dash/NameInput'
|
||||||
|
|
||||||
export function DataSettings() {
|
export function DataSettings() {
|
||||||
const { data, setData } = useData()
|
const { data, setData } = useData()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useData } from '../../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
|
|
||||||
export function DescriptionInput() {
|
export function DescriptionInput() {
|
||||||
const { data, setData } = useData()
|
const { data, setData } = useData()
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { useData } from '../../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
|
|
||||||
|
import type { Fonts } from 'types/Fonts'
|
||||||
|
|
||||||
export function FontsSelect() {
|
export function FontsSelect() {
|
||||||
const { data, setData } = useData()
|
const { data, setData } = useData()
|
||||||
@@ -11,14 +13,18 @@ export function FontsSelect() {
|
|||||||
...data,
|
...data,
|
||||||
settings: {
|
settings: {
|
||||||
...data.settings,
|
...data.settings,
|
||||||
font: e.target.value
|
font: e.target.value as Fonts
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<option value="'Baloo Bhaijaan 2', sans-serif">Baloo</option>
|
<option value="inconsolata">Inconsolata</option>
|
||||||
<option value="'Montserrat', sans-serif">Montserrat</option>
|
<option value="oswald">Oswald</option>
|
||||||
<option value="'Roboto', sans-serif">Roboto</option>
|
<option value="poppins">Poppins</option>
|
||||||
|
<option value="quicksand">Quicksand</option>
|
||||||
|
<option value="roboto">Roboto</option>
|
||||||
|
<option value="robotoSlab">Roboto Slab</option>
|
||||||
|
<option value="ubuntu">Ubuntu</option>
|
||||||
</select>
|
</select>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useData } from '../../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
|
|
||||||
export function NameInput() {
|
export function NameInput() {
|
||||||
const { data, setData } = useData()
|
const { data, setData } = useData()
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import type { Dispatch, SetStateAction } from 'react'
|
|
||||||
|
|
||||||
import { useData } from '../../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
import { api } from '../../../services/api'
|
import { api } from 'services/api'
|
||||||
import type { Data } from '../../../types/Data'
|
import { removeLocalStorageData } from 'utils/localStorage'
|
||||||
import { removeLocalStorageData } from '../../../utils/localStorage'
|
import { Button } from 'components/Button'
|
||||||
import { Button } from '../../Button'
|
|
||||||
import { ButtonsGroup, Wrapper } from './styles'
|
import { ButtonsGroup, Wrapper } from './styles'
|
||||||
|
|
||||||
|
import type { Data } from '../../../types/Data'
|
||||||
|
import type { Dispatch, SetStateAction } from 'react'
|
||||||
|
|
||||||
type SaveChangesAlertProps = {
|
type SaveChangesAlertProps = {
|
||||||
hasUnsavedChanges: boolean
|
hasUnsavedChanges: boolean
|
||||||
setHasUnsavedChanges: Dispatch<SetStateAction<boolean>>
|
setHasUnsavedChanges: Dispatch<SetStateAction<boolean>>
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ import { isEqual } from 'lodash'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Collapsible from 'react-collapsible'
|
import Collapsible from 'react-collapsible'
|
||||||
|
|
||||||
import { useAuth } from '../../hooks/useAuth'
|
import { useAuth } from 'hooks/useAuth'
|
||||||
import { useData } from '../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
import type { Data } from '../../types/Data'
|
import { getLocalStorageData, setLocalStorageData } from 'utils/localStorage'
|
||||||
import { getLocalStorageData, setLocalStorageData } from '../../utils/localStorage'
|
import { Home } from 'components/Home'
|
||||||
import { Home } from '../Home'
|
import { ColorsSettings } from 'components/Dash/ColorsSettings'
|
||||||
import { ColorsSettings } from './ColorsSettings'
|
import { DataSettings } from 'components/Dash/DataSettings'
|
||||||
import { DataSettings } from './DataSettings'
|
import { SaveChangesAlert } from 'components/Dash/SaveChangesAlert'
|
||||||
import { SaveChangesAlert } from './SaveChangesAlert'
|
|
||||||
import { Content, Preview, Wrapper } from './styles'
|
import { Content, Preview, Wrapper } from './styles'
|
||||||
|
|
||||||
|
import type { Data } from 'types/Data'
|
||||||
|
|
||||||
type DashProps = {
|
type DashProps = {
|
||||||
initialData: Data
|
initialData: Data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { useData } from '../../hooks/useData'
|
import { fonts } from 'constants/fonts'
|
||||||
import { Avatar } from '../Avatar'
|
import { useData } from 'hooks/useData'
|
||||||
import { Button } from '../Button'
|
import { Button } from 'components/Button'
|
||||||
import { SocialLinks } from '../SocialLinks'
|
import { Avatar } from 'components/Avatar'
|
||||||
|
import { SocialLinks } from 'components/SocialLinks'
|
||||||
|
|
||||||
import { Content, Description, Name, Wrapper } from './styles'
|
import { Content, Description, Name, Wrapper } from './styles'
|
||||||
|
|
||||||
export const Home = () => {
|
export const Home = () => {
|
||||||
@@ -9,7 +11,7 @@ export const Home = () => {
|
|||||||
const { colors, buttonBorderRadius, font, name, description } = data.settings
|
const { colors, buttonBorderRadius, font, name, description } = data.settings
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper color={colors.texts} font={font}>
|
<Wrapper color={colors.texts} font={fonts[font].name}>
|
||||||
<Content>
|
<Content>
|
||||||
<Avatar />
|
<Avatar />
|
||||||
<Name>{name}</Name>
|
<Name>{name}</Name>
|
||||||
|
|||||||
25
src/components/Layout/index.tsx
Normal file
25
src/components/Layout/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import Head from 'next/head'
|
||||||
|
|
||||||
|
import { fonts } from 'constants/fonts'
|
||||||
|
import { useData } from 'hooks/useData'
|
||||||
|
import { Global } from 'styles/global'
|
||||||
|
|
||||||
|
import type { ReactNode } from 'react'
|
||||||
|
|
||||||
|
type LayoutProps = {
|
||||||
|
children: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Layout({ children }: LayoutProps) {
|
||||||
|
const { data } = useData()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Global data={data} />
|
||||||
|
<Head>
|
||||||
|
<link href={fonts[data.settings.font].url} rel="stylesheet" />
|
||||||
|
</Head>
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,12 +5,14 @@ import {
|
|||||||
} from 'react-icons/ai'
|
} from 'react-icons/ai'
|
||||||
import { BsEnvelope as Email } from 'react-icons/bs'
|
import { BsEnvelope as Email } from 'react-icons/bs'
|
||||||
import { FaDev as Dev, FaLinkedinIn as LinkedIn } from 'react-icons/fa'
|
import { FaDev as Dev, FaLinkedinIn as LinkedIn } from 'react-icons/fa'
|
||||||
import type { IconType } from 'react-icons/lib'
|
|
||||||
|
|
||||||
import { useData } from '../../hooks/useData'
|
import { useData } from 'hooks/useData'
|
||||||
import { Link } from '../Link'
|
import { Link } from 'components/Link'
|
||||||
|
|
||||||
import { SocialItem, Wrapper } from './styles'
|
import { SocialItem, Wrapper } from './styles'
|
||||||
|
|
||||||
|
import type { IconType } from 'react-icons/lib'
|
||||||
|
|
||||||
const Icons = {
|
const Icons = {
|
||||||
Email,
|
Email,
|
||||||
GitHub,
|
GitHub,
|
||||||
|
|||||||
15
src/constants/auth.ts
Normal file
15
src/constants/auth.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const JWT_EXPIRES_IN = 15 // minutes
|
||||||
|
const SESSION_EXPIRES_IN = 30 // days
|
||||||
|
|
||||||
|
const { JWT_SECRET } = process.env
|
||||||
|
const SESSION_EXPIRES_IN_S = SESSION_EXPIRES_IN * 24 * 60 * 60
|
||||||
|
const SESSION_EXPIRES_IN_MS = SESSION_EXPIRES_IN_S * 1000
|
||||||
|
|
||||||
|
if (!JWT_SECRET && !process.browser) throw new Error('JWT_SECRET is not defined')
|
||||||
|
|
||||||
|
export const authConstants = {
|
||||||
|
JWT_SECRET,
|
||||||
|
JWT_EXPIRES_IN,
|
||||||
|
SESSION_EXPIRES_IN_S,
|
||||||
|
SESSION_EXPIRES_IN_MS
|
||||||
|
}
|
||||||
30
src/constants/fonts.ts
Normal file
30
src/constants/fonts.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export const fonts = {
|
||||||
|
roboto: {
|
||||||
|
name: "'Roboto', sans-serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
robotoSlab: {
|
||||||
|
name: "'Roboto Slab', serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
oswald: {
|
||||||
|
name: "'Oswald', sans-serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Oswald:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
poppins: {
|
||||||
|
name: "'Poppins', sans-serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
ubuntu: {
|
||||||
|
name: "'Ubuntu', sans-serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
quicksand: {
|
||||||
|
name: "'Quicksand', sans-serif",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500&display=swap'
|
||||||
|
},
|
||||||
|
inconsolata: {
|
||||||
|
name: "'Inconsolata', monospace",
|
||||||
|
url: 'https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;500&display=swap'
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
import type { User } from '@prisma/client'
|
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { parseCookies } from 'nookies'
|
import { parseCookies } from 'nookies'
|
||||||
import type { ReactNode } from 'react'
|
import { useEffect, createContext, useState } from 'react'
|
||||||
import { useEffect } from 'react'
|
|
||||||
import { createContext, useState } from 'react'
|
|
||||||
|
|
||||||
import { api } from '../services/api'
|
import { api } from 'services/api'
|
||||||
import { destroyCookies } from '../utils/destroyCookies'
|
import { destroyCookies, setCookies } from 'utils/cookies'
|
||||||
import { retrieveUser } from '../utils/retrieveUser'
|
import { retrieveUser } from 'utils/retrieveUser'
|
||||||
import { setCookies } from '../utils/setCookies'
|
|
||||||
|
import type { ReactNode } from 'react'
|
||||||
|
import type { User } from 'types/User'
|
||||||
|
|
||||||
type AuthContextType = {
|
type AuthContextType = {
|
||||||
user?: Omit<User, 'password'>
|
user?: User
|
||||||
signIn: (username: string, password: string) => Promise<void>
|
signIn: (username: string, password: string) => Promise<void>
|
||||||
signOut: () => void
|
signOut: () => void
|
||||||
}
|
}
|
||||||
@@ -23,7 +22,7 @@ type AuthProviderProps = {
|
|||||||
export const AuthContext = createContext({} as AuthContextType)
|
export const AuthContext = createContext({} as AuthContextType)
|
||||||
|
|
||||||
export const AuthProvider = ({ children }: AuthProviderProps) => {
|
export const AuthProvider = ({ children }: AuthProviderProps) => {
|
||||||
const [user, setUser] = useState<Omit<User, 'password'>>()
|
const [user, setUser] = useState<User>()
|
||||||
const { push } = useRouter()
|
const { push } = useRouter()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Dispatch, ReactNode, SetStateAction } from 'react'
|
|
||||||
import { createContext, useState } from 'react'
|
import { createContext, useState } from 'react'
|
||||||
|
|
||||||
import type { Data } from '../types/Data'
|
import type { Dispatch, ReactNode, SetStateAction } from 'react'
|
||||||
|
import type { Data } from 'types/Data'
|
||||||
|
|
||||||
type DataContextType = {
|
type DataContextType = {
|
||||||
data: Data
|
data: Data
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useContext } from 'react'
|
import { useContext } from 'react'
|
||||||
|
|
||||||
import { AuthContext } from '../contexts/AuthContext'
|
import { AuthContext } from 'contexts/AuthContext'
|
||||||
|
|
||||||
export const useAuth = () => useContext(AuthContext)
|
export const useAuth = () => useContext(AuthContext)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useContext } from 'react'
|
import { useContext } from 'react'
|
||||||
|
|
||||||
import { DataContext } from '../contexts/DataContext'
|
import { DataContext } from 'contexts/DataContext'
|
||||||
|
|
||||||
export const useData = () => useContext(DataContext)
|
export const useData = () => useContext(DataContext)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { AppProps } from 'next/app'
|
import { Layout } from 'components/Layout'
|
||||||
|
import { AuthProvider } from 'contexts/AuthContext'
|
||||||
|
import { DataProvider } from 'contexts/DataContext'
|
||||||
|
|
||||||
import { AuthProvider } from '../contexts/AuthContext'
|
import type { AppProps } from 'next/app'
|
||||||
import { DataProvider } from '../contexts/DataContext'
|
|
||||||
import { Layout } from '../styles/layout'
|
|
||||||
|
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export default function App({ Component, pageProps }: AppProps) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ export default class Document extends NextDocument {
|
|||||||
<Head>
|
<Head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Baloo+Bhaijaan+2:wght@400;500&family=Montserrat:wght@400;500&family=Roboto:wght@400;500&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
/>
|
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<body>
|
||||||
<Main />
|
<Main />
|
||||||
|
|||||||
@@ -1,35 +1,11 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
|
||||||
import { compare } from 'bcryptjs'
|
import { compare } from 'bcryptjs'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
||||||
import nc from 'next-connect'
|
|
||||||
|
|
||||||
import { prisma } from '../../../services/prisma'
|
import { prisma } from 'services/prisma'
|
||||||
import { createSession } from '../../../utils/createSession'
|
import { createSession } from 'utils/createSession'
|
||||||
import { ExceptionError } from '../../../utils/error'
|
import { ExceptionError } from 'utils/error'
|
||||||
|
import { nc } from 'utils/nc'
|
||||||
|
|
||||||
const handler = nc<NextApiRequest, NextApiResponse>({
|
const handler = nc.post(async (req, res) => {
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).post(async (req, res) => {
|
|
||||||
const { username, password } = req.body
|
const { username, password } = req.body
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
|
|||||||
@@ -1,34 +1,9 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
import { prisma } from 'services/prisma'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
import { createSession } from 'utils/createSession'
|
||||||
import nc from 'next-connect'
|
import { ExceptionError } from 'utils/error'
|
||||||
|
import { nc } from 'utils/nc'
|
||||||
|
|
||||||
import { prisma } from '../../../services/prisma'
|
const handler = nc.post(async (req, res) => {
|
||||||
import { createSession } from '../../../utils/createSession'
|
|
||||||
import { ExceptionError } from '../../../utils/error'
|
|
||||||
|
|
||||||
const handler = nc<NextApiRequest, NextApiResponse>({
|
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).post(async (req, res) => {
|
|
||||||
const { refreshToken } = req.body
|
const { refreshToken } = req.body
|
||||||
|
|
||||||
if (!refreshToken) {
|
if (!refreshToken) {
|
||||||
|
|||||||
@@ -1,34 +1,9 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
import { prisma } from 'services/prisma'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
||||||
import nc from 'next-connect'
|
|
||||||
|
|
||||||
import { prisma } from '../../services/prisma'
|
|
||||||
// import { authMiddleware } from '../../utils/authMiddleware'
|
// import { authMiddleware } from '../../utils/authMiddleware'
|
||||||
import { ExceptionError } from '../../utils/error'
|
import { ExceptionError } from 'utils/error'
|
||||||
|
import { nc } from 'utils/nc'
|
||||||
|
|
||||||
const handler = nc<NextApiRequest, NextApiResponse>({
|
const handler = nc
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.get(async (_req, res) => {
|
.get(async (_req, res) => {
|
||||||
const response = await prisma.data.findUnique({
|
const response = await prisma.data.findUnique({
|
||||||
where: { id: 1 }
|
where: { id: 1 }
|
||||||
|
|||||||
@@ -1,39 +1,10 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
|
||||||
import { compare, hashSync } from 'bcryptjs'
|
import { compare, hashSync } from 'bcryptjs'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
||||||
import nc from 'next-connect'
|
|
||||||
|
|
||||||
import { prisma } from '../../../services/prisma'
|
import { nc } from 'utils/nc'
|
||||||
import { ExceptionError } from '../../../utils/error'
|
import { prisma } from 'services/prisma'
|
||||||
|
import { ExceptionError } from 'utils/error'
|
||||||
|
|
||||||
interface Request extends NextApiRequest {
|
const handler = nc
|
||||||
userId: string
|
|
||||||
userRole: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const handler = nc<Request, NextApiResponse>({
|
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.get(async (req, res) => {
|
.get(async (req, res) => {
|
||||||
const { id } = req.query
|
const { id } = req.query
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,11 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
|
||||||
import { hashSync } from 'bcryptjs'
|
import { hashSync } from 'bcryptjs'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
||||||
import nc from 'next-connect'
|
|
||||||
|
|
||||||
import { prisma } from '../../../services/prisma'
|
import { prisma } from 'services/prisma'
|
||||||
import { authMiddleware } from '../../../utils/authMiddleware'
|
import { authMiddleware } from 'utils/authMiddleware'
|
||||||
import { ExceptionError } from '../../../utils/error'
|
import { ExceptionError } from 'utils/error'
|
||||||
|
import { nc } from 'utils/nc'
|
||||||
|
|
||||||
interface Request extends NextApiRequest {
|
const handler = nc
|
||||||
userId: string
|
|
||||||
userRole: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const handler = nc<Request, NextApiResponse>({
|
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.use(authMiddleware)
|
.use(authMiddleware)
|
||||||
.get(async (_req, res) => {
|
.get(async (_req, res) => {
|
||||||
const response = await prisma.user.findMany({
|
const response = await prisma.user.findMany({
|
||||||
|
|||||||
@@ -1,56 +1,24 @@
|
|||||||
import { Prisma } from '@prisma/client'
|
import { prisma } from 'services/prisma'
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
import { authMiddleware } from 'utils/authMiddleware'
|
||||||
import nc from 'next-connect'
|
import { ExceptionError } from 'utils/error'
|
||||||
|
import { nc } from 'utils/nc'
|
||||||
|
|
||||||
import { prisma } from '../../../services/prisma'
|
const handler = nc.use(authMiddleware).get(async (req, res) => {
|
||||||
import { authMiddleware } from '../../../utils/authMiddleware'
|
const { userId } = req
|
||||||
import { ExceptionError } from '../../../utils/error'
|
const response = await prisma.user.findUnique({
|
||||||
|
where: { id: +userId },
|
||||||
interface Request extends NextApiRequest {
|
select: {
|
||||||
userId: string
|
id: true,
|
||||||
userRole: string
|
username: true,
|
||||||
}
|
role: true
|
||||||
|
|
||||||
const handler = nc<Request, NextApiResponse>({
|
|
||||||
onNoMatch: (_req, res) => {
|
|
||||||
res.status(404).json({ error: 'Not found' })
|
|
||||||
},
|
|
||||||
onError: (err, _req, res) => {
|
|
||||||
if (err instanceof ExceptionError) {
|
|
||||||
res.status(err.status).json({
|
|
||||||
status: err.status,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
|
||||||
res.status(400).json({
|
|
||||||
status: 400,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.status(500).json({
|
|
||||||
status: 500,
|
|
||||||
error: err.message
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
.use(authMiddleware)
|
|
||||||
.get(async (req, res) => {
|
|
||||||
const { userId } = req
|
|
||||||
const response = await prisma.user.findUnique({
|
|
||||||
where: { id: +userId },
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
role: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!response) {
|
|
||||||
throw new ExceptionError('User not found')
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).json(response)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!response) {
|
||||||
|
throw new ExceptionError('User not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json(response)
|
||||||
|
})
|
||||||
|
|
||||||
export default handler
|
export default handler
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { GetServerSideProps } from 'next'
|
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
import { useAuth } from '../hooks/useAuth'
|
import { useAuth } from 'hooks/useAuth'
|
||||||
import { fetchData } from '../services/fetchData'
|
import { fetchData } from 'services/fetchData'
|
||||||
|
|
||||||
|
import type { GetStaticProps } from 'next'
|
||||||
|
|
||||||
export default function AuthPage() {
|
export default function AuthPage() {
|
||||||
const { signIn } = useAuth()
|
const { signIn } = useAuth()
|
||||||
@@ -35,10 +36,7 @@ export default function AuthPage() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async () => {
|
export const getStaticProps: GetStaticProps = async () => {
|
||||||
const initialData = await fetchData()
|
const initialData = await fetchData()
|
||||||
|
return { props: { initialData }, revalidate: 1 }
|
||||||
return {
|
|
||||||
props: { initialData }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { GetServerSideProps } from 'next'
|
import { Dash } from 'components/Dash'
|
||||||
|
import { fetchData } from 'services/fetchData'
|
||||||
|
|
||||||
import { Dash } from '../components/Dash'
|
import type { GetServerSideProps } from 'next'
|
||||||
import { fetchData } from '../services/fetchData'
|
import type { Data } from 'types/Data'
|
||||||
import type { Data } from '../types/Data'
|
|
||||||
|
|
||||||
type DashPageProps = {
|
type DashPageProps = {
|
||||||
initialData: Data
|
initialData: Data
|
||||||
@@ -14,8 +14,5 @@ export default function DashPage({ initialData }: DashPageProps) {
|
|||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async () => {
|
export const getServerSideProps: GetServerSideProps = async () => {
|
||||||
const initialData = await fetchData()
|
const initialData = await fetchData()
|
||||||
|
return { props: { initialData } }
|
||||||
return {
|
|
||||||
props: { initialData }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { GetStaticProps } from 'next'
|
import { Home } from 'components/Home'
|
||||||
|
import { fetchData } from 'services/fetchData'
|
||||||
|
|
||||||
import { Home } from '../components/Home'
|
import type { GetStaticProps } from 'next'
|
||||||
import { fetchData } from '../services/fetchData'
|
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return <Home />
|
return <Home />
|
||||||
@@ -9,9 +9,5 @@ export default function HomePage() {
|
|||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async () => {
|
export const getStaticProps: GetStaticProps = async () => {
|
||||||
const initialData = await fetchData()
|
const initialData = await fetchData()
|
||||||
|
return { props: { initialData }, revalidate: 1 }
|
||||||
return {
|
|
||||||
props: { initialData },
|
|
||||||
revalidate: 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import { GetServerSidePropsContext } from 'next'
|
|||||||
import router from 'next/router'
|
import router from 'next/router'
|
||||||
import { parseCookies } from 'nookies'
|
import { parseCookies } from 'nookies'
|
||||||
|
|
||||||
import { destroyCookies } from '../utils/destroyCookies'
|
import { destroyCookies, setCookies } from 'utils/cookies'
|
||||||
import { setCookies } from '../utils/setCookies'
|
|
||||||
|
|
||||||
let isRefreshing = false
|
let isRefreshing = false
|
||||||
let failedRequestsQueued: any[] = []
|
let failedRequestsQueued: any[] = []
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { Data } from '../types/Data'
|
import { prisma } from 'services/prisma'
|
||||||
import { prisma } from './prisma'
|
|
||||||
|
import type { Data } from 'types/Data'
|
||||||
|
|
||||||
export async function fetchData(): Promise<Data> {
|
export async function fetchData(): Promise<Data> {
|
||||||
const response = await prisma.data.findUnique({
|
const response = await prisma.data.findUnique({
|
||||||
|
|||||||
22
src/styles/global.ts
Normal file
22
src/styles/global.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { createGlobalStyle } from 'styled-components'
|
||||||
|
|
||||||
|
import type { Data } from 'types/Data'
|
||||||
|
|
||||||
|
type GlobalStyleProps = {
|
||||||
|
data: Data
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Global = createGlobalStyle<GlobalStyleProps>`
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
color: #0f172a;
|
||||||
|
background: ${({ data }) => data.settings.colors.background};
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { ReactNode } from 'react'
|
|
||||||
import { createGlobalStyle } from 'styled-components'
|
|
||||||
|
|
||||||
import { useData } from '../hooks/useData'
|
|
||||||
import { Data } from '../types/Data'
|
|
||||||
|
|
||||||
type GlobalStyleProps = {
|
|
||||||
data: Data
|
|
||||||
}
|
|
||||||
|
|
||||||
type LayoutProps = {
|
|
||||||
children: ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
const GlobalStyles = createGlobalStyle<GlobalStyleProps>`
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
transition: all 0.25s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
color: #0f172a;
|
|
||||||
background: ${({ data }) => data.settings.colors.background};
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export function Layout({ children }: LayoutProps) {
|
|
||||||
const { data } = useData()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<GlobalStyles data={data} />
|
|
||||||
{children}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import type { Fonts } from './Fonts'
|
||||||
|
|
||||||
export type Data = {
|
export type Data = {
|
||||||
settings: {
|
settings: {
|
||||||
avatar: string
|
avatar: string
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
font: string
|
font: Fonts
|
||||||
buttonBorderRadius: string
|
buttonBorderRadius: string
|
||||||
colors: {
|
colors: {
|
||||||
texts: string
|
texts: string
|
||||||
|
|||||||
2
src/types/Fonts.ts
Normal file
2
src/types/Fonts.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { fonts } from 'constants/fonts'
|
||||||
|
export type Fonts = keyof typeof fonts
|
||||||
2
src/types/User.ts
Normal file
2
src/types/User.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { User as UserModel } from '@prisma/client'
|
||||||
|
export type User = Omit<UserModel, 'password'>
|
||||||
8
src/types/next.d.ts
vendored
Normal file
8
src/types/next.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { IncomingMessage } from 'http'
|
||||||
|
|
||||||
|
declare module 'next' {
|
||||||
|
export interface NextApiRequest extends IncomingMessage {
|
||||||
|
userId: string
|
||||||
|
userRole: string
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,17 @@
|
|||||||
import jwt from 'jsonwebtoken'
|
import jwt from 'jsonwebtoken'
|
||||||
|
|
||||||
|
import { authConstants } from 'constants/auth'
|
||||||
|
import { ExceptionError } from 'utils/error'
|
||||||
|
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
import { ExceptionError } from './error'
|
|
||||||
|
|
||||||
interface Request extends NextApiRequest {
|
|
||||||
userId: string
|
|
||||||
userRole: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Token = {
|
type Token = {
|
||||||
sub: string
|
sub: string
|
||||||
role: string
|
role: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function authMiddleware(req: Request, _res: NextApiResponse, next: () => void) {
|
export async function authMiddleware(req: NextApiRequest, _res: NextApiResponse, next: () => void) {
|
||||||
|
const { JWT_SECRET } = authConstants
|
||||||
const token = req.headers['authorization']
|
const token = req.headers['authorization']
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@@ -22,13 +20,7 @@ export async function authMiddleware(req: Request, _res: NextApiResponse, next:
|
|||||||
|
|
||||||
const [, tokenValue] = token.split(' ')
|
const [, tokenValue] = token.split(' ')
|
||||||
|
|
||||||
const { JWT_SECRET } = process.env
|
const isValidToken = jwt.verify(tokenValue, JWT_SECRET!) as Token
|
||||||
|
|
||||||
if (!JWT_SECRET) {
|
|
||||||
throw new ExceptionError('JWT_SECRET is not defined')
|
|
||||||
}
|
|
||||||
|
|
||||||
const isValidToken = jwt.verify(tokenValue, JWT_SECRET) as Token
|
|
||||||
|
|
||||||
if (!isValidToken) {
|
if (!isValidToken) {
|
||||||
throw new ExceptionError('Invalid token', 401)
|
throw new ExceptionError('Invalid token', 401)
|
||||||
|
|||||||
38
src/utils/cookies.ts
Normal file
38
src/utils/cookies.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { destroyCookie, setCookie } from 'nookies'
|
||||||
|
|
||||||
|
import { authConstants } from 'constants/auth'
|
||||||
|
import { api } from 'services/api'
|
||||||
|
|
||||||
|
import type { GetServerSidePropsContext } from 'next'
|
||||||
|
|
||||||
|
type SetCookiesProps = {
|
||||||
|
ctx?: GetServerSidePropsContext
|
||||||
|
accessToken: string
|
||||||
|
refreshToken: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCookies({ ctx = undefined, accessToken, refreshToken }: SetCookiesProps) {
|
||||||
|
const { SESSION_EXPIRES_IN_S } = authConstants
|
||||||
|
// @ts-ignore
|
||||||
|
api.defaults.headers['authorization'] = `Bearer ${accessToken}`
|
||||||
|
|
||||||
|
setCookie(ctx, 'accessToken', accessToken, {
|
||||||
|
maxAge: SESSION_EXPIRES_IN_S,
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
|
||||||
|
setCookie(ctx, 'refreshToken', refreshToken, {
|
||||||
|
maxAge: SESSION_EXPIRES_IN_S,
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function destroyCookies(ctx: GetServerSidePropsContext | undefined = undefined) {
|
||||||
|
destroyCookie(ctx, 'accessToken', {
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
|
||||||
|
destroyCookie(ctx, 'refreshToken', {
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,30 +1,25 @@
|
|||||||
import type { User } from '@prisma/client'
|
|
||||||
import jwt from 'jsonwebtoken'
|
import jwt from 'jsonwebtoken'
|
||||||
|
|
||||||
import { prisma } from '../services/prisma'
|
import { authConstants } from 'constants/auth'
|
||||||
import { ExceptionError } from './error'
|
import { prisma } from 'services/prisma'
|
||||||
|
import { ExceptionError } from 'utils/error'
|
||||||
|
|
||||||
const EXPIRES_IN = 30 // days
|
import type { User } from '@prisma/client'
|
||||||
const EXPIRES_IN_MS = EXPIRES_IN * 24 * 60 * 60 * 1000
|
|
||||||
|
|
||||||
export async function createSession(user: User) {
|
export async function createSession(user: User) {
|
||||||
const { JWT_SECRET } = process.env
|
const { SESSION_EXPIRES_IN_MS, JWT_EXPIRES_IN, JWT_SECRET } = authConstants
|
||||||
|
|
||||||
if (!JWT_SECRET) {
|
|
||||||
throw new ExceptionError('JWT_SECRET is not defined')
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const session = await prisma.session.create({
|
const session = await prisma.session.create({
|
||||||
data: {
|
data: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
expiresAt: new Date(Date.now() + EXPIRES_IN_MS)
|
expiresAt: new Date(Date.now() + SESSION_EXPIRES_IN_MS)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const payload = { role: user.role, sub: user.id }
|
const payload = { role: user.role, sub: user.id }
|
||||||
const accessToken = jwt.sign(payload, JWT_SECRET, {
|
const accessToken = jwt.sign(payload, JWT_SECRET!, {
|
||||||
expiresIn: '15m'
|
expiresIn: `${JWT_EXPIRES_IN}m`
|
||||||
})
|
})
|
||||||
|
|
||||||
return { accessToken, refreshToken: session.id }
|
return { accessToken, refreshToken: session.id }
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import { GetServerSidePropsContext } from 'next'
|
|
||||||
import { destroyCookie } from 'nookies'
|
|
||||||
|
|
||||||
export function destroyCookies(ctx: GetServerSidePropsContext | undefined = undefined) {
|
|
||||||
destroyCookie(ctx, 'accessToken', {
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
|
|
||||||
destroyCookie(ctx, 'refreshToken', {
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Data } from '../types/Data'
|
import type { Data } from 'types/Data'
|
||||||
|
|
||||||
const KEY = 'link-free-data'
|
const KEY = 'link-free-data'
|
||||||
|
|
||||||
@@ -8,9 +8,9 @@ export function getLocalStorageData(): Data | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setLocalStorageData(data = {}) {
|
export function setLocalStorageData(data = {}) {
|
||||||
localStorage.setItem(KEY, JSON.stringify(data))
|
process.browser && localStorage.setItem(KEY, JSON.stringify(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeLocalStorageData() {
|
export function removeLocalStorageData() {
|
||||||
localStorage.removeItem(KEY)
|
process.browser && localStorage.removeItem(KEY)
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/utils/nc.ts
Normal file
30
src/utils/nc.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import nextConnect from 'next-connect'
|
||||||
|
import { Prisma } from '@prisma/client'
|
||||||
|
|
||||||
|
import { ExceptionError } from 'utils/error'
|
||||||
|
|
||||||
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
|
export const nc = nextConnect<NextApiRequest, NextApiResponse>({
|
||||||
|
onNoMatch: (_req, res) => {
|
||||||
|
res.status(404).json({ error: 'Not found' })
|
||||||
|
},
|
||||||
|
onError: (err, _req, res) => {
|
||||||
|
if (err instanceof ExceptionError) {
|
||||||
|
res.status(err.status).json({
|
||||||
|
status: err.status,
|
||||||
|
error: err.message
|
||||||
|
})
|
||||||
|
} else if (err instanceof Prisma.PrismaClientKnownRequestError) {
|
||||||
|
res.status(400).json({
|
||||||
|
status: 400,
|
||||||
|
error: err.message
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
res.status(500).json({
|
||||||
|
status: 500,
|
||||||
|
error: err.message
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { User } from '@prisma/client'
|
import { api } from 'services/api'
|
||||||
|
|
||||||
import { api } from '../services/api'
|
import type { User } from 'types/User'
|
||||||
|
|
||||||
export async function retrieveUser() {
|
export async function retrieveUser() {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get<Omit<User, 'password'>>('users/me')
|
const { data } = await api.get<User>('users/me')
|
||||||
return data
|
return data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import { GetServerSidePropsContext } from 'next'
|
|
||||||
import { setCookie } from 'nookies'
|
|
||||||
|
|
||||||
import { api } from '../services/api'
|
|
||||||
|
|
||||||
type SetCookiesProps = {
|
|
||||||
ctx?: GetServerSidePropsContext
|
|
||||||
accessToken: string
|
|
||||||
refreshToken: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setCookies({ ctx = undefined, accessToken, refreshToken }: SetCookiesProps) {
|
|
||||||
// @ts-ignore
|
|
||||||
api.defaults.headers['authorization'] = `Bearer ${accessToken}`
|
|
||||||
|
|
||||||
setCookie(ctx, 'accessToken', accessToken, {
|
|
||||||
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
|
|
||||||
setCookie(ctx, 'refreshToken', refreshToken, {
|
|
||||||
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./src",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
|||||||
73
yarn.lock
73
yarn.lock
@@ -535,7 +535,7 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.5"
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
fastq "^1.6.0"
|
fastq "^1.6.0"
|
||||||
|
|
||||||
"@prisma/client@^3.6.0":
|
"@prisma/client@3.6.0":
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.6.0.tgz#68a60cd4c73a369b11f72e173e86fd6789939293"
|
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.6.0.tgz#68a60cd4c73a369b11f72e173e86fd6789939293"
|
||||||
integrity sha512-ycSGY9EZGROtje0iCNsgC5Zqi/ttX2sO7BNMYaLsUMiTlf3F69ZPH+08pRo0hrDfkZzyimXYqeXJlaoYDH1w7A==
|
integrity sha512-ycSGY9EZGROtje0iCNsgC5Zqi/ttX2sO7BNMYaLsUMiTlf3F69ZPH+08pRo0hrDfkZzyimXYqeXJlaoYDH1w7A==
|
||||||
@@ -577,7 +577,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
||||||
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
||||||
|
|
||||||
"@types/bcryptjs@^2.4.2":
|
"@types/bcryptjs@2.4.2":
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae"
|
resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae"
|
||||||
integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==
|
integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==
|
||||||
@@ -595,14 +595,14 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||||
|
|
||||||
"@types/jsonwebtoken@^8.5.6":
|
"@types/jsonwebtoken@8.5.6":
|
||||||
version "8.5.6"
|
version "8.5.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.6.tgz#1913e5a61e70a192c5a444623da4901a7b1a9d42"
|
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.6.tgz#1913e5a61e70a192c5a444623da4901a7b1a9d42"
|
||||||
integrity sha512-+P3O/xC7nzVizIi5VbF34YtqSonFsdnbXBnWUCYRiKOi1f9gA4sEFvXkrGr/QVV23IbMYvcoerI7nnhDUiWXRQ==
|
integrity sha512-+P3O/xC7nzVizIi5VbF34YtqSonFsdnbXBnWUCYRiKOi1f9gA4sEFvXkrGr/QVV23IbMYvcoerI7nnhDUiWXRQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/lodash@^4.14.178":
|
"@types/lodash@4.14.178":
|
||||||
version "4.14.178"
|
version "4.14.178"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
|
||||||
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
|
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
|
||||||
@@ -622,7 +622,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10"
|
||||||
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
|
integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==
|
||||||
|
|
||||||
"@types/node@^17.0.0":
|
"@types/node@17.0.0":
|
||||||
version "17.0.0"
|
version "17.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.0.tgz#62797cee3b8b497f6547503b2312254d4fe3c2bb"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.0.tgz#62797cee3b8b497f6547503b2312254d4fe3c2bb"
|
||||||
integrity sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==
|
integrity sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==
|
||||||
@@ -642,7 +642,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
||||||
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
||||||
|
|
||||||
"@types/react-color@^3.0.6":
|
"@types/react-color@3.0.6":
|
||||||
version "3.0.6"
|
version "3.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.6.tgz#602fed023802b2424e7cd6ff3594ccd3d5055f9a"
|
resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.6.tgz#602fed023802b2424e7cd6ff3594ccd3d5055f9a"
|
||||||
integrity sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==
|
integrity sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==
|
||||||
@@ -671,7 +671,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||||
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
||||||
|
|
||||||
"@types/styled-components@^5.1.18":
|
"@types/styled-components@5.1.18":
|
||||||
version "5.1.18"
|
version "5.1.18"
|
||||||
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.18.tgz#1c361130f76a52f1cb4851c2a32aa328267e5b78"
|
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.18.tgz#1c361130f76a52f1cb4851c2a32aa328267e5b78"
|
||||||
integrity sha512-xPTYmWP7Mxk5TAD3pYsqjwA9G5fAI8e/S51QUJEl7EQD1siKCdiYXIWiH2lzoHRl+QqbQCJMcGv3YTF3OmyPdQ==
|
integrity sha512-xPTYmWP7Mxk5TAD3pYsqjwA9G5fAI8e/S51QUJEl7EQD1siKCdiYXIWiH2lzoHRl+QqbQCJMcGv3YTF3OmyPdQ==
|
||||||
@@ -954,7 +954,7 @@ axe-core@^4.3.5:
|
|||||||
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5"
|
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5"
|
||||||
integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==
|
integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==
|
||||||
|
|
||||||
axios@^0.24.0:
|
axios@0.24.0:
|
||||||
version "0.24.0"
|
version "0.24.0"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
|
||||||
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
||||||
@@ -966,7 +966,7 @@ axobject-query@^2.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||||
integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
|
integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
|
||||||
|
|
||||||
"babel-plugin-styled-components@>= 1.12.0", babel-plugin-styled-components@^2.0.2:
|
babel-plugin-styled-components@2.0.2, "babel-plugin-styled-components@>= 1.12.0":
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz#0fac11402dc9db73698b55847ab1dc73f5197c54"
|
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz#0fac11402dc9db73698b55847ab1dc73f5197c54"
|
||||||
integrity sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==
|
integrity sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==
|
||||||
@@ -991,7 +991,7 @@ base64-js@^1.0.2, base64-js@^1.3.1:
|
|||||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||||
|
|
||||||
bcryptjs@^2.4.3:
|
bcryptjs@2.4.3:
|
||||||
version "2.4.3"
|
version "2.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
|
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
|
||||||
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
|
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
|
||||||
@@ -1553,7 +1553,7 @@ csstype@^3.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5"
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5"
|
||||||
integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==
|
integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==
|
||||||
|
|
||||||
cuid@^2.1.8:
|
cuid@2.1.8:
|
||||||
version "2.1.8"
|
version "2.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.8.tgz#cbb88f954171e0d5747606c0139fb65c5101eac0"
|
resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.8.tgz#cbb88f954171e0d5747606c0139fb65c5101eac0"
|
||||||
integrity sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==
|
integrity sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==
|
||||||
@@ -1706,7 +1706,7 @@ dot-prop@^5.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-obj "^2.0.0"
|
is-obj "^2.0.0"
|
||||||
|
|
||||||
dotenv@^10.0.0:
|
dotenv@10.0.0:
|
||||||
version "10.0.0"
|
version "10.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
||||||
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
||||||
@@ -1882,7 +1882,7 @@ eslint-module-utils@^2.7.1:
|
|||||||
find-up "^2.1.0"
|
find-up "^2.1.0"
|
||||||
pkg-dir "^2.0.0"
|
pkg-dir "^2.0.0"
|
||||||
|
|
||||||
eslint-plugin-import@^2.25.2:
|
eslint-plugin-import@2.25.3, eslint-plugin-import@^2.25.2:
|
||||||
version "2.25.3"
|
version "2.25.3"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766"
|
||||||
integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==
|
integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==
|
||||||
@@ -1951,11 +1951,6 @@ eslint-plugin-react@^7.27.0:
|
|||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
string.prototype.matchall "^4.0.6"
|
string.prototype.matchall "^4.0.6"
|
||||||
|
|
||||||
eslint-plugin-simple-import-sort@7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz#a1dad262f46d2184a90095a60c66fef74727f0f8"
|
|
||||||
integrity sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==
|
|
||||||
|
|
||||||
eslint-scope@^7.1.0:
|
eslint-scope@^7.1.0:
|
||||||
version "7.1.0"
|
version "7.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153"
|
||||||
@@ -2867,7 +2862,7 @@ jsonparse@^1.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
|
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
|
||||||
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
|
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
|
||||||
|
|
||||||
jsonwebtoken@^8.5.1:
|
jsonwebtoken@8.5.1:
|
||||||
version "8.5.1"
|
version "8.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
|
||||||
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
|
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
|
||||||
@@ -3062,7 +3057,7 @@ lodash.sortby@^4.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||||
|
|
||||||
lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
|
lodash@4.17.21, lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
@@ -3267,7 +3262,7 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
next-connect@^0.11.0:
|
next-connect@0.11.0:
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/next-connect/-/next-connect-0.11.0.tgz#447c7b78937ff71f36c97d03f1623a6d0264ef49"
|
resolved "https://registry.yarnpkg.com/next-connect/-/next-connect-0.11.0.tgz#447c7b78937ff71f36c97d03f1623a6d0264ef49"
|
||||||
integrity sha512-7VW5z9MWOpd8wnbST9dXgVd0c0V76LLLk5mBDYLSMtEC2dj3v3YF/Bl3t58cJrzm4SZ0e/s3yeD361F888u0yg==
|
integrity sha512-7VW5z9MWOpd8wnbST9dXgVd0c0V76LLLk5mBDYLSMtEC2dj3v3YF/Bl3t58cJrzm4SZ0e/s3yeD361F888u0yg==
|
||||||
@@ -3370,7 +3365,7 @@ node-releases@^1.1.71:
|
|||||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e"
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e"
|
||||||
integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==
|
integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==
|
||||||
|
|
||||||
nookies@^2.5.2:
|
nookies@2.5.2:
|
||||||
version "2.5.2"
|
version "2.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/nookies/-/nookies-2.5.2.tgz#cc55547efa982d013a21475bd0db0c02c1b35b27"
|
resolved "https://registry.yarnpkg.com/nookies/-/nookies-2.5.2.tgz#cc55547efa982d013a21475bd0db0c02c1b35b27"
|
||||||
integrity sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==
|
integrity sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==
|
||||||
@@ -3691,7 +3686,7 @@ platform@1.3.6:
|
|||||||
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
|
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
|
||||||
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
|
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
|
||||||
|
|
||||||
polished@^4.1.3:
|
polished@4.1.3:
|
||||||
version "4.1.3"
|
version "4.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/polished/-/polished-4.1.3.tgz#7a3abf2972364e7d97770b827eec9a9e64002cfc"
|
resolved "https://registry.yarnpkg.com/polished/-/polished-4.1.3.tgz#7a3abf2972364e7d97770b827eec9a9e64002cfc"
|
||||||
integrity sha512-ocPAcVBUOryJEKe0z2KLd1l9EBa1r5mSwlKpExmrLzsnIzJo4axsoU9O2BjOTkDGDT4mZ0WFE5XKTlR3nLnZOA==
|
integrity sha512-ocPAcVBUOryJEKe0z2KLd1l9EBa1r5mSwlKpExmrLzsnIzJo4axsoU9O2BjOTkDGDT4mZ0WFE5XKTlR3nLnZOA==
|
||||||
@@ -3760,7 +3755,7 @@ pretty-quick@3.1.2:
|
|||||||
mri "^1.1.5"
|
mri "^1.1.5"
|
||||||
multimatch "^4.0.0"
|
multimatch "^4.0.0"
|
||||||
|
|
||||||
prisma@^3.6.0:
|
prisma@3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.6.0.tgz#99532abc02e045e58c6133a19771bdeb28cecdbe"
|
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.6.0.tgz#99532abc02e045e58c6133a19771bdeb28cecdbe"
|
||||||
integrity sha512-6SqgHS/5Rq6HtHjsWsTxlj+ySamGyCLBUQfotc2lStOjPv52IQuDVpp58GieNqc9VnfuFyHUvTZw7aQB+G2fvQ==
|
integrity sha512-6SqgHS/5Rq6HtHjsWsTxlj+ySamGyCLBUQfotc2lStOjPv52IQuDVpp58GieNqc9VnfuFyHUvTZw7aQB+G2fvQ==
|
||||||
@@ -3889,7 +3884,7 @@ rc-motion@^2.0.0:
|
|||||||
classnames "^2.2.1"
|
classnames "^2.2.1"
|
||||||
rc-util "^5.2.1"
|
rc-util "^5.2.1"
|
||||||
|
|
||||||
rc-slider@^9.7.5:
|
rc-slider@9.7.5:
|
||||||
version "9.7.5"
|
version "9.7.5"
|
||||||
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-9.7.5.tgz#193141c68e99b1dc3b746daeb6bf852946f5b7f4"
|
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-9.7.5.tgz#193141c68e99b1dc3b746daeb6bf852946f5b7f4"
|
||||||
integrity sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==
|
integrity sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==
|
||||||
@@ -3938,12 +3933,12 @@ rc@^1.2.7:
|
|||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
strip-json-comments "~2.0.1"
|
strip-json-comments "~2.0.1"
|
||||||
|
|
||||||
react-collapsible@^2.8.4:
|
react-collapsible@2.8.4:
|
||||||
version "2.8.4"
|
version "2.8.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-collapsible/-/react-collapsible-2.8.4.tgz#319ff7471138c4381ce0afa3ac308ccde7f4e09f"
|
resolved "https://registry.yarnpkg.com/react-collapsible/-/react-collapsible-2.8.4.tgz#319ff7471138c4381ce0afa3ac308ccde7f4e09f"
|
||||||
integrity sha512-oG4yOk6AGKswe0OD/8t3/nf4Rgj4UhlZUUvqL5jop0/ez02B3dBDmNvs3sQz0PcTpJvt0ai8zF7Atd1SzN/UNw==
|
integrity sha512-oG4yOk6AGKswe0OD/8t3/nf4Rgj4UhlZUUvqL5jop0/ez02B3dBDmNvs3sQz0PcTpJvt0ai8zF7Atd1SzN/UNw==
|
||||||
|
|
||||||
react-color@^2.19.3:
|
react-color@2.19.3:
|
||||||
version "2.19.3"
|
version "2.19.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.19.3.tgz#ec6c6b4568312a3c6a18420ab0472e146aa5683d"
|
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.19.3.tgz#ec6c6b4568312a3c6a18420ab0472e146aa5683d"
|
||||||
integrity sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==
|
integrity sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==
|
||||||
@@ -3956,7 +3951,7 @@ react-color@^2.19.3:
|
|||||||
reactcss "^1.2.0"
|
reactcss "^1.2.0"
|
||||||
tinycolor2 "^1.4.1"
|
tinycolor2 "^1.4.1"
|
||||||
|
|
||||||
react-dom@^17.0.2:
|
react-dom@17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
||||||
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
|
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
|
||||||
@@ -3965,12 +3960,12 @@ react-dom@^17.0.2:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
scheduler "^0.20.2"
|
||||||
|
|
||||||
react-icons@^4.3.1:
|
react-icons@4.3.1:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
|
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
|
||||||
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
|
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
|
||||||
|
|
||||||
react-is@17.0.2, react-is@^17.0.2:
|
react-is@17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
@@ -3985,7 +3980,7 @@ react-refresh@0.8.3:
|
|||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||||
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
||||||
|
|
||||||
react@^17.0.2:
|
react@17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||||
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
||||||
@@ -4247,7 +4242,7 @@ shallowequal@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||||
|
|
||||||
sharp@^0.29.3:
|
sharp@0.29.3:
|
||||||
version "0.29.3"
|
version "0.29.3"
|
||||||
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2"
|
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2"
|
||||||
integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA==
|
integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA==
|
||||||
@@ -4573,7 +4568,7 @@ strip-json-comments@~2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||||
|
|
||||||
styled-components@^5.3.3:
|
styled-components@5.3.3:
|
||||||
version "5.3.3"
|
version "5.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743"
|
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743"
|
||||||
integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
|
integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
|
||||||
@@ -4730,7 +4725,7 @@ trouter@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
regexparam "^1.3.0"
|
regexparam "^1.3.0"
|
||||||
|
|
||||||
ts-node@^10.4.0:
|
ts-node@10.4.0:
|
||||||
version "10.4.0"
|
version "10.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
||||||
integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
|
integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
|
||||||
@@ -4841,16 +4836,16 @@ type-fest@^0.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||||
|
|
||||||
|
typescript@4.5.4:
|
||||||
|
version "4.5.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
|
||||||
|
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
|
||||||
|
|
||||||
typescript@^4.4.3:
|
typescript@^4.4.3:
|
||||||
version "4.5.3"
|
version "4.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c"
|
||||||
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
|
integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==
|
||||||
|
|
||||||
typescript@^4.5.4:
|
|
||||||
version "4.5.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
|
|
||||||
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
|
|
||||||
|
|
||||||
unbox-primitive@^1.0.1:
|
unbox-primitive@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
|
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
|
||||||
|
|||||||
Reference in New Issue
Block a user