feat: add OAuth2 authentication (#16)
This commit is contained in:
parent
8f74263daa
commit
c595d42313
@ -10,4 +10,3 @@ temp
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.lighthouseci
|
.lighthouseci
|
||||||
.vercel
|
.vercel
|
||||||
storybook-static
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
.next
|
.next
|
||||||
.lighthouseci
|
.lighthouseci
|
||||||
storybook-static
|
|
||||||
coverage
|
coverage
|
||||||
node_modules
|
node_modules
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": ["conventions", "next/core-web-vitals", "prettier"],
|
||||||
"conventions",
|
|
||||||
"next/core-web-vitals",
|
|
||||||
"plugin:storybook/recommended",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"plugins": ["prettier"],
|
"plugins": ["prettier"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"project": "./tsconfig.json"
|
"project": "./tsconfig.json"
|
||||||
@ -16,7 +11,6 @@
|
|||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"prettier/prettier": "error",
|
"prettier/prettier": "error",
|
||||||
"@next/next/no-img-element": "off",
|
"@next/next/no-img-element": "off"
|
||||||
"@typescript-eslint/no-misused-promises": "off"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -23,6 +23,3 @@ jobs:
|
|||||||
|
|
||||||
- name: 'Build'
|
- name: 'Build'
|
||||||
run: 'npm run build'
|
run: 'npm run build'
|
||||||
|
|
||||||
- name: 'Build Storybook'
|
|
||||||
run: 'npm run storybook:build'
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -48,5 +48,4 @@ npm-debug.log*
|
|||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.lighthouseci
|
.lighthouseci
|
||||||
storybook-static
|
|
||||||
.vercel
|
.vercel
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
.next
|
.next
|
||||||
.lighthouseci
|
.lighthouseci
|
||||||
storybook-static
|
|
||||||
coverage
|
coverage
|
||||||
node_modules
|
node_modules
|
||||||
**/workbox-*.js
|
**/workbox-*.js
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
const path = require('path')
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
core: {
|
|
||||||
builder: 'webpack5'
|
|
||||||
},
|
|
||||||
staticDirs: ['../public'],
|
|
||||||
stories: ['../components/**/*.stories.@(ts|tsx|js|jsx)'],
|
|
||||||
addons: [
|
|
||||||
'@storybook/addon-links',
|
|
||||||
'@storybook/addon-essentials',
|
|
||||||
'@storybook/addon-postcss',
|
|
||||||
'storybook-tailwind-dark-mode'
|
|
||||||
],
|
|
||||||
webpackFinal: async (config) => {
|
|
||||||
config.module.rules.push({
|
|
||||||
test: /\,css&/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'postcss-loader',
|
|
||||||
options: {
|
|
||||||
ident: 'postcss',
|
|
||||||
plugins: [require('tailwindcss'), require('autoprefixer')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
include: path.resolve(__dirname, '../')
|
|
||||||
})
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import * as NextImage from 'next/image'
|
|
||||||
import { addDecorator } from '@storybook/react'
|
|
||||||
import I18nProvider from 'next-translate/I18nProvider'
|
|
||||||
|
|
||||||
import i18n from '../i18n.json'
|
|
||||||
import common from '../locales/en/common.json'
|
|
||||||
import authentication from '../locales/en/authentication.json'
|
|
||||||
import application from '../locales/en/application.json'
|
|
||||||
|
|
||||||
import '../styles/global.css'
|
|
||||||
|
|
||||||
import '@fontsource/montserrat/400.css'
|
|
||||||
import '@fontsource/montserrat/500.css'
|
|
||||||
import '@fontsource/montserrat/600.css'
|
|
||||||
import '@fontsource/montserrat/700.css'
|
|
||||||
|
|
||||||
import '@fontsource/roboto/400.css'
|
|
||||||
import '@fontsource/roboto/700.css'
|
|
||||||
|
|
||||||
addDecorator((story) => (
|
|
||||||
<I18nProvider
|
|
||||||
lang='en'
|
|
||||||
namespaces={{
|
|
||||||
common,
|
|
||||||
authentication,
|
|
||||||
application
|
|
||||||
}}
|
|
||||||
config={i18n}
|
|
||||||
>
|
|
||||||
<div id='preview-storybook'>{story()}</div>
|
|
||||||
</I18nProvider>
|
|
||||||
))
|
|
||||||
|
|
||||||
const OriginalNextImage = NextImage.default
|
|
||||||
|
|
||||||
Object.defineProperty(NextImage, 'default', {
|
|
||||||
configurable: true,
|
|
||||||
value: (props) => <OriginalNextImage {...props} unoptimized />
|
|
||||||
})
|
|
@ -1,16 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { channelExample } from '../../../../cypress/fixtures/channels/channel'
|
|
||||||
import { Channel as Component, ChannelProps } from './Channel'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Channel',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Channel: Story<ChannelProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Channel.args = { path: { channelId: 1, guildId: 1 }, channel: channelExample }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { CreateGuild as Component } from './CreateGuild'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'CreateGuild',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const CreateGuild: Story = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
CreateGuild.args = {}
|
|
@ -6,10 +6,9 @@ import { PhotographIcon } from '@heroicons/react/solid'
|
|||||||
import { Form } from 'react-component-form'
|
import { Form } from 'react-component-form'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
import { HandleSubmitCallback, useForm } from '../../../hooks/useForm'
|
||||||
import { guildSchema } from 'models/Guild'
|
import { guildSchema } from '../../../models/Guild'
|
||||||
import { FormState } from 'components/design/FormState'
|
import { FormState } from '../../design/FormState'
|
||||||
|
|
||||||
import { API_URL } from '../../../tools/api'
|
import { API_URL } from '../../../tools/api'
|
||||||
import { useGuildMember } from '../../../contexts/GuildMember'
|
import { useGuildMember } from '../../../contexts/GuildMember'
|
||||||
import { Textarea } from '../../design/Textarea'
|
import { Textarea } from '../../design/Textarea'
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Guild as Component, GuildProps } from './Guild'
|
|
||||||
import { guildExample } from '../../../../cypress/fixtures/guilds/guild'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Guild',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Guild: Story<GuildProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Guild.args = {
|
|
||||||
guild: {
|
|
||||||
...guildExample,
|
|
||||||
defaultChannelId: 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,10 +5,9 @@ import useTranslation from 'next-translate/useTranslation'
|
|||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { Emoji } from 'components/Emoji'
|
import { Emoji } from '../../../Emoji'
|
||||||
import { ConfirmGuildJoin } from 'components/Application/ConfirmGuildJoin'
|
import { ConfirmGuildJoin } from '../../ConfirmGuildJoin'
|
||||||
import { API_URL } from 'tools/api'
|
import { API_URL } from '../../../../tools/api'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GuildPublic as GuildPublicType,
|
GuildPublic as GuildPublicType,
|
||||||
GuildWithDefaultChannelId
|
GuildWithDefaultChannelId
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Member as Component, MemberProps } from './Member'
|
|
||||||
import { memberExampleComplete } from '../../../../cypress/fixtures/members/member'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Member',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Member: Story<MemberProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Member.args = { member: memberExampleComplete }
|
|
@ -1,16 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Message as Component, MessageProps } from './Message'
|
|
||||||
import { messageExampleComplete } from '../../../../cypress/fixtures/messages/message'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Message',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Message: Story<MessageProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Message.args = { message: messageExampleComplete }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { PopupGuild as Component, PopupGuildProps } from './PopupGuild'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'PopupGuild',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const PopupGuild: Story<PopupGuildProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
PopupGuild.args = {}
|
|
@ -1,36 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
import { PlusSmIcon } from '@heroicons/react/solid'
|
|
||||||
import Image from 'next/image'
|
|
||||||
|
|
||||||
import {
|
|
||||||
PopupGuildCard as Component,
|
|
||||||
PopupGuildCardProps
|
|
||||||
} from './PopupGuildCard'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'PopupGuildCard',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const PopupGuildCard: Story<PopupGuildCardProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
PopupGuildCard.args = {
|
|
||||||
image: (
|
|
||||||
<Image
|
|
||||||
src='/images/svg/design/create-server.svg'
|
|
||||||
alt=''
|
|
||||||
width={230}
|
|
||||||
height={230}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
description:
|
|
||||||
'Create your own guild and manage everything within a few clicks !',
|
|
||||||
link: {
|
|
||||||
icon: <PlusSmIcon className='mr-2 h-8 w-8' />,
|
|
||||||
text: 'Create a server',
|
|
||||||
href: '/application/guilds/create'
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { channelExample } from '../../../cypress/fixtures/channels/channel'
|
|
||||||
import { guildExample } from '../../../cypress/fixtures/guilds/guild'
|
|
||||||
import { SendMessage as Component, SendMessageProps } from './SendMessage'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'SendMessage',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const SendMessage: Story<SendMessageProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
SendMessage.args = {
|
|
||||||
path: { channelId: channelExample.id, guildId: guildExample.id }
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Sidebar as Component, SidebarProps } from './Sidebar'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Sidebar',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Sidebar: Story<SidebarProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import {
|
|
||||||
guildExample,
|
|
||||||
guildExample2
|
|
||||||
} from '../../../cypress/fixtures/guilds/guild'
|
|
||||||
import {
|
|
||||||
userExample,
|
|
||||||
userSettingsExample
|
|
||||||
} from '../../../cypress/fixtures/users/user'
|
|
||||||
import { UserProfile as Component, UserProfileProps } from './UserProfile'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'UserProfile',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const UserProfile: Story<UserProfileProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
UserProfile.args = {
|
|
||||||
user: {
|
|
||||||
...userExample,
|
|
||||||
settings: userSettingsExample
|
|
||||||
},
|
|
||||||
guilds: [guildExample, guildExample2]
|
|
||||||
}
|
|
@ -1,16 +1,10 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import React, { useState } from 'react'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
import date from 'date-and-time'
|
import date from 'date-and-time'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
import { XIcon } from '@heroicons/react/solid'
|
|
||||||
|
|
||||||
import { API_URL } from '../../../tools/api'
|
import { API_URL } from '../../../tools/api'
|
||||||
import { UserPublic } from '../../../models/User'
|
import { UserPublic } from '../../../models/User'
|
||||||
import { UserProfileGuilds } from './UserProfileGuilds'
|
|
||||||
import { UserProfileGuild } from './UserProfileGuilds/UserProfileGuild'
|
|
||||||
import { Guild } from '../../../models/Guild'
|
import { Guild } from '../../../models/Guild'
|
||||||
import { ConfirmGuildJoin } from '../ConfirmGuildJoin'
|
|
||||||
|
|
||||||
export interface UserProfileProps {
|
export interface UserProfileProps {
|
||||||
className?: string
|
className?: string
|
||||||
@ -19,27 +13,12 @@ export interface UserProfileProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
||||||
const { user, guilds } = props
|
const { user } = props
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const [showPopup, setShowPopup] = useState(false)
|
|
||||||
const [confirmation, setConfirmation] = useState(false)
|
|
||||||
|
|
||||||
const handleConfirmationState = (): void => {
|
|
||||||
setConfirmation((confirmation) => !confirmation)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePopupVisibility = (): void => {
|
|
||||||
setShowPopup((showPopup) => !showPopup)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='relative flex h-full flex-col items-center justify-center'>
|
<div className='relative flex h-full flex-col items-center justify-center'>
|
||||||
<div
|
<div className='transition'>
|
||||||
className={classNames('transition', {
|
|
||||||
'select-none blur-3xl': showPopup
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className='max-w-[1000px] px-12'>
|
<div className='max-w-[1000px] px-12'>
|
||||||
<div className='flex items-center justify-between'>
|
<div className='flex items-center justify-between'>
|
||||||
<div className='flex w-max items-center'>
|
<div className='flex w-max items-center'>
|
||||||
@ -109,13 +88,6 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='py-8 px-4' onClick={handlePopupVisibility}>
|
|
||||||
<UserProfileGuilds
|
|
||||||
isPublicGuilds={user.settings.isPublicGuilds}
|
|
||||||
guilds={guilds}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-7'>
|
<div className='mt-7'>
|
||||||
{user.biography != null && (
|
{user.biography != null && (
|
||||||
@ -124,46 +96,6 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'pointer-events-none invisible absolute top-0 flex h-full w-full items-center justify-center bg-zinc-900/75 opacity-0 transition',
|
|
||||||
{
|
|
||||||
'pointer-events-auto !visible !opacity-100': showPopup
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'relative h-[400px] w-[400px] scale-0 overflow-y-auto overflow-x-hidden rounded-2xl bg-gray-200 py-2 shadow-xl transition dark:bg-gray-800',
|
|
||||||
{ 'scale-100': showPopup }
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classNames('relative h-full transition', {
|
|
||||||
'-translate-x-[150%]': confirmation
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<UserProfileGuild
|
|
||||||
handleConfirmationState={handleConfirmationState}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ConfirmGuildJoin
|
|
||||||
className={classNames(
|
|
||||||
'absolute top-0 left-[150%] flex h-full w-full flex-col items-center justify-center transition-all',
|
|
||||||
{ 'left-[0%]': confirmation }
|
|
||||||
)}
|
|
||||||
handleYes={handleConfirmationState}
|
|
||||||
handleNo={() => {}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<XIcon
|
|
||||||
height={40}
|
|
||||||
onClick={handlePopupVisibility}
|
|
||||||
className='absolute top-8 right-8 cursor-pointer text-white transition hover:rotate-90'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import {
|
|
||||||
UserProfileGuild as Component,
|
|
||||||
UserProfileGuildProps
|
|
||||||
} from './UserProfileGuild'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'UserProfileGuild',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const UserProfileGuild: Story<UserProfileGuildProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
UserProfileGuild.args = { className: 'text-center' }
|
|
@ -1,12 +0,0 @@
|
|||||||
import { render } from '@testing-library/react'
|
|
||||||
|
|
||||||
import { UserProfileGuild } from './UserProfileGuild'
|
|
||||||
|
|
||||||
describe('<UserProfileGuild />', () => {
|
|
||||||
it('should render successfully', () => {
|
|
||||||
const { baseElement } = render(
|
|
||||||
<UserProfileGuild handleConfirmationState={() => {}} />
|
|
||||||
)
|
|
||||||
expect(baseElement).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,50 +0,0 @@
|
|||||||
import Image from 'next/image'
|
|
||||||
import { LoginIcon } from '@heroicons/react/solid'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
|
|
||||||
export interface UserProfileGuildProps {
|
|
||||||
className?: string
|
|
||||||
handleConfirmationState: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UserProfileGuild: React.FC<UserProfileGuildProps> = ({
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'group relative flex w-full cursor-pointer transition',
|
|
||||||
props.className
|
|
||||||
)}
|
|
||||||
onClick={props.handleConfirmationState}
|
|
||||||
>
|
|
||||||
<div className='relative w-full px-8 py-5 transition group-hover:-translate-x-20'>
|
|
||||||
<div className='flex transition group-hover:opacity-40'>
|
|
||||||
<div className='mr-8 flex min-h-[60px] min-w-[60px] select-none justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_1.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex flex-col'>
|
|
||||||
<h1 className='text-xl font-bold'>Guild Name</h1>
|
|
||||||
<p className='mt-2 text-gray-900 dark:text-gray-300'>
|
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Debitis,
|
|
||||||
nam.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='absolute top-0 right-[-80px] flex h-full w-[80px] items-center justify-center'>
|
|
||||||
<LoginIcon
|
|
||||||
height={40}
|
|
||||||
className='fill-green-600 drop-shadow-[0_0_15px_rgba(22,163,74,0.50)]'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from './UserProfileGuild'
|
|
@ -1,20 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import {
|
|
||||||
UserProfileGuilds as Component,
|
|
||||||
UserProfileGuildsProps
|
|
||||||
} from './UserProfileGuilds'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'UserProfileGuilds',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const UserProfileGuilds: Story<UserProfileGuildsProps> = (
|
|
||||||
arguments_
|
|
||||||
) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
UserProfileGuilds.args = {}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { render } from '@testing-library/react'
|
|
||||||
|
|
||||||
import { UserProfileGuilds } from './UserProfileGuilds'
|
|
||||||
|
|
||||||
describe('<UserProfileGuilds />', () => {
|
|
||||||
it('should render successfully', () => {
|
|
||||||
const { baseElement } = render(<UserProfileGuilds />)
|
|
||||||
expect(baseElement).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,107 +0,0 @@
|
|||||||
import Image from 'next/image'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
import { EyeOffIcon } from '@heroicons/react/solid'
|
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
|
||||||
|
|
||||||
import { Guild } from '../../../../models/Guild'
|
|
||||||
|
|
||||||
export interface UserProfileGuildsProps {
|
|
||||||
isPublicGuilds?: boolean
|
|
||||||
guilds: Guild[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UserProfileGuilds: React.FC<UserProfileGuildsProps> = (props) => {
|
|
||||||
const { isPublicGuilds = false } = props
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames('relative cursor-pointer', {
|
|
||||||
'cursor-auto': !isPublicGuilds
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={classNames('flex -space-x-7', {
|
|
||||||
'select-none blur-lg': !isPublicGuilds
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_1.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_2.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_3.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_4.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_5.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='flex items-center justify-center rounded-full drop-shadow-lg filter'>
|
|
||||||
<Image
|
|
||||||
className='rounded-full'
|
|
||||||
src='/images/guilds/Guild_6.svg'
|
|
||||||
alt={'Profil Picture'}
|
|
||||||
draggable='false'
|
|
||||||
height={60}
|
|
||||||
width={60}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='z-10 flex h-[60px] w-[60px] items-center justify-center rounded-full bg-gray-300 drop-shadow-lg filter dark:bg-gray-800'>
|
|
||||||
<span className='select-none text-xl font-bold text-black dark:text-white'>
|
|
||||||
+4
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'absolute top-1/2 flex -translate-y-1/2 items-center',
|
|
||||||
{ hidden: isPublicGuilds }
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<EyeOffIcon height={25} />
|
|
||||||
<p className='ml-4 drop-shadow-2xl'>
|
|
||||||
{t('application:private-user-guilds-list')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from './UserProfileGuilds'
|
|
@ -7,7 +7,6 @@ import { Type } from '@sinclair/typebox'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { API_URL } from '../../../tools/api'
|
import { API_URL } from '../../../tools/api'
|
||||||
import { UserProfileGuilds } from '../UserProfile/UserProfileGuilds'
|
|
||||||
import { Input } from '../../design/Input'
|
import { Input } from '../../design/Input'
|
||||||
import { Checkbox } from '../../design/Checkbox'
|
import { Checkbox } from '../../design/Checkbox'
|
||||||
import { Textarea } from '../../design/Textarea'
|
import { Textarea } from '../../design/Textarea'
|
||||||
@ -20,11 +19,9 @@ import { FormState } from '../../design/FormState'
|
|||||||
import { useForm, HandleSubmitCallback } from '../../../hooks/useForm'
|
import { useForm, HandleSubmitCallback } from '../../../hooks/useForm'
|
||||||
import { userCurrentSchema, userSchema } from '../../../models/User'
|
import { userCurrentSchema, userSchema } from '../../../models/User'
|
||||||
import { userSettingsSchema } from '../../../models/UserSettings'
|
import { userSettingsSchema } from '../../../models/UserSettings'
|
||||||
import { useGuilds } from '../../../contexts/Guilds'
|
|
||||||
|
|
||||||
export const UserSettings: React.FC = () => {
|
export const UserSettings: React.FC = () => {
|
||||||
const { user, setUser, authentication } = useAuthentication()
|
const { user, setUser, authentication } = useAuthentication()
|
||||||
const { guilds } = useGuilds()
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [inputValues, setInputValues] = useState({
|
const [inputValues, setInputValues] = useState({
|
||||||
name: user.name,
|
name: user.name,
|
||||||
@ -212,20 +209,6 @@ export const UserSettings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-10 ml-0 flex flex-col items-center lg:ml-24 lg:mt-0'>
|
|
||||||
<UserProfileGuilds
|
|
||||||
isPublicGuilds={inputValues.isPublicGuilds}
|
|
||||||
guilds={guilds}
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
name='isPublicGuilds'
|
|
||||||
label={t('application:label-checkbox-guilds')}
|
|
||||||
onChange={onChangeCheckbox}
|
|
||||||
checked={inputValues.isPublicGuilds}
|
|
||||||
id='checkbox-public-guilds'
|
|
||||||
className='px-8'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-12 flex w-full flex-col items-center justify-between sm:w-fit lg:flex-row'>
|
<div className='mt-12 flex w-full flex-col items-center justify-between sm:w-fit lg:flex-row'>
|
||||||
<div className='w-4/5 pr-0 sm:w-[450px] lg:border-r-[1px] lg:border-neutral-700 lg:pr-12'>
|
<div className='w-4/5 pr-0 sm:w-[450px] lg:border-r-[1px] lg:border-neutral-700 lg:pr-12'>
|
||||||
|
@ -4,7 +4,6 @@ import useTranslation from 'next-translate/useTranslation'
|
|||||||
import { useTheme } from 'next-themes'
|
import { useTheme } from 'next-themes'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { SocialMediaButton } from '../design/SocialMediaButton'
|
|
||||||
import { Main } from '../design/Main'
|
import { Main } from '../design/Main'
|
||||||
import { Input } from '../design/Input'
|
import { Input } from '../design/Input'
|
||||||
import { Button } from '../design/Button'
|
import { Button } from '../design/Button'
|
||||||
@ -17,6 +16,7 @@ import {
|
|||||||
Authentication as AuthenticationClass
|
Authentication as AuthenticationClass
|
||||||
} from '../../tools/authentication'
|
} from '../../tools/authentication'
|
||||||
import { useForm, HandleSubmitCallback } from '../../hooks/useForm'
|
import { useForm, HandleSubmitCallback } from '../../hooks/useForm'
|
||||||
|
import { AuthenticationSocialMedia } from './AuthenticationSocialMedia'
|
||||||
|
|
||||||
export interface AuthenticationProps {
|
export interface AuthenticationProps {
|
||||||
mode: 'signup' | 'signin'
|
mode: 'signup' | 'signin'
|
||||||
@ -93,13 +93,7 @@ export const Authentication: React.FC<AuthenticationProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Main>
|
<Main>
|
||||||
<div className='flex flex-col sm:w-full sm:items-center'>
|
<AuthenticationSocialMedia />
|
||||||
<div className='flex flex-col items-center justify-center space-y-6 sm:w-4/6 sm:flex-row sm:space-x-6 sm:space-y-0'>
|
|
||||||
<SocialMediaButton socialMedia='Google' />
|
|
||||||
<SocialMediaButton socialMedia='GitHub' />
|
|
||||||
<SocialMediaButton socialMedia='Discord' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='pt-8 text-center font-paragraph text-lg'>
|
<div className='pt-8 text-center font-paragraph text-lg'>
|
||||||
{t('authentication:or')}
|
{t('authentication:or')}
|
||||||
</div>
|
</div>
|
||||||
|
50
components/Authentication/AuthenticationSocialMedia.tsx
Normal file
50
components/Authentication/AuthenticationSocialMedia.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
|
import { api } from '../../tools/api'
|
||||||
|
import { Authentication, isTokens } from '../../tools/authentication'
|
||||||
|
import { SocialMediaButton, SocialMedia } from '../design/SocialMediaButton'
|
||||||
|
|
||||||
|
export const AuthenticationSocialMedia: React.FC = () => {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const handleAuthentication = (
|
||||||
|
socialMedia: SocialMedia
|
||||||
|
): (() => Promise<void>) => {
|
||||||
|
return async () => {
|
||||||
|
const redirect = window.location.href
|
||||||
|
const { data: url } = await api.get(
|
||||||
|
`/users/oauth2/${socialMedia.toLowerCase()}/signin?redirectURI=${redirect}`
|
||||||
|
)
|
||||||
|
window.location.href = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const data = router.query
|
||||||
|
if (isTokens(data)) {
|
||||||
|
const authentication = new Authentication(data)
|
||||||
|
authentication.signin()
|
||||||
|
router.push('/application').catch(() => {})
|
||||||
|
}
|
||||||
|
}, [router])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-col sm:w-full sm:items-center'>
|
||||||
|
<div className='flex flex-col items-center justify-center space-y-6 sm:w-4/6 sm:flex-row sm:space-x-6 sm:space-y-0'>
|
||||||
|
<SocialMediaButton
|
||||||
|
socialMedia='Google'
|
||||||
|
onClick={handleAuthentication('Google')}
|
||||||
|
/>
|
||||||
|
<SocialMediaButton
|
||||||
|
socialMedia='GitHub'
|
||||||
|
onClick={handleAuthentication('GitHub')}
|
||||||
|
/>
|
||||||
|
<SocialMediaButton
|
||||||
|
socialMedia='Discord'
|
||||||
|
onClick={handleAuthentication('Discord')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Emoji as Component, EmojiProps } from './Emoji'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Emoji',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Emoji: Story<EmojiProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Emoji.args = { value: ':wave:', size: 20 }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { EmojiPicker as Component, EmojiPickerProps } from './EmojiPicker'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'EmojiPicker',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const EmojiPicker: Story<EmojiPickerProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
EmojiPicker.args = { onClick: (emoji, event) => console.log(emoji, event) }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { ErrorPage as Component, ErrorPageProps } from './ErrorPage'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'ErrorPage',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const ErrorPage: Story<ErrorPageProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
ErrorPage.args = { message: 'message content', statusCode: 404 }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Footer as Component, FooterProps } from '.'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Footer',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Footer: Story<FooterProps> = (arguments_) => (
|
|
||||||
<Component {...arguments_} />
|
|
||||||
)
|
|
||||||
Footer.args = { version: '1.0.0' }
|
|
@ -1,12 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Header as Component } from '.'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Header',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Header: Story = (arguments_) => <Component {...arguments_} />
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Button as Component, ButtonProps } from './Button'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Button',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Button: Story<ButtonProps> = (arguments_) => (
|
|
||||||
<Component {...arguments_} />
|
|
||||||
)
|
|
||||||
Button.args = { children: 'Get started' }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Checkbox as Component, CheckboxProps } from './Checkbox'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Checkbox',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Checkbox: Story<CheckboxProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Checkbox.args = { label: 'Checkbox' }
|
|
@ -1,12 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Divider as Component } from '.'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Divider',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Divider: Story = (arguments_) => <Component {...arguments_} />
|
|
@ -1,30 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Input, InputProps } from './Input'
|
|
||||||
import { AuthenticationForm } from '../../Authentication/AuthenticationForm'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Input',
|
|
||||||
component: Input
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
const Template: Story<InputProps> = (arguments_) => (
|
|
||||||
<AuthenticationForm>
|
|
||||||
<Input {...arguments_} />
|
|
||||||
</AuthenticationForm>
|
|
||||||
)
|
|
||||||
|
|
||||||
export const Text = Template.bind({})
|
|
||||||
Text.args = { label: 'Text', name: 'text', type: 'text' }
|
|
||||||
|
|
||||||
export const Password = Template.bind({})
|
|
||||||
Password.args = { label: 'Password', name: 'password', type: 'password' }
|
|
||||||
|
|
||||||
export const Error = Template.bind({})
|
|
||||||
Error.args = {
|
|
||||||
label: 'Error',
|
|
||||||
type: 'text',
|
|
||||||
error: 'Oops, this field is required 🙈.'
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Loader as Component, LoaderProps } from './Loader'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Loader',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Loader: Story<LoaderProps> = (arguments_) => (
|
|
||||||
<Component {...arguments_} />
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { SocialMediaButton, SocialMediaButtonProps } from './SocialMediaButton'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'SocialMediaButton',
|
|
||||||
component: SocialMediaButton
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
const Template: Story<SocialMediaButtonProps> = (arguments_) => (
|
|
||||||
<SocialMediaButton {...arguments_} />
|
|
||||||
)
|
|
||||||
|
|
||||||
export const Github = Template.bind({})
|
|
||||||
Github.args = { socialMedia: 'GitHub' }
|
|
||||||
|
|
||||||
export const Discord = Template.bind({})
|
|
||||||
Discord.args = { socialMedia: 'Discord' }
|
|
||||||
|
|
||||||
export const Google = Template.bind({})
|
|
||||||
Google.args = { socialMedia: 'Google' }
|
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { Textarea as Component, TextareaProps } from './Textarea'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: 'Textarea',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const Textarea: Story<TextareaProps> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
Textarea.args = { label: 'Textarea' }
|
|
@ -1,11 +1,11 @@
|
|||||||
import { createContext, useContext, useEffect } from 'react'
|
import { createContext, useContext, useEffect } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||||
import { useAuthentication } from 'tools/authentication'
|
import { useAuthentication } from '../tools/authentication'
|
||||||
import { Channel, ChannelWithDefaultChannelId } from 'models/Channel'
|
import { Channel, ChannelWithDefaultChannelId } from '../models/Channel'
|
||||||
import { GuildsChannelsPath } from 'components/Application'
|
import { GuildsChannelsPath } from '../components/Application'
|
||||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||||
|
|
||||||
export interface Channels {
|
export interface Channels {
|
||||||
channels: Channel[]
|
channels: Channel[]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { createContext, useContext, useEffect, useState } from 'react'
|
import { createContext, useContext, useEffect, useState } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
import { GuildWithDefaultChannelId } from 'models/Guild'
|
import { GuildWithDefaultChannelId } from '../models/Guild'
|
||||||
import { Member } from 'models/Member'
|
import { Member } from '../models/Member'
|
||||||
import { useAuthentication } from 'tools/authentication'
|
import { useAuthentication } from '../tools/authentication'
|
||||||
import { SocketData } from 'tools/handleSocketData'
|
import { SocketData } from '../tools/handleSocketData'
|
||||||
|
|
||||||
export interface GuildMember {
|
export interface GuildMember {
|
||||||
guild: GuildWithDefaultChannelId
|
guild: GuildWithDefaultChannelId
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { createContext, useContext, useEffect } from 'react'
|
import { createContext, useContext, useEffect } from 'react'
|
||||||
|
|
||||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||||
import { useAuthentication } from 'tools/authentication'
|
import { useAuthentication } from '../tools/authentication'
|
||||||
import { GuildWithDefaultChannelId } from 'models/Guild'
|
import { GuildWithDefaultChannelId } from '../models/Guild'
|
||||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||||
|
|
||||||
export interface Guilds {
|
export interface Guilds {
|
||||||
guilds: GuildWithDefaultChannelId[]
|
guilds: GuildWithDefaultChannelId[]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { createContext, useContext, useEffect } from 'react'
|
import { createContext, useContext, useEffect } from 'react'
|
||||||
|
|
||||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||||
import { useAuthentication } from 'tools/authentication'
|
import { useAuthentication } from '../tools/authentication'
|
||||||
import { MemberWithPublicUser } from 'models/Member'
|
import { MemberWithPublicUser } from '../models/Member'
|
||||||
import { GuildsChannelsPath } from 'components/Application'
|
import { GuildsChannelsPath } from '../components/Application'
|
||||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||||
import { User } from 'models/User'
|
import { User } from '../models/User'
|
||||||
|
|
||||||
export interface Members {
|
export interface Members {
|
||||||
members: MemberWithPublicUser[]
|
members: MemberWithPublicUser[]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { createContext, useContext, useEffect } from 'react'
|
import { createContext, useContext, useEffect } from 'react'
|
||||||
|
|
||||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||||
import { useAuthentication } from 'tools/authentication'
|
import { useAuthentication } from '../tools/authentication'
|
||||||
import { MessageWithMember } from 'models/Message'
|
import { MessageWithMember } from '../models/Message'
|
||||||
import { GuildsChannelsPath } from 'components/Application'
|
import { GuildsChannelsPath } from '../components/Application'
|
||||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||||
|
|
||||||
export interface Messages {
|
export interface Messages {
|
||||||
messages: MessageWithMember[]
|
messages: MessageWithMember[]
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { deleteLeaveMembersWithGuildIdHandler } from 'cypress/fixtures/guilds/[guildId]/members/leave'
|
import { deleteLeaveMembersWithGuildIdHandler } from '../../../../fixtures/guilds/[guildId]/members/leave'
|
||||||
|
|
||||||
import { guildExample } from '../../../../fixtures/guilds/guild'
|
import { guildExample } from '../../../../fixtures/guilds/guild'
|
||||||
import {
|
import {
|
||||||
getGuildMemberNotOwnerWithGuildIdHandler,
|
getGuildMemberNotOwnerWithGuildIdHandler,
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
import { Meta, Story } from '@storybook/react'
|
|
||||||
|
|
||||||
import { {{ properCase name }} as Component, {{ properCase name }}Props } from './{{ properCase name }}'
|
|
||||||
|
|
||||||
const Stories: Meta = {
|
|
||||||
title: '{{ properCase name }}',
|
|
||||||
component: Component
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Stories
|
|
||||||
|
|
||||||
export const {{ properCase name }}: Story<{{ properCase name }}Props> = (arguments_) => {
|
|
||||||
return <Component {...arguments_} />
|
|
||||||
}
|
|
||||||
{{ properCase name }}.args = { className: 'text-center' }
|
|
36589
package-lock.json
generated
36589
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
55
package.json
55
package.json
@ -27,9 +27,6 @@
|
|||||||
"test:lighthouse": "lhci autorun",
|
"test:lighthouse": "lhci autorun",
|
||||||
"test:e2e": "start-server-and-test \"start\" \"http://localhost:3000\" \"cypress run\"",
|
"test:e2e": "start-server-and-test \"start\" \"http://localhost:3000\" \"cypress run\"",
|
||||||
"test:e2e:dev": "start-server-and-test \"dev\" \"http://localhost:3000\" \"cypress open\"",
|
"test:e2e:dev": "start-server-and-test \"dev\" \"http://localhost:3000\" \"cypress open\"",
|
||||||
"storybook": "start-storybook --port 6006",
|
|
||||||
"storybook:build": "build-storybook",
|
|
||||||
"storybook:serve": "serve -p 6006 storybook-static",
|
|
||||||
"release": "semantic-release",
|
"release": "semantic-release",
|
||||||
"deploy": "vercel",
|
"deploy": "vercel",
|
||||||
"postinstall": "husky install"
|
"postinstall": "husky install"
|
||||||
@ -41,13 +38,13 @@
|
|||||||
"@sinclair/typebox": "0.23.4",
|
"@sinclair/typebox": "0.23.4",
|
||||||
"ajv": "8.10.0",
|
"ajv": "8.10.0",
|
||||||
"ajv-formats": "2.1.1",
|
"ajv-formats": "2.1.1",
|
||||||
"axios": "0.26.0",
|
"axios": "0.26.1",
|
||||||
"classnames": "2.3.1",
|
"classnames": "2.3.1",
|
||||||
"date-and-time": "2.2.1",
|
"date-and-time": "2.3.0",
|
||||||
"emoji-mart": "3.0.1",
|
"emoji-mart": "3.0.1",
|
||||||
"katex": "0.15.2",
|
"katex": "0.15.3",
|
||||||
"next": "12.1.0",
|
"next": "12.1.0",
|
||||||
"next-pwa": "5.4.5",
|
"next-pwa": "5.4.6",
|
||||||
"next-themes": "0.1.1",
|
"next-themes": "0.1.1",
|
||||||
"next-translate": "1.3.5",
|
"next-translate": "1.3.5",
|
||||||
"pretty-bytes": "6.0.0",
|
"pretty-bytes": "6.0.0",
|
||||||
@ -55,7 +52,7 @@
|
|||||||
"react-component-form": "2.0.0",
|
"react-component-form": "2.0.0",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-infinite-scroll-component": "6.1.0",
|
"react-infinite-scroll-component": "6.1.0",
|
||||||
"react-markdown": "8.0.0",
|
"react-markdown": "8.0.1",
|
||||||
"react-responsive": "8.2.0",
|
"react-responsive": "8.2.0",
|
||||||
"react-swipeable": "6.2.0",
|
"react-swipeable": "6.2.0",
|
||||||
"react-textarea-autosize": "8.3.3",
|
"react-textarea-autosize": "8.3.3",
|
||||||
@ -64,66 +61,56 @@
|
|||||||
"remark-breaks": "3.0.2",
|
"remark-breaks": "3.0.2",
|
||||||
"remark-gfm": "3.0.1",
|
"remark-gfm": "3.0.1",
|
||||||
"remark-math": "5.1.1",
|
"remark-math": "5.1.1",
|
||||||
"sharp": "0.30.2",
|
"sharp": "0.30.3",
|
||||||
"socket.io-client": "4.4.1",
|
"socket.io-client": "4.4.1",
|
||||||
"unified": "10.1.1",
|
"unified": "10.1.2",
|
||||||
"unist-util-visit": "4.1.0",
|
"unist-util-visit": "4.1.0",
|
||||||
"universal-cookie": "4.0.4"
|
"universal-cookie": "4.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "16.2.1",
|
"@commitlint/cli": "16.2.3",
|
||||||
"@commitlint/config-conventional": "16.2.1",
|
"@commitlint/config-conventional": "16.2.1",
|
||||||
"@lhci/cli": "0.9.0",
|
"@lhci/cli": "0.9.0",
|
||||||
"@saithodev/semantic-release-backmerge": "2.1.2",
|
"@saithodev/semantic-release-backmerge": "2.1.2",
|
||||||
"@storybook/addon-essentials": "6.4.19",
|
|
||||||
"@storybook/addon-links": "6.4.19",
|
|
||||||
"@storybook/addon-postcss": "2.0.0",
|
|
||||||
"@storybook/builder-webpack5": "6.4.19",
|
|
||||||
"@storybook/manager-webpack5": "6.4.19",
|
|
||||||
"@storybook/react": "6.4.19",
|
|
||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "5.16.2",
|
||||||
"@testing-library/react": "12.1.3",
|
"@testing-library/react": "12.1.4",
|
||||||
"@types/date-and-time": "0.13.0",
|
|
||||||
"@types/emoji-mart": "3.0.9",
|
"@types/emoji-mart": "3.0.9",
|
||||||
"@types/hast": "2.3.4",
|
"@types/hast": "2.3.4",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@types/katex": "0.11.1",
|
"@types/katex": "0.11.1",
|
||||||
"@types/node": "17.0.21",
|
"@types/node": "17.0.21",
|
||||||
"@types/react": "17.0.39",
|
"@types/react": "17.0.40",
|
||||||
"@types/react-responsive": "8.0.5",
|
"@types/react-responsive": "8.0.5",
|
||||||
"@types/unist": "2.0.6",
|
"@types/unist": "2.0.6",
|
||||||
"@typescript-eslint/eslint-plugin": "5.13.0",
|
"@typescript-eslint/eslint-plugin": "5.15.0",
|
||||||
"@typescript-eslint/parser": "5.13.0",
|
"@typescript-eslint/parser": "5.15.0",
|
||||||
"autoprefixer": "10.4.2",
|
"autoprefixer": "10.4.4",
|
||||||
"cypress": "9.5.1",
|
"cypress": "9.5.2",
|
||||||
"editorconfig-checker": "4.0.2",
|
"editorconfig-checker": "4.0.2",
|
||||||
"eslint": "8.10.0",
|
"eslint": "8.11.0",
|
||||||
"eslint-config-conventions": "1.1.0",
|
"eslint-config-conventions": "1.1.1",
|
||||||
"eslint-config-next": "12.1.0",
|
"eslint-config-next": "12.1.0",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-plugin-import": "2.25.4",
|
"eslint-plugin-import": "2.25.4",
|
||||||
"eslint-plugin-prettier": "4.0.0",
|
"eslint-plugin-prettier": "4.0.0",
|
||||||
"eslint-plugin-promise": "6.0.0",
|
"eslint-plugin-promise": "6.0.0",
|
||||||
"eslint-plugin-storybook": "0.5.7",
|
|
||||||
"eslint-plugin-unicorn": "41.0.0",
|
"eslint-plugin-unicorn": "41.0.0",
|
||||||
"html-w3c-validator": "1.1.0",
|
"html-w3c-validator": "1.1.0",
|
||||||
"husky": "7.0.4",
|
"husky": "7.0.4",
|
||||||
"jest": "27.5.1",
|
"jest": "27.5.1",
|
||||||
"lint-staged": "12.3.5",
|
"lint-staged": "12.3.6",
|
||||||
"markdownlint-cli": "0.31.1",
|
"markdownlint-cli": "0.31.1",
|
||||||
"mockttp": "2.6.0",
|
"mockttp": "2.7.0",
|
||||||
"next-secure-headers": "2.2.0",
|
"next-secure-headers": "2.2.0",
|
||||||
"plop": "3.0.5",
|
"plop": "3.0.5",
|
||||||
"postcss": "8.4.7",
|
"postcss": "8.4.12",
|
||||||
"prettier": "2.5.1",
|
"prettier": "2.6.0",
|
||||||
"prettier-plugin-tailwindcss": "0.1.8",
|
"prettier-plugin-tailwindcss": "0.1.8",
|
||||||
"semantic-release": "19.0.2",
|
"semantic-release": "19.0.2",
|
||||||
"serve": "13.0.2",
|
"serve": "13.0.2",
|
||||||
"start-server-and-test": "1.14.0",
|
"start-server-and-test": "1.14.0",
|
||||||
"storybook-tailwind-dark-mode": "1.0.11",
|
|
||||||
"tailwindcss": "3.0.23",
|
"tailwindcss": "3.0.23",
|
||||||
"typescript": "4.6.2",
|
"typescript": "4.6.2",
|
||||||
"vercel": "24.0.0",
|
"vercel": "24.0.0"
|
||||||
"webpack": "5.70.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { GetStaticProps, NextPage } from 'next'
|
import { GetStaticProps, NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { ErrorPage } from 'components/ErrorPage'
|
import { ErrorPage } from '../components/ErrorPage'
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../components/Head'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../components/Header'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../components/Footer'
|
||||||
|
|
||||||
const Error404: NextPage<FooterProps> = (props) => {
|
const Error404: NextPage<FooterProps> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { GetStaticProps, NextPage } from 'next'
|
import { GetStaticProps, NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { ErrorPage } from 'components/ErrorPage'
|
import { ErrorPage } from '../components/ErrorPage'
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../components/Head'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../components/Header'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../components/Footer'
|
||||||
|
|
||||||
const Error500: NextPage<FooterProps> = (props) => {
|
const Error500: NextPage<FooterProps> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -3,7 +3,7 @@ import { AppProps } from 'next/app'
|
|||||||
import { ThemeProvider } from 'next-themes'
|
import { ThemeProvider } from 'next-themes'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import 'styles/global.css'
|
import '../styles/global.css'
|
||||||
|
|
||||||
import '@fontsource/montserrat/400.css'
|
import '@fontsource/montserrat/400.css'
|
||||||
import '@fontsource/montserrat/500.css'
|
import '@fontsource/montserrat/500.css'
|
||||||
@ -13,7 +13,7 @@ import '@fontsource/montserrat/700.css'
|
|||||||
import '@fontsource/roboto/400.css'
|
import '@fontsource/roboto/400.css'
|
||||||
import '@fontsource/roboto/700.css'
|
import '@fontsource/roboto/700.css'
|
||||||
|
|
||||||
import { cookies } from 'tools/cookies'
|
import { cookies } from '../tools/cookies'
|
||||||
|
|
||||||
const Application = ({ Component, pageProps }: AppProps): JSX.Element => {
|
const Application = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||||
const { lang } = useTranslation()
|
const { lang } = useTranslation()
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../../components/Application'
|
||||||
import { Messages } from 'components/Application/Messages'
|
import { Messages } from '../../../../components/Application/Messages'
|
||||||
import { SendMessage } from 'components/Application/SendMessage'
|
import { SendMessage } from '../../../../components/Application/SendMessage'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../../tools/authentication'
|
||||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
import {
|
||||||
import { GuildLeftSidebar } from 'components/Application/GuildLeftSidebar'
|
GuildMember,
|
||||||
import { ChannelsProvider } from 'contexts/Channels'
|
GuildMemberProvider
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
} from '../../../../contexts/GuildMember'
|
||||||
import { Channel } from 'models/Channel'
|
import { GuildLeftSidebar } from '../../../../components/Application/GuildLeftSidebar'
|
||||||
import { MessagesProvider } from 'contexts/Messages'
|
import { ChannelsProvider } from '../../../../contexts/Channels'
|
||||||
import { MembersProviders } from 'contexts/Members'
|
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||||
|
import { Channel } from '../../../../models/Channel'
|
||||||
|
import { MessagesProvider } from '../../../../contexts/Messages'
|
||||||
|
import { MembersProviders } from '../../../../contexts/Members'
|
||||||
|
|
||||||
export interface ChannelPageProps extends PagePropsWithAuthentication {
|
export interface ChannelPageProps extends PagePropsWithAuthentication {
|
||||||
channelId: number
|
channelId: number
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../../tools/authentication'
|
||||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
import {
|
||||||
import { GuildLeftSidebar } from 'components/Application/GuildLeftSidebar'
|
GuildMember,
|
||||||
import { ChannelSettings } from 'components/Application/ChannelSettings'
|
GuildMemberProvider
|
||||||
import { ChannelsProvider } from 'contexts/Channels'
|
} from '../../../../contexts/GuildMember'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildLeftSidebar } from '../../../../components/Application/GuildLeftSidebar'
|
||||||
import { Channel } from 'models/Channel'
|
import { ChannelSettings } from '../../../../components/Application/ChannelSettings'
|
||||||
import { MembersProviders } from 'contexts/Members'
|
import { ChannelsProvider } from '../../../../contexts/Channels'
|
||||||
|
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||||
|
import { Channel } from '../../../../models/Channel'
|
||||||
|
import { MembersProviders } from '../../../../contexts/Members'
|
||||||
|
|
||||||
export interface ChannelSettingsPageProps extends PagePropsWithAuthentication {
|
export interface ChannelSettingsPageProps extends PagePropsWithAuthentication {
|
||||||
channelId: number
|
channelId: number
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../../tools/authentication'
|
||||||
import { CreateChannel } from 'components/Application/CreateChannel'
|
import { CreateChannel } from '../../../../components/Application/CreateChannel'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
import {
|
||||||
|
GuildMember,
|
||||||
|
GuildMemberProvider
|
||||||
|
} from '../../../../contexts/GuildMember'
|
||||||
|
|
||||||
export interface CreateChannelPageProps extends PagePropsWithAuthentication {
|
export interface CreateChannelPageProps extends PagePropsWithAuthentication {
|
||||||
guildId: number
|
guildId: number
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../tools/authentication'
|
||||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
import { GuildMember, GuildMemberProvider } from '../../../contexts/GuildMember'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||||
import { GuildSettings } from 'components/Application/GuildSettings'
|
import { GuildSettings } from '../../../components/Application/GuildSettings'
|
||||||
|
|
||||||
export interface GuildSettingsPageProps extends PagePropsWithAuthentication {
|
export interface GuildSettingsPageProps extends PagePropsWithAuthentication {
|
||||||
guildId: number
|
guildId: number
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../tools/authentication'
|
||||||
import { CreateGuild } from 'components/Application/CreateGuild'
|
import { CreateGuild } from '../../../components/Application/CreateGuild'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||||
|
|
||||||
const CreateGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
const CreateGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../tools/authentication'
|
||||||
import { JoinGuildsPublic } from 'components/Application/JoinGuildsPublic'
|
import { JoinGuildsPublic } from '../../../components/Application/JoinGuildsPublic'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||||
|
|
||||||
const JoinGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
const JoinGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../components/Application'
|
||||||
import { PopupGuild } from 'components/Application/PopupGuild'
|
import { PopupGuild } from '../../components/Application/PopupGuild'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../tools/authentication'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../contexts/Guilds'
|
||||||
|
|
||||||
const ApplicationPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
const ApplicationPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../../tools/authentication'
|
||||||
import { UserProfile } from 'components/Application/UserProfile'
|
import { UserProfile } from '../../../../components/Application/UserProfile'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||||
import { UserPublic } from 'models/User'
|
import { UserPublic } from '../../../../models/User'
|
||||||
import { Guild } from 'models/Guild'
|
import { Guild } from '../../../../models/Guild'
|
||||||
|
|
||||||
export interface UserProfilePageProps extends PagePropsWithAuthentication {
|
export interface UserProfilePageProps extends PagePropsWithAuthentication {
|
||||||
user: UserPublic
|
user: UserPublic
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../../components/Head'
|
||||||
import { Application } from 'components/Application'
|
import { Application } from '../../../components/Application'
|
||||||
import {
|
import {
|
||||||
authenticationFromServerSide,
|
authenticationFromServerSide,
|
||||||
AuthenticationProvider,
|
AuthenticationProvider,
|
||||||
PagePropsWithAuthentication
|
PagePropsWithAuthentication
|
||||||
} from 'tools/authentication'
|
} from '../../../tools/authentication'
|
||||||
import { UserSettings } from 'components/Application/UserSettings'
|
import { UserSettings } from '../../../components/Application/UserSettings'
|
||||||
import { GuildsProvider } from 'contexts/Guilds'
|
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||||
|
|
||||||
const UserSettingsPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
const UserSettingsPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -3,19 +3,19 @@ import Link from 'next/link'
|
|||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { AuthenticationForm } from 'components/Authentication'
|
import { AuthenticationForm } from '../../components/Authentication'
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../components/Head'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../../components/Header'
|
||||||
import { Main } from 'components/design/Main'
|
import { Main } from '../../components/design/Main'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../../components/Footer'
|
||||||
import { Input } from 'components/design/Input'
|
import { Input } from '../../components/design/Input'
|
||||||
import { Button } from 'components/design/Button'
|
import { Button } from '../../components/design/Button'
|
||||||
import { FormState } from 'components/design/FormState'
|
import { FormState } from '../../components/design/FormState'
|
||||||
import { authenticationFromServerSide } from 'tools/authentication'
|
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||||
import { ScrollableBody } from 'components/ScrollableBody'
|
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||||
import { userSchema } from 'models/User'
|
import { userSchema } from '../../models/User'
|
||||||
import { api } from 'tools/api'
|
import { api } from '../../tools/api'
|
||||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
import { HandleSubmitCallback, useForm } from '../../hooks/useForm'
|
||||||
|
|
||||||
const ForgotPassword: NextPage<FooterProps> = (props) => {
|
const ForgotPassword: NextPage<FooterProps> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -3,19 +3,19 @@ import { useRouter } from 'next/router'
|
|||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../components/Head'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../../components/Header'
|
||||||
import { Main } from 'components/design/Main'
|
import { FormState } from '../../components/design/FormState'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Main } from '../../components/design/Main'
|
||||||
import { Input } from 'components/design/Input'
|
import { Footer, FooterProps } from '../../components/Footer'
|
||||||
import { Button } from 'components/design/Button'
|
import { Input } from '../../components/design/Input'
|
||||||
import { FormState } from 'components/design/FormState'
|
import { Button } from '../../components/design/Button'
|
||||||
import { authenticationFromServerSide } from 'tools/authentication'
|
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||||
import { AuthenticationForm } from 'components/Authentication'
|
import { AuthenticationForm } from '../../components/Authentication'
|
||||||
import { ScrollableBody } from 'components/ScrollableBody/ScrollableBody'
|
import { ScrollableBody } from '../../components/ScrollableBody/ScrollableBody'
|
||||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
import { HandleSubmitCallback, useForm } from '../../hooks/useForm'
|
||||||
import { api } from 'tools/api'
|
import { api } from '../../tools/api'
|
||||||
import { userSchema } from 'models/User'
|
import { userSchema } from '../../models/User'
|
||||||
|
|
||||||
const ResetPassword: NextPage<FooterProps> = (props) => {
|
const ResetPassword: NextPage<FooterProps> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../components/Head'
|
||||||
import { Authentication } from 'components/Authentication'
|
import { Authentication } from '../../components/Authentication'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../../components/Header'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../../components/Footer'
|
||||||
import { authenticationFromServerSide } from 'tools/authentication'
|
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||||
import { ScrollableBody } from 'components/ScrollableBody'
|
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||||
|
|
||||||
const Signin: NextPage<FooterProps> = (props) => {
|
const Signin: NextPage<FooterProps> = (props) => {
|
||||||
const { version } = props
|
const { version } = props
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../../components/Head'
|
||||||
import { Authentication } from 'components/Authentication'
|
import { Authentication } from '../../components/Authentication'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../../components/Header'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../../components/Footer'
|
||||||
import { authenticationFromServerSide } from 'tools/authentication'
|
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||||
import { ScrollableBody } from 'components/ScrollableBody'
|
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||||
|
|
||||||
const Signup: NextPage<FooterProps> = (props) => {
|
const Signup: NextPage<FooterProps> = (props) => {
|
||||||
const { version } = props
|
const { version } = props
|
||||||
|
@ -4,13 +4,13 @@ import Image from 'next/image'
|
|||||||
import Translation from 'next-translate/Trans'
|
import Translation from 'next-translate/Trans'
|
||||||
import useTranslation from 'next-translate/useTranslation'
|
import useTranslation from 'next-translate/useTranslation'
|
||||||
|
|
||||||
import { Head } from 'components/Head'
|
import { Head } from '../components/Head'
|
||||||
import { Header } from 'components/Header'
|
import { Header } from '../components/Header'
|
||||||
import { Main } from 'components/design/Main'
|
import { Main } from '../components/design/Main'
|
||||||
import { Footer, FooterProps } from 'components/Footer'
|
import { Footer, FooterProps } from '../components/Footer'
|
||||||
import { SocialMediaLink } from 'components/design/SocialMediaButton'
|
import { SocialMediaLink } from '../components/design/SocialMediaButton'
|
||||||
import { ButtonLink } from 'components/design/Button'
|
import { ButtonLink } from '../components/design/Button'
|
||||||
import { ScrollableBody } from 'components/ScrollableBody'
|
import { ScrollableBody } from '../components/ScrollableBody'
|
||||||
|
|
||||||
const Home: NextPage<FooterProps> = (props) => {
|
const Home: NextPage<FooterProps> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -6,16 +6,11 @@
|
|||||||
@apply flex h-screen flex-col;
|
@apply flex h-screen flex-col;
|
||||||
}
|
}
|
||||||
|
|
||||||
body,
|
body {
|
||||||
#preview-storybook {
|
|
||||||
@apply bg-white font-headline text-black dark:bg-black dark:text-white;
|
@apply bg-white font-headline text-black dark:bg-black dark:text-white;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#preview-storybook {
|
|
||||||
@apply min-h-screen p-6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-full-without-header {
|
.h-full-without-header {
|
||||||
height: calc(100vh - 64px);
|
height: calc(100vh - 64px);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,15 @@ export interface PagePropsWithAuthentication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isTokens = (data: { [key: string]: any }): data is Tokens => {
|
||||||
|
return (
|
||||||
|
'accessToken' in data &&
|
||||||
|
'refreshToken' in data &&
|
||||||
|
'type' in data &&
|
||||||
|
'expiresIn' in data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export * from './Authentication'
|
export * from './Authentication'
|
||||||
export * from './authenticationFromServerSide'
|
export * from './authenticationFromServerSide'
|
||||||
export * from './AuthenticationContext'
|
export * from './AuthenticationContext'
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"types": ["jest", "@testing-library/jest-dom", "@testing-library/react"],
|
"types": ["jest", "@testing-library/jest-dom", "@testing-library/react"],
|
||||||
"baseUrl": ".",
|
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
Reference in New Issue
Block a user