feat: add OAuth2 authentication (#16)
This commit is contained in:
@ -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'>
|
||||
|
Reference in New Issue
Block a user