feat: add OAuth2 authentication (#16)
This commit is contained in:
		| @@ -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' } | ||||
							
								
								
									
										36605
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36605
									
								
								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