feat: add OAuth2 authentication (#16)
This commit is contained in:
parent
8f74263daa
commit
c595d42313
@ -10,4 +10,3 @@ temp
|
||||
.DS_Store
|
||||
.lighthouseci
|
||||
.vercel
|
||||
storybook-static
|
||||
|
@ -1,6 +1,5 @@
|
||||
.next
|
||||
.lighthouseci
|
||||
storybook-static
|
||||
coverage
|
||||
node_modules
|
||||
next-env.d.ts
|
||||
|
@ -1,10 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"conventions",
|
||||
"next/core-web-vitals",
|
||||
"plugin:storybook/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"extends": ["conventions", "next/core-web-vitals", "prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
@ -16,7 +11,6 @@
|
||||
},
|
||||
"rules": {
|
||||
"prettier/prettier": "error",
|
||||
"@next/next/no-img-element": "off",
|
||||
"@typescript-eslint/no-misused-promises": "off"
|
||||
"@next/next/no-img-element": "off"
|
||||
}
|
||||
}
|
||||
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -23,6 +23,3 @@ jobs:
|
||||
|
||||
- name: '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
|
||||
.DS_Store
|
||||
.lighthouseci
|
||||
storybook-static
|
||||
.vercel
|
||||
|
@ -1,6 +1,5 @@
|
||||
.next
|
||||
.lighthouseci
|
||||
storybook-static
|
||||
coverage
|
||||
node_modules
|
||||
**/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 useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
||||
import { guildSchema } from 'models/Guild'
|
||||
import { FormState } from 'components/design/FormState'
|
||||
|
||||
import { HandleSubmitCallback, useForm } from '../../../hooks/useForm'
|
||||
import { guildSchema } from '../../../models/Guild'
|
||||
import { FormState } from '../../design/FormState'
|
||||
import { API_URL } from '../../../tools/api'
|
||||
import { useGuildMember } from '../../../contexts/GuildMember'
|
||||
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 axios from 'axios'
|
||||
|
||||
import { Emoji } from 'components/Emoji'
|
||||
import { ConfirmGuildJoin } from 'components/Application/ConfirmGuildJoin'
|
||||
import { API_URL } from 'tools/api'
|
||||
|
||||
import { Emoji } from '../../../Emoji'
|
||||
import { ConfirmGuildJoin } from '../../ConfirmGuildJoin'
|
||||
import { API_URL } from '../../../../tools/api'
|
||||
import {
|
||||
GuildPublic as GuildPublicType,
|
||||
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 React, { useState } from 'react'
|
||||
import classNames from 'classnames'
|
||||
import date from 'date-and-time'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
import { XIcon } from '@heroicons/react/solid'
|
||||
|
||||
import { API_URL } from '../../../tools/api'
|
||||
import { UserPublic } from '../../../models/User'
|
||||
import { UserProfileGuilds } from './UserProfileGuilds'
|
||||
import { UserProfileGuild } from './UserProfileGuilds/UserProfileGuild'
|
||||
import { Guild } from '../../../models/Guild'
|
||||
import { ConfirmGuildJoin } from '../ConfirmGuildJoin'
|
||||
|
||||
export interface UserProfileProps {
|
||||
className?: string
|
||||
@ -19,27 +13,12 @@ export interface UserProfileProps {
|
||||
}
|
||||
|
||||
export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
||||
const { user, guilds } = props
|
||||
const { user } = props
|
||||
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 (
|
||||
<div className='relative flex h-full flex-col items-center justify-center'>
|
||||
<div
|
||||
className={classNames('transition', {
|
||||
'select-none blur-3xl': showPopup
|
||||
})}
|
||||
>
|
||||
<div className='transition'>
|
||||
<div className='max-w-[1000px] px-12'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='flex w-max items-center'>
|
||||
@ -109,13 +88,6 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='py-8 px-4' onClick={handlePopupVisibility}>
|
||||
<UserProfileGuilds
|
||||
isPublicGuilds={user.settings.isPublicGuilds}
|
||||
guilds={guilds}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mt-7'>
|
||||
{user.biography != null && (
|
||||
@ -124,46 +96,6 @@ export const UserProfile: React.FC<UserProfileProps> = (props) => {
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
@ -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 { API_URL } from '../../../tools/api'
|
||||
import { UserProfileGuilds } from '../UserProfile/UserProfileGuilds'
|
||||
import { Input } from '../../design/Input'
|
||||
import { Checkbox } from '../../design/Checkbox'
|
||||
import { Textarea } from '../../design/Textarea'
|
||||
@ -20,11 +19,9 @@ import { FormState } from '../../design/FormState'
|
||||
import { useForm, HandleSubmitCallback } from '../../../hooks/useForm'
|
||||
import { userCurrentSchema, userSchema } from '../../../models/User'
|
||||
import { userSettingsSchema } from '../../../models/UserSettings'
|
||||
import { useGuilds } from '../../../contexts/Guilds'
|
||||
|
||||
export const UserSettings: React.FC = () => {
|
||||
const { user, setUser, authentication } = useAuthentication()
|
||||
const { guilds } = useGuilds()
|
||||
const { t } = useTranslation()
|
||||
const [inputValues, setInputValues] = useState({
|
||||
name: user.name,
|
||||
@ -212,20 +209,6 @@ export const UserSettings: React.FC = () => {
|
||||
/>
|
||||
</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 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'>
|
||||
|
@ -4,7 +4,6 @@ import useTranslation from 'next-translate/useTranslation'
|
||||
import { useTheme } from 'next-themes'
|
||||
import axios from 'axios'
|
||||
|
||||
import { SocialMediaButton } from '../design/SocialMediaButton'
|
||||
import { Main } from '../design/Main'
|
||||
import { Input } from '../design/Input'
|
||||
import { Button } from '../design/Button'
|
||||
@ -17,6 +16,7 @@ import {
|
||||
Authentication as AuthenticationClass
|
||||
} from '../../tools/authentication'
|
||||
import { useForm, HandleSubmitCallback } from '../../hooks/useForm'
|
||||
import { AuthenticationSocialMedia } from './AuthenticationSocialMedia'
|
||||
|
||||
export interface AuthenticationProps {
|
||||
mode: 'signup' | 'signin'
|
||||
@ -93,13 +93,7 @@ export const Authentication: React.FC<AuthenticationProps> = (props) => {
|
||||
|
||||
return (
|
||||
<Main>
|
||||
<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' />
|
||||
<SocialMediaButton socialMedia='GitHub' />
|
||||
<SocialMediaButton socialMedia='Discord' />
|
||||
</div>
|
||||
</div>
|
||||
<AuthenticationSocialMedia />
|
||||
<div className='pt-8 text-center font-paragraph text-lg'>
|
||||
{t('authentication:or')}
|
||||
</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 { useRouter } from 'next/router'
|
||||
|
||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { Channel, ChannelWithDefaultChannelId } from 'models/Channel'
|
||||
import { GuildsChannelsPath } from 'components/Application'
|
||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
||||
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||
import { useAuthentication } from '../tools/authentication'
|
||||
import { Channel, ChannelWithDefaultChannelId } from '../models/Channel'
|
||||
import { GuildsChannelsPath } from '../components/Application'
|
||||
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||
|
||||
export interface Channels {
|
||||
channels: Channel[]
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { GuildWithDefaultChannelId } from 'models/Guild'
|
||||
import { Member } from 'models/Member'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { SocketData } from 'tools/handleSocketData'
|
||||
import { GuildWithDefaultChannelId } from '../models/Guild'
|
||||
import { Member } from '../models/Member'
|
||||
import { useAuthentication } from '../tools/authentication'
|
||||
import { SocketData } from '../tools/handleSocketData'
|
||||
|
||||
export interface GuildMember {
|
||||
guild: GuildWithDefaultChannelId
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { createContext, useContext, useEffect } from 'react'
|
||||
|
||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { GuildWithDefaultChannelId } from 'models/Guild'
|
||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
||||
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||
import { useAuthentication } from '../tools/authentication'
|
||||
import { GuildWithDefaultChannelId } from '../models/Guild'
|
||||
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||
|
||||
export interface Guilds {
|
||||
guilds: GuildWithDefaultChannelId[]
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { createContext, useContext, useEffect } from 'react'
|
||||
|
||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { MemberWithPublicUser } from 'models/Member'
|
||||
import { GuildsChannelsPath } from 'components/Application'
|
||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
||||
import { User } from 'models/User'
|
||||
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||
import { useAuthentication } from '../tools/authentication'
|
||||
import { MemberWithPublicUser } from '../models/Member'
|
||||
import { GuildsChannelsPath } from '../components/Application'
|
||||
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||
import { User } from '../models/User'
|
||||
|
||||
export interface Members {
|
||||
members: MemberWithPublicUser[]
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { createContext, useContext, useEffect } from 'react'
|
||||
|
||||
import { NextPage, usePagination } from 'hooks/usePagination'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { MessageWithMember } from 'models/Message'
|
||||
import { GuildsChannelsPath } from 'components/Application'
|
||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
||||
import { NextPage, usePagination } from '../hooks/usePagination'
|
||||
import { useAuthentication } from '../tools/authentication'
|
||||
import { MessageWithMember } from '../models/Message'
|
||||
import { GuildsChannelsPath } from '../components/Application'
|
||||
import { handleSocketData, SocketData } from '../tools/handleSocketData'
|
||||
|
||||
export interface Messages {
|
||||
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 {
|
||||
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:e2e": "start-server-and-test \"start\" \"http://localhost:3000\" \"cypress run\"",
|
||||
"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",
|
||||
"deploy": "vercel",
|
||||
"postinstall": "husky install"
|
||||
@ -41,13 +38,13 @@
|
||||
"@sinclair/typebox": "0.23.4",
|
||||
"ajv": "8.10.0",
|
||||
"ajv-formats": "2.1.1",
|
||||
"axios": "0.26.0",
|
||||
"axios": "0.26.1",
|
||||
"classnames": "2.3.1",
|
||||
"date-and-time": "2.2.1",
|
||||
"date-and-time": "2.3.0",
|
||||
"emoji-mart": "3.0.1",
|
||||
"katex": "0.15.2",
|
||||
"katex": "0.15.3",
|
||||
"next": "12.1.0",
|
||||
"next-pwa": "5.4.5",
|
||||
"next-pwa": "5.4.6",
|
||||
"next-themes": "0.1.1",
|
||||
"next-translate": "1.3.5",
|
||||
"pretty-bytes": "6.0.0",
|
||||
@ -55,7 +52,7 @@
|
||||
"react-component-form": "2.0.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-infinite-scroll-component": "6.1.0",
|
||||
"react-markdown": "8.0.0",
|
||||
"react-markdown": "8.0.1",
|
||||
"react-responsive": "8.2.0",
|
||||
"react-swipeable": "6.2.0",
|
||||
"react-textarea-autosize": "8.3.3",
|
||||
@ -64,66 +61,56 @@
|
||||
"remark-breaks": "3.0.2",
|
||||
"remark-gfm": "3.0.1",
|
||||
"remark-math": "5.1.1",
|
||||
"sharp": "0.30.2",
|
||||
"sharp": "0.30.3",
|
||||
"socket.io-client": "4.4.1",
|
||||
"unified": "10.1.1",
|
||||
"unified": "10.1.2",
|
||||
"unist-util-visit": "4.1.0",
|
||||
"universal-cookie": "4.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "16.2.1",
|
||||
"@commitlint/cli": "16.2.3",
|
||||
"@commitlint/config-conventional": "16.2.1",
|
||||
"@lhci/cli": "0.9.0",
|
||||
"@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/react": "12.1.3",
|
||||
"@types/date-and-time": "0.13.0",
|
||||
"@testing-library/react": "12.1.4",
|
||||
"@types/emoji-mart": "3.0.9",
|
||||
"@types/hast": "2.3.4",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/katex": "0.11.1",
|
||||
"@types/node": "17.0.21",
|
||||
"@types/react": "17.0.39",
|
||||
"@types/react": "17.0.40",
|
||||
"@types/react-responsive": "8.0.5",
|
||||
"@types/unist": "2.0.6",
|
||||
"@typescript-eslint/eslint-plugin": "5.13.0",
|
||||
"@typescript-eslint/parser": "5.13.0",
|
||||
"autoprefixer": "10.4.2",
|
||||
"cypress": "9.5.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.15.0",
|
||||
"@typescript-eslint/parser": "5.15.0",
|
||||
"autoprefixer": "10.4.4",
|
||||
"cypress": "9.5.2",
|
||||
"editorconfig-checker": "4.0.2",
|
||||
"eslint": "8.10.0",
|
||||
"eslint-config-conventions": "1.1.0",
|
||||
"eslint": "8.11.0",
|
||||
"eslint-config-conventions": "1.1.1",
|
||||
"eslint-config-next": "12.1.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-prettier": "4.0.0",
|
||||
"eslint-plugin-promise": "6.0.0",
|
||||
"eslint-plugin-storybook": "0.5.7",
|
||||
"eslint-plugin-unicorn": "41.0.0",
|
||||
"html-w3c-validator": "1.1.0",
|
||||
"husky": "7.0.4",
|
||||
"jest": "27.5.1",
|
||||
"lint-staged": "12.3.5",
|
||||
"lint-staged": "12.3.6",
|
||||
"markdownlint-cli": "0.31.1",
|
||||
"mockttp": "2.6.0",
|
||||
"mockttp": "2.7.0",
|
||||
"next-secure-headers": "2.2.0",
|
||||
"plop": "3.0.5",
|
||||
"postcss": "8.4.7",
|
||||
"prettier": "2.5.1",
|
||||
"postcss": "8.4.12",
|
||||
"prettier": "2.6.0",
|
||||
"prettier-plugin-tailwindcss": "0.1.8",
|
||||
"semantic-release": "19.0.2",
|
||||
"serve": "13.0.2",
|
||||
"start-server-and-test": "1.14.0",
|
||||
"storybook-tailwind-dark-mode": "1.0.11",
|
||||
"tailwindcss": "3.0.23",
|
||||
"typescript": "4.6.2",
|
||||
"vercel": "24.0.0",
|
||||
"webpack": "5.70.0"
|
||||
"vercel": "24.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GetStaticProps, NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { ErrorPage } from 'components/ErrorPage'
|
||||
import { Head } from 'components/Head'
|
||||
import { Header } from 'components/Header'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { ErrorPage } from '../components/ErrorPage'
|
||||
import { Head } from '../components/Head'
|
||||
import { Header } from '../components/Header'
|
||||
import { Footer, FooterProps } from '../components/Footer'
|
||||
|
||||
const Error404: NextPage<FooterProps> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { GetStaticProps, NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { ErrorPage } from 'components/ErrorPage'
|
||||
import { Head } from 'components/Head'
|
||||
import { Header } from 'components/Header'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { ErrorPage } from '../components/ErrorPage'
|
||||
import { Head } from '../components/Head'
|
||||
import { Header } from '../components/Header'
|
||||
import { Footer, FooterProps } from '../components/Footer'
|
||||
|
||||
const Error500: NextPage<FooterProps> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -3,7 +3,7 @@ import { AppProps } from 'next/app'
|
||||
import { ThemeProvider } from 'next-themes'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import 'styles/global.css'
|
||||
import '../styles/global.css'
|
||||
|
||||
import '@fontsource/montserrat/400.css'
|
||||
import '@fontsource/montserrat/500.css'
|
||||
@ -13,7 +13,7 @@ import '@fontsource/montserrat/700.css'
|
||||
import '@fontsource/roboto/400.css'
|
||||
import '@fontsource/roboto/700.css'
|
||||
|
||||
import { cookies } from 'tools/cookies'
|
||||
import { cookies } from '../tools/cookies'
|
||||
|
||||
const Application = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||
const { lang } = useTranslation()
|
||||
|
@ -1,21 +1,24 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Messages } from 'components/Application/Messages'
|
||||
import { SendMessage } from 'components/Application/SendMessage'
|
||||
import { Head } from '../../../../components/Head'
|
||||
import { Application } from '../../../../components/Application'
|
||||
import { Messages } from '../../../../components/Application/Messages'
|
||||
import { SendMessage } from '../../../../components/Application/SendMessage'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
||||
import { GuildLeftSidebar } from 'components/Application/GuildLeftSidebar'
|
||||
import { ChannelsProvider } from 'contexts/Channels'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
import { Channel } from 'models/Channel'
|
||||
import { MessagesProvider } from 'contexts/Messages'
|
||||
import { MembersProviders } from 'contexts/Members'
|
||||
} from '../../../../tools/authentication'
|
||||
import {
|
||||
GuildMember,
|
||||
GuildMemberProvider
|
||||
} from '../../../../contexts/GuildMember'
|
||||
import { GuildLeftSidebar } from '../../../../components/Application/GuildLeftSidebar'
|
||||
import { ChannelsProvider } from '../../../../contexts/Channels'
|
||||
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 {
|
||||
channelId: number
|
||||
|
@ -1,19 +1,22 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../../components/Head'
|
||||
import { Application } from '../../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
||||
import { GuildLeftSidebar } from 'components/Application/GuildLeftSidebar'
|
||||
import { ChannelSettings } from 'components/Application/ChannelSettings'
|
||||
import { ChannelsProvider } from 'contexts/Channels'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
import { Channel } from 'models/Channel'
|
||||
import { MembersProviders } from 'contexts/Members'
|
||||
} from '../../../../tools/authentication'
|
||||
import {
|
||||
GuildMember,
|
||||
GuildMemberProvider
|
||||
} from '../../../../contexts/GuildMember'
|
||||
import { GuildLeftSidebar } from '../../../../components/Application/GuildLeftSidebar'
|
||||
import { ChannelSettings } from '../../../../components/Application/ChannelSettings'
|
||||
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 {
|
||||
channelId: number
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../../components/Head'
|
||||
import { Application } from '../../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { CreateChannel } from 'components/Application/CreateChannel'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
||||
} from '../../../../tools/authentication'
|
||||
import { CreateChannel } from '../../../../components/Application/CreateChannel'
|
||||
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||
import {
|
||||
GuildMember,
|
||||
GuildMemberProvider
|
||||
} from '../../../../contexts/GuildMember'
|
||||
|
||||
export interface CreateChannelPageProps extends PagePropsWithAuthentication {
|
||||
guildId: number
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../components/Head'
|
||||
import { Application } from '../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { GuildMember, GuildMemberProvider } from 'contexts/GuildMember'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
import { GuildSettings } from 'components/Application/GuildSettings'
|
||||
} from '../../../tools/authentication'
|
||||
import { GuildMember, GuildMemberProvider } from '../../../contexts/GuildMember'
|
||||
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||
import { GuildSettings } from '../../../components/Application/GuildSettings'
|
||||
|
||||
export interface GuildSettingsPageProps extends PagePropsWithAuthentication {
|
||||
guildId: number
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../components/Head'
|
||||
import { Application } from '../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { CreateGuild } from 'components/Application/CreateGuild'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
} from '../../../tools/authentication'
|
||||
import { CreateGuild } from '../../../components/Application/CreateGuild'
|
||||
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||
|
||||
const CreateGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../components/Head'
|
||||
import { Application } from '../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { JoinGuildsPublic } from 'components/Application/JoinGuildsPublic'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
} from '../../../tools/authentication'
|
||||
import { JoinGuildsPublic } from '../../../components/Application/JoinGuildsPublic'
|
||||
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||
|
||||
const JoinGuildPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { PopupGuild } from 'components/Application/PopupGuild'
|
||||
import { Head } from '../../components/Head'
|
||||
import { Application } from '../../components/Application'
|
||||
import { PopupGuild } from '../../components/Application/PopupGuild'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
} from '../../tools/authentication'
|
||||
import { GuildsProvider } from '../../contexts/Guilds'
|
||||
|
||||
const ApplicationPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||
return (
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../../components/Head'
|
||||
import { Application } from '../../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { UserProfile } from 'components/Application/UserProfile'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
import { UserPublic } from 'models/User'
|
||||
import { Guild } from 'models/Guild'
|
||||
} from '../../../../tools/authentication'
|
||||
import { UserProfile } from '../../../../components/Application/UserProfile'
|
||||
import { GuildsProvider } from '../../../../contexts/Guilds'
|
||||
import { UserPublic } from '../../../../models/User'
|
||||
import { Guild } from '../../../../models/Guild'
|
||||
|
||||
export interface UserProfilePageProps extends PagePropsWithAuthentication {
|
||||
user: UserPublic
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { NextPage } from 'next'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Application } from 'components/Application'
|
||||
import { Head } from '../../../components/Head'
|
||||
import { Application } from '../../../components/Application'
|
||||
import {
|
||||
authenticationFromServerSide,
|
||||
AuthenticationProvider,
|
||||
PagePropsWithAuthentication
|
||||
} from 'tools/authentication'
|
||||
import { UserSettings } from 'components/Application/UserSettings'
|
||||
import { GuildsProvider } from 'contexts/Guilds'
|
||||
} from '../../../tools/authentication'
|
||||
import { UserSettings } from '../../../components/Application/UserSettings'
|
||||
import { GuildsProvider } from '../../../contexts/Guilds'
|
||||
|
||||
const UserSettingsPage: NextPage<PagePropsWithAuthentication> = (props) => {
|
||||
return (
|
||||
|
@ -3,19 +3,19 @@ import Link from 'next/link'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
import axios from 'axios'
|
||||
|
||||
import { AuthenticationForm } from 'components/Authentication'
|
||||
import { Head } from 'components/Head'
|
||||
import { Header } from 'components/Header'
|
||||
import { Main } from 'components/design/Main'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { Input } from 'components/design/Input'
|
||||
import { Button } from 'components/design/Button'
|
||||
import { FormState } from 'components/design/FormState'
|
||||
import { authenticationFromServerSide } from 'tools/authentication'
|
||||
import { ScrollableBody } from 'components/ScrollableBody'
|
||||
import { userSchema } from 'models/User'
|
||||
import { api } from 'tools/api'
|
||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
||||
import { AuthenticationForm } from '../../components/Authentication'
|
||||
import { Head } from '../../components/Head'
|
||||
import { Header } from '../../components/Header'
|
||||
import { Main } from '../../components/design/Main'
|
||||
import { Footer, FooterProps } from '../../components/Footer'
|
||||
import { Input } from '../../components/design/Input'
|
||||
import { Button } from '../../components/design/Button'
|
||||
import { FormState } from '../../components/design/FormState'
|
||||
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||
import { userSchema } from '../../models/User'
|
||||
import { api } from '../../tools/api'
|
||||
import { HandleSubmitCallback, useForm } from '../../hooks/useForm'
|
||||
|
||||
const ForgotPassword: NextPage<FooterProps> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -3,19 +3,19 @@ import { useRouter } from 'next/router'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
import axios from 'axios'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Header } from 'components/Header'
|
||||
import { Main } from 'components/design/Main'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { Input } from 'components/design/Input'
|
||||
import { Button } from 'components/design/Button'
|
||||
import { FormState } from 'components/design/FormState'
|
||||
import { authenticationFromServerSide } from 'tools/authentication'
|
||||
import { AuthenticationForm } from 'components/Authentication'
|
||||
import { ScrollableBody } from 'components/ScrollableBody/ScrollableBody'
|
||||
import { HandleSubmitCallback, useForm } from 'hooks/useForm'
|
||||
import { api } from 'tools/api'
|
||||
import { userSchema } from 'models/User'
|
||||
import { Head } from '../../components/Head'
|
||||
import { Header } from '../../components/Header'
|
||||
import { FormState } from '../../components/design/FormState'
|
||||
import { Main } from '../../components/design/Main'
|
||||
import { Footer, FooterProps } from '../../components/Footer'
|
||||
import { Input } from '../../components/design/Input'
|
||||
import { Button } from '../../components/design/Button'
|
||||
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||
import { AuthenticationForm } from '../../components/Authentication'
|
||||
import { ScrollableBody } from '../../components/ScrollableBody/ScrollableBody'
|
||||
import { HandleSubmitCallback, useForm } from '../../hooks/useForm'
|
||||
import { api } from '../../tools/api'
|
||||
import { userSchema } from '../../models/User'
|
||||
|
||||
const ResetPassword: NextPage<FooterProps> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Authentication } from 'components/Authentication'
|
||||
import { Header } from 'components/Header'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { authenticationFromServerSide } from 'tools/authentication'
|
||||
import { ScrollableBody } from 'components/ScrollableBody'
|
||||
import { Head } from '../../components/Head'
|
||||
import { Authentication } from '../../components/Authentication'
|
||||
import { Header } from '../../components/Header'
|
||||
import { Footer, FooterProps } from '../../components/Footer'
|
||||
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||
|
||||
const Signin: NextPage<FooterProps> = (props) => {
|
||||
const { version } = props
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { NextPage } from 'next'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Authentication } from 'components/Authentication'
|
||||
import { Header } from 'components/Header'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { authenticationFromServerSide } from 'tools/authentication'
|
||||
import { ScrollableBody } from 'components/ScrollableBody'
|
||||
import { Head } from '../../components/Head'
|
||||
import { Authentication } from '../../components/Authentication'
|
||||
import { Header } from '../../components/Header'
|
||||
import { Footer, FooterProps } from '../../components/Footer'
|
||||
import { authenticationFromServerSide } from '../../tools/authentication'
|
||||
import { ScrollableBody } from '../../components/ScrollableBody'
|
||||
|
||||
const Signup: NextPage<FooterProps> = (props) => {
|
||||
const { version } = props
|
||||
|
@ -4,13 +4,13 @@ import Image from 'next/image'
|
||||
import Translation from 'next-translate/Trans'
|
||||
import useTranslation from 'next-translate/useTranslation'
|
||||
|
||||
import { Head } from 'components/Head'
|
||||
import { Header } from 'components/Header'
|
||||
import { Main } from 'components/design/Main'
|
||||
import { Footer, FooterProps } from 'components/Footer'
|
||||
import { SocialMediaLink } from 'components/design/SocialMediaButton'
|
||||
import { ButtonLink } from 'components/design/Button'
|
||||
import { ScrollableBody } from 'components/ScrollableBody'
|
||||
import { Head } from '../components/Head'
|
||||
import { Header } from '../components/Header'
|
||||
import { Main } from '../components/design/Main'
|
||||
import { Footer, FooterProps } from '../components/Footer'
|
||||
import { SocialMediaLink } from '../components/design/SocialMediaButton'
|
||||
import { ButtonLink } from '../components/design/Button'
|
||||
import { ScrollableBody } from '../components/ScrollableBody'
|
||||
|
||||
const Home: NextPage<FooterProps> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -6,16 +6,11 @@
|
||||
@apply flex h-screen flex-col;
|
||||
}
|
||||
|
||||
body,
|
||||
#preview-storybook {
|
||||
body {
|
||||
@apply bg-white font-headline text-black dark:bg-black dark:text-white;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#preview-storybook {
|
||||
@apply min-h-screen p-6;
|
||||
}
|
||||
|
||||
.h-full-without-header {
|
||||
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 './authenticationFromServerSide'
|
||||
export * from './AuthenticationContext'
|
||||
|
@ -11,7 +11,6 @@
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"types": ["jest", "@testing-library/jest-dom", "@testing-library/react"],
|
||||
"baseUrl": ".",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
|
Reference in New Issue
Block a user