feat: add guilds list in left sidebar
This commit is contained in:
		| @@ -1,6 +1,7 @@ | |||||||
| import { Meta, Story } from '@storybook/react' | import { Meta, Story } from '@storybook/react' | ||||||
| 
 | 
 | ||||||
| import { Guild as Component, GuildProps } from './Guild' | import { Guild as Component, GuildProps } from './Guild' | ||||||
|  | import { guildExample } from '../../../../cypress/fixtures/guilds/guild' | ||||||
| 
 | 
 | ||||||
| const Stories: Meta = { | const Stories: Meta = { | ||||||
|   title: 'Guild', |   title: 'Guild', | ||||||
| @@ -14,12 +15,7 @@ export const Guild: Story<GuildProps> = (arguments_) => { | |||||||
| } | } | ||||||
| Guild.args = { | Guild.args = { | ||||||
|   guild: { |   guild: { | ||||||
|     id: 1, |     ...guildExample, | ||||||
|     name: 'GuildExample', |     defaultChannelId: 1 | ||||||
|     description: 'guild example.', |  | ||||||
|     icon: null, |  | ||||||
|     createdAt: new Date().toISOString(), |  | ||||||
|     updatedAt: new Date().toISOString(), |  | ||||||
|     membersCount: 1 |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -1,19 +1,15 @@ | |||||||
| import { render } from '@testing-library/react' | import { render } from '@testing-library/react' | ||||||
| 
 | 
 | ||||||
| import { Guild } from './Guild' | import { Guild } from './Guild' | ||||||
|  | import { guildExample } from '../../../../cypress/fixtures/guilds/guild' | ||||||
| 
 | 
 | ||||||
| describe('<Guild />', () => { | describe('<Guild />', () => { | ||||||
|   it('should render successfully', () => { |   it('should render successfully', () => { | ||||||
|     const { baseElement } = render( |     const { baseElement } = render( | ||||||
|       <Guild |       <Guild | ||||||
|         guild={{ |         guild={{ | ||||||
|           id: 1, |           ...guildExample, | ||||||
|           name: 'GuildExample', |           defaultChannelId: 1 | ||||||
|           description: 'guild example.', |  | ||||||
|           icon: null, |  | ||||||
|           createdAt: new Date().toISOString(), |  | ||||||
|           updatedAt: new Date().toISOString(), |  | ||||||
|           membersCount: 1 |  | ||||||
|         }} |         }} | ||||||
|       /> |       /> | ||||||
|     ) |     ) | ||||||
							
								
								
									
										34
									
								
								components/Application/Guilds/Guild/Guild.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								components/Application/Guilds/Guild/Guild.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | import Image from 'next/image' | ||||||
|  |  | ||||||
|  | import { GuildWithDefaultChannelId } from '../../../../models/Guild' | ||||||
|  | import { IconLink } from '../../../design/IconLink' | ||||||
|  |  | ||||||
|  | export interface GuildProps { | ||||||
|  |   guild: GuildWithDefaultChannelId | ||||||
|  |   selected?: boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const Guild: React.FC<GuildProps> = (props) => { | ||||||
|  |   const { guild, selected } = props | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <IconLink | ||||||
|  |       key={guild.id} | ||||||
|  |       href={`/application/${guild.id}/${guild.defaultChannelId}`} | ||||||
|  |       selected={selected} | ||||||
|  |       title={guild.name} | ||||||
|  |     > | ||||||
|  |       <div className='pl-[6px]'> | ||||||
|  |         <Image | ||||||
|  |           className='rounded-full' | ||||||
|  |           src={ | ||||||
|  |             guild.icon != null ? guild.icon : '/images/data/guild-default.png' | ||||||
|  |           } | ||||||
|  |           alt='logo' | ||||||
|  |           width={48} | ||||||
|  |           height={48} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|  |     </IconLink> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| import { Meta, Story } from '@storybook/react' |  | ||||||
|  |  | ||||||
| import { Guilds as Component, GuildsProps } from './' |  | ||||||
|  |  | ||||||
| const Stories: Meta = { |  | ||||||
|   title: 'Guilds', |  | ||||||
|   component: Component |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export default Stories |  | ||||||
|  |  | ||||||
| export const Guilds: Story<GuildsProps> = (arguments_) => ( |  | ||||||
|   <Component {...arguments_} /> |  | ||||||
| ) |  | ||||||
| Guilds.args = { path: { channelId: 1, guildId: 2 } } |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| import { render } from '@testing-library/react' |  | ||||||
|  |  | ||||||
| import { Guilds } from './' |  | ||||||
|  |  | ||||||
| describe('<Guilds />', () => { |  | ||||||
|   it('should render successfully', () => { |  | ||||||
|     const { baseElement } = render( |  | ||||||
|       <Guilds path={{ channelId: 1, guildId: 2 }} /> |  | ||||||
|     ) |  | ||||||
|     expect(baseElement).toBeTruthy() |  | ||||||
|   }) |  | ||||||
| }) |  | ||||||
| @@ -1,34 +1,72 @@ | |||||||
| import Image from 'next/image' | import { useCallback, useEffect, useState, useRef } from 'react' | ||||||
|  | import InfiniteScroll from 'react-infinite-scroll-component' | ||||||
|  |  | ||||||
|  | import { useAuthentication } from 'utils/authentication' | ||||||
|  | import { GuildWithDefaultChannelId } from 'models/Guild' | ||||||
|  | import { Loader } from 'components/design/Loader' | ||||||
|  | import { useFetchState } from 'hooks/useFetchState' | ||||||
| import { ApplicationProps } from '../Application' | import { ApplicationProps } from '../Application' | ||||||
| import { IconLink } from '../../design/IconLink' | import { Guild } from './Guild' | ||||||
|  |  | ||||||
| export interface GuildsProps extends ApplicationProps {} | export interface GuildsProps extends ApplicationProps {} | ||||||
|  |  | ||||||
| export const Guilds: React.FC<GuildsProps> = (props) => { | export const Guilds: React.FC<GuildsProps> = (props) => { | ||||||
|   const { path } = props |   const { path } = props | ||||||
|  |  | ||||||
|  |   const [guilds, setGuilds] = useState<GuildWithDefaultChannelId[]>([]) | ||||||
|  |   const [hasMore, setHasMore] = useState(true) | ||||||
|  |   const [fetchState, setFetchState] = useFetchState('idle') | ||||||
|  |   const afterId = useRef<number | null>(null) | ||||||
|  |  | ||||||
|  |   const { authentication } = useAuthentication() | ||||||
|  |  | ||||||
|  |   const fetchGuilds = useCallback(async (): Promise<void> => { | ||||||
|  |     if (fetchState !== 'idle') { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     setFetchState('loading') | ||||||
|  |     const { data } = await authentication.api.get<GuildWithDefaultChannelId[]>( | ||||||
|  |       `/guilds?limit=20${ | ||||||
|  |         afterId.current != null ? `&after=${afterId.current}` : '' | ||||||
|  |       }` | ||||||
|  |     ) | ||||||
|  |     afterId.current = data.length > 0 ? data[data.length - 1].id : null | ||||||
|  |     setGuilds((oldGuilds) => { | ||||||
|  |       return [...oldGuilds, ...data] | ||||||
|  |     }) | ||||||
|  |     setHasMore(data.length > 0) | ||||||
|  |     setFetchState('idle') | ||||||
|  |   }, [authentication, fetchState, setFetchState]) | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     fetchGuilds().catch((error) => { | ||||||
|  |       console.error(error) | ||||||
|  |     }) | ||||||
|  |   }, []) // eslint-disable-line react-hooks/exhaustive-deps | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <div className='min-w-[92px] mt-[130px] pt-2 h-full border-r-2 border-gray-500 dark:border-white/20 space-y-2 scrollbar-firefox-support overflow-y-auto'> |     <div | ||||||
|       {new Array(100).fill(null).map((_, index) => { |       id='guilds-list-members' | ||||||
|         return ( |       className='min-w-[92px] mt-[130px] pt-2 h-full border-r-2 border-gray-500 dark:border-white/20 space-y-2 scrollbar-firefox-support overflow-y-auto' | ||||||
|           <IconLink |     > | ||||||
|             key={index} |       <InfiniteScroll | ||||||
|             href={`/application/${index}/0`} |         className='guilds-list' | ||||||
|             selected={typeof path !== 'string' && path.guildId === index} |         dataLength={guilds.length} | ||||||
|             title='Guild Name' |         next={fetchGuilds} | ||||||
|           > |         hasMore={hasMore} | ||||||
|             <div className='pl-[6px]'> |         scrollableTarget='guilds-list-members' | ||||||
|               <Image |         loader={<Loader />} | ||||||
|                 src='/images/icons/Thream.png' |       > | ||||||
|                 alt='logo' |         {guilds.map((guild) => { | ||||||
|                 width={48} |           return ( | ||||||
|                 height={48} |             <Guild | ||||||
|               /> |               guild={guild} | ||||||
|             </div> |               key={guild.id} | ||||||
|           </IconLink> |               selected={typeof path !== 'string' && path.guildId === guild.id} | ||||||
|         ) |             /> | ||||||
|       })} |           ) | ||||||
|  |         })} | ||||||
|  |       </InfiniteScroll> | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | import { Meta, Story } from '@storybook/react' | ||||||
|  |  | ||||||
|  | import { GuildPublic as Component, GuildPublicProps } from './GuildPublic' | ||||||
|  | import { guildExample } from '../../../../cypress/fixtures/guilds/guild' | ||||||
|  |  | ||||||
|  | const Stories: Meta = { | ||||||
|  |   title: 'GuildPublic', | ||||||
|  |   component: Component | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default Stories | ||||||
|  |  | ||||||
|  | export const GuildPublic: Story<GuildPublicProps> = (arguments_) => { | ||||||
|  |   return <Component {...arguments_} /> | ||||||
|  | } | ||||||
|  | GuildPublic.args = { | ||||||
|  |   guild: { | ||||||
|  |     ...guildExample, | ||||||
|  |     membersCount: 1 | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | import { render } from '@testing-library/react' | ||||||
|  |  | ||||||
|  | import { GuildPublic } from './GuildPublic' | ||||||
|  | import { guildExample } from '../../../../cypress/fixtures/guilds/guild' | ||||||
|  |  | ||||||
|  | describe('<GuildPublic />', () => { | ||||||
|  |   it('should render successfully', () => { | ||||||
|  |     const { baseElement } = render( | ||||||
|  |       <GuildPublic | ||||||
|  |         guild={{ | ||||||
|  |           ...guildExample, | ||||||
|  |           membersCount: 1 | ||||||
|  |         }} | ||||||
|  |       /> | ||||||
|  |     ) | ||||||
|  |     expect(baseElement).toBeTruthy() | ||||||
|  |   }) | ||||||
|  | }) | ||||||
| @@ -1,12 +1,12 @@ | |||||||
| import Image from 'next/image' | import Image from 'next/image' | ||||||
| 
 | 
 | ||||||
| import { GuildPublic } from 'models/Guild' | import { GuildPublic as GuildPublicType } from 'models/Guild' | ||||||
| 
 | 
 | ||||||
| export interface GuildProps { | export interface GuildPublicProps { | ||||||
|   guild: GuildPublic |   guild: GuildPublicType | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const Guild: React.FC<GuildProps> = (props) => { | export const GuildPublic: React.FC<GuildPublicProps> = (props) => { | ||||||
|   const { guild } = props |   const { guild } = props | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
| @@ -0,0 +1 @@ | |||||||
|  | export * from './GuildPublic' | ||||||
| @@ -2,13 +2,13 @@ import { useCallback, useEffect, useState, useRef } from 'react' | |||||||
| import InfiniteScroll from 'react-infinite-scroll-component' | import InfiniteScroll from 'react-infinite-scroll-component' | ||||||
|  |  | ||||||
| import { useAuthentication } from 'utils/authentication' | import { useAuthentication } from 'utils/authentication' | ||||||
| import { GuildPublic } from 'models/Guild' | import { GuildPublic as GuildPublicType } from 'models/Guild' | ||||||
| import { Loader } from 'components/design/Loader' | import { Loader } from 'components/design/Loader' | ||||||
| import { useFetchState } from 'hooks/useFetchState' | import { useFetchState } from 'hooks/useFetchState' | ||||||
| import { Guild } from './Guild' | import { GuildPublic } from './GuildPublic' | ||||||
|  |  | ||||||
| export const JoinGuildsPublic: React.FC = () => { | export const JoinGuildsPublic: React.FC = () => { | ||||||
|   const [guilds, setGuilds] = useState<GuildPublic[]>([]) |   const [guilds, setGuilds] = useState<GuildPublicType[]>([]) | ||||||
|   const [hasMore, setHasMore] = useState(true) |   const [hasMore, setHasMore] = useState(true) | ||||||
|   const [inputSearch, setInputSearch] = useState('') |   const [inputSearch, setInputSearch] = useState('') | ||||||
|   const [fetchState, setFetchState] = useFetchState('idle') |   const [fetchState, setFetchState] = useFetchState('idle') | ||||||
| @@ -21,7 +21,7 @@ export const JoinGuildsPublic: React.FC = () => { | |||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     setFetchState('loading') |     setFetchState('loading') | ||||||
|     const { data } = await authentication.api.get<GuildPublic[]>( |     const { data } = await authentication.api.get<GuildPublicType[]>( | ||||||
|       `/guilds/public?limit=20&search=${inputSearch}${ |       `/guilds/public?limit=20&search=${inputSearch}${ | ||||||
|         afterId.current != null ? `&after=${afterId.current}` : '' |         afterId.current != null ? `&after=${afterId.current}` : '' | ||||||
|       }` |       }` | ||||||
| @@ -58,7 +58,7 @@ export const JoinGuildsPublic: React.FC = () => { | |||||||
|       /> |       /> | ||||||
|       <div className='w-full flex items-center justify-center p-12'> |       <div className='w-full flex items-center justify-center p-12'> | ||||||
|         <InfiniteScroll |         <InfiniteScroll | ||||||
|           className='guilds-list max-w-[1600px] grid grid-cols-1 xl:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-8 !overflow-hidden' |           className='guilds-public-list max-w-[1600px] grid grid-cols-1 xl:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-8 !overflow-hidden' | ||||||
|           dataLength={guilds.length} |           dataLength={guilds.length} | ||||||
|           next={fetchGuilds} |           next={fetchGuilds} | ||||||
|           scrollableTarget='application-page-content' |           scrollableTarget='application-page-content' | ||||||
| @@ -66,7 +66,7 @@ export const JoinGuildsPublic: React.FC = () => { | |||||||
|           loader={<Loader />} |           loader={<Loader />} | ||||||
|         > |         > | ||||||
|           {guilds.map((guild) => { |           {guilds.map((guild) => { | ||||||
|             return <Guild guild={guild} key={guild.id} /> |             return <GuildPublic guild={guild} key={guild.id} /> | ||||||
|           })} |           })} | ||||||
|         </InfiniteScroll> |         </InfiniteScroll> | ||||||
|       </div> |       </div> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ export const Members: React.FC = () => { | |||||||
|       <div className='flex items-center cursor-pointer py-2 px-4 pr-10 rounded hover:bg-gray-300 dark:hover:bg-gray-900'> |       <div className='flex items-center cursor-pointer py-2 px-4 pr-10 rounded hover:bg-gray-300 dark:hover:bg-gray-900'> | ||||||
|         <div className='min-w-[50px] flex rounded-full border-2 border-green-500'> |         <div className='min-w-[50px] flex rounded-full border-2 border-green-500'> | ||||||
|           <Image |           <Image | ||||||
|             src='/images/data/divlo.png' |             src='/images/data/user-default.png' | ||||||
|             alt={"Users's profil picture"} |             alt={"Users's profil picture"} | ||||||
|             height={50} |             height={50} | ||||||
|             width={50} |             width={50} | ||||||
| @@ -35,7 +35,7 @@ export const Members: React.FC = () => { | |||||||
|           > |           > | ||||||
|             <div className='min-w-[50px] flex rounded-full border-2 border-transparent drop-shadow-md'> |             <div className='min-w-[50px] flex rounded-full border-2 border-transparent drop-shadow-md'> | ||||||
|               <Image |               <Image | ||||||
|                 src='/images/data/divlo.png' |                 src='/images/data/user-default.png' | ||||||
|                 alt={"Users's profil picture"} |                 alt={"Users's profil picture"} | ||||||
|                 height={50} |                 height={50} | ||||||
|                 width={50} |                 width={50} | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ export const Messages: React.FC = () => { | |||||||
|                 <div className='w-10 h-10 drop-shadow-md'> |                 <div className='w-10 h-10 drop-shadow-md'> | ||||||
|                   <Image |                   <Image | ||||||
|                     className='rounded-full' |                     className='rounded-full' | ||||||
|                     src='/images/data/divlo.png' |                     src='/images/data/user-default.png' | ||||||
|                     alt='logo' |                     alt='logo' | ||||||
|                     width={50} |                     width={50} | ||||||
|                     height={50} |                     height={50} | ||||||
|   | |||||||
| @@ -1,5 +1,8 @@ | |||||||
| import { Meta, Story } from '@storybook/react' | import { Meta, Story } from '@storybook/react' | ||||||
| import { user, userSettings } from '../../../cypress/fixtures/users/user' | import { | ||||||
|  |   userExample, | ||||||
|  |   userSettingsExample | ||||||
|  | } from '../../../cypress/fixtures/users/user' | ||||||
|  |  | ||||||
| import { UserProfile as Component, UserProfileProps } from './UserProfile' | import { UserProfile as Component, UserProfileProps } from './UserProfile' | ||||||
|  |  | ||||||
| @@ -15,7 +18,7 @@ export const UserProfile: Story<UserProfileProps> = (arguments_) => { | |||||||
| } | } | ||||||
| UserProfile.args = { | UserProfile.args = { | ||||||
|   user: { |   user: { | ||||||
|     ...user, |     ...userExample, | ||||||
|     settings: userSettings |     settings: userSettingsExample | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import { guild } from '../guilds/guild' | import { guildExample } from '../guilds/guild' | ||||||
|  |  | ||||||
| export const channel = { | export const channelExample = { | ||||||
|   id: 1, |   id: 1, | ||||||
|   name: 'general', |   name: 'general', | ||||||
|   guildId: guild.id, |   guildId: guildExample.id, | ||||||
|   createdAt: new Date().toISOString(), |   createdAt: new Date().toISOString(), | ||||||
|   updatedAt: new Date().toISOString() |   updatedAt: new Date().toISOString() | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								cypress/fixtures/guilds/get.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								cypress/fixtures/guilds/get.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | import { Handler } from '../handler' | ||||||
|  |  | ||||||
|  | import { guildExample, guildExample2 } from './guild' | ||||||
|  |  | ||||||
|  | export const getGuildsHandler: Handler = { | ||||||
|  |   method: 'GET', | ||||||
|  |   url: '/guilds', | ||||||
|  |   response: { | ||||||
|  |     statusCode: 200, | ||||||
|  |     body: [ | ||||||
|  |       { ...guildExample, defaultChannelId: 1 }, | ||||||
|  |       { ...guildExample2, defaultChannelId: 2 } | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,4 +1,6 @@ | |||||||
| export const guild = { | import { Guild } from '../../../models/Guild' | ||||||
|  |  | ||||||
|  | export const guildExample: Guild = { | ||||||
|   id: 1, |   id: 1, | ||||||
|   name: 'GuildExample', |   name: 'GuildExample', | ||||||
|   description: 'guild example.', |   description: 'guild example.', | ||||||
| @@ -7,7 +9,8 @@ export const guild = { | |||||||
|   updatedAt: new Date().toISOString() |   updatedAt: new Date().toISOString() | ||||||
| } | } | ||||||
|  |  | ||||||
| export const guild2 = { | export const guildExample2: Guild = { | ||||||
|   ...guild, |   ...guildExample, | ||||||
|  |   id: 2, | ||||||
|   name: 'app' |   name: 'app' | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import { Handler } from '../handler' | import { Handler } from '../handler' | ||||||
|  |  | ||||||
| import { guild } from './guild' | import { guildExample } from './guild' | ||||||
| import { channel } from '../channels/channel' | import { channelExample } from '../channels/channel' | ||||||
| import { memberComplete } from '../members/member' | import { memberExampleComplete } from '../members/member' | ||||||
|  |  | ||||||
| export const postGuildsHandler: Handler = { | export const postGuildsHandler: Handler = { | ||||||
|   method: 'POST', |   method: 'POST', | ||||||
| @@ -11,9 +11,9 @@ export const postGuildsHandler: Handler = { | |||||||
|     statusCode: 201, |     statusCode: 201, | ||||||
|     body: { |     body: { | ||||||
|       guild: { |       guild: { | ||||||
|         ...guild, |         ...guildExample, | ||||||
|         channels: [channel], |         channels: [channelExample], | ||||||
|         members: [memberComplete] |         members: [memberExampleComplete] | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Handler } from '../../handler' | import { Handler } from '../../handler' | ||||||
|  |  | ||||||
| import { guild, guild2 } from '../guild' | import { guildExample, guildExample2 } from '../guild' | ||||||
|  |  | ||||||
| export const getGuildsPublicEmptyHandler: Handler = { | export const getGuildsPublicEmptyHandler: Handler = { | ||||||
|   method: 'GET', |   method: 'GET', | ||||||
| @@ -17,8 +17,8 @@ export const getGuildsPublicHandler: Handler = { | |||||||
|   response: { |   response: { | ||||||
|     statusCode: 200, |     statusCode: 200, | ||||||
|     body: [ |     body: [ | ||||||
|       { ...guild, membersCount: 1 }, |       { ...guildExample, membersCount: 1 }, | ||||||
|       { ...guild2, membersCount: 1 } |       { ...guildExample2, membersCount: 1 } | ||||||
|     ] |     ] | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -28,6 +28,6 @@ export const getGuildsPublicSearchHandler: Handler = { | |||||||
|   url: '/guilds/public', |   url: '/guilds/public', | ||||||
|   response: { |   response: { | ||||||
|     statusCode: 200, |     statusCode: 200, | ||||||
|     body: [{ ...guild2, membersCount: 1 }] |     body: [{ ...guildExample2, membersCount: 1 }] | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,16 +1,16 @@ | |||||||
| import { guild } from '../guilds/guild' | import { guildExample } from '../guilds/guild' | ||||||
| import { user } from '../users/user' | import { userExample } from '../users/user' | ||||||
|  |  | ||||||
| export const member = { | export const memberExample = { | ||||||
|   id: 1, |   id: 1, | ||||||
|   isOwner: true, |   isOwner: true, | ||||||
|   userId: user.id, |   userId: userExample.id, | ||||||
|   guildId: guild.id, |   guildId: guildExample.id, | ||||||
|   createdAt: new Date().toISOString(), |   createdAt: new Date().toISOString(), | ||||||
|   updatedAt: new Date().toISOString() |   updatedAt: new Date().toISOString() | ||||||
| } | } | ||||||
|  |  | ||||||
| export const memberComplete = { | export const memberExampleComplete = { | ||||||
|   ...member, |   ...memberExample, | ||||||
|   user |   user: userExample | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Handler } from '../../handler' | import { Handler } from '../../handler' | ||||||
|  |  | ||||||
| import { user, userSettings } from '../user' | import { userExample, userSettingsExample } from '../user' | ||||||
|  |  | ||||||
| export const getUsersCurrentHandler: Handler = { | export const getUsersCurrentHandler: Handler = { | ||||||
|   method: 'GET', |   method: 'GET', | ||||||
| @@ -9,8 +9,8 @@ export const getUsersCurrentHandler: Handler = { | |||||||
|     statusCode: 200, |     statusCode: 200, | ||||||
|     body: { |     body: { | ||||||
|       user: { |       user: { | ||||||
|         ...user, |         ...userExample, | ||||||
|         settings: userSettings, |         settings: userSettingsExample, | ||||||
|         currentStrategy: 'local', |         currentStrategy: 'local', | ||||||
|         strategies: ['local'] |         strategies: ['local'] | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Handler } from '../../handler' | import { Handler } from '../../handler' | ||||||
|  |  | ||||||
| import { user, userSettings } from '../user' | import { userExample, userSettingsExample } from '../user' | ||||||
|  |  | ||||||
| export const postUsersSignupHandler: Handler = { | export const postUsersSignupHandler: Handler = { | ||||||
|   method: 'POST', |   method: 'POST', | ||||||
| @@ -9,8 +9,8 @@ export const postUsersSignupHandler: Handler = { | |||||||
|     statusCode: 201, |     statusCode: 201, | ||||||
|     body: { |     body: { | ||||||
|       user: { |       user: { | ||||||
|         ...user, |         ...userExample, | ||||||
|         settings: userSettings |         settings: userSettingsExample | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { UserSettings } from '../../../models/UserSettings' | import { UserSettings } from '../../../models/UserSettings' | ||||||
| import { User } from '../../../models/User' | import { User } from '../../../models/User' | ||||||
|  |  | ||||||
| export const user: User = { | export const userExample: User = { | ||||||
|   id: 1, |   id: 1, | ||||||
|   name: 'Divlo', |   name: 'Divlo', | ||||||
|   email: 'contact@divlo.fr', |   email: 'contact@divlo.fr', | ||||||
| @@ -17,7 +17,7 @@ export const user: User = { | |||||||
|   updatedAt: '2021-10-20T20:59:08.485Z' |   updatedAt: '2021-10-20T20:59:08.485Z' | ||||||
| } | } | ||||||
|  |  | ||||||
| export const userSettings: UserSettings = { | export const userSettingsExample: UserSettings = { | ||||||
|   id: 1, |   id: 1, | ||||||
|   language: 'en', |   language: 'en', | ||||||
|   theme: 'dark', |   theme: 'dark', | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { channel } from '../../../../fixtures/channels/channel' | import { channelExample } from '../../../../fixtures/channels/channel' | ||||||
| import { guild } from '../../../../fixtures/guilds/guild' | import { guildExample } from '../../../../fixtures/guilds/guild' | ||||||
| import { postGuildsHandler } from '../../../../fixtures/guilds/post' | import { postGuildsHandler } from '../../../../fixtures/guilds/post' | ||||||
| import { authenticationHandlers } from '../../../../fixtures/handler' | import { authenticationHandlers } from '../../../../fixtures/handler' | ||||||
|  |  | ||||||
| @@ -15,11 +15,11 @@ describe('Pages > /application/guilds/create', () => { | |||||||
|     ]).setCookie('refreshToken', 'refresh-token') |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|     cy.visit('/application/guilds/create') |     cy.visit('/application/guilds/create') | ||||||
|     cy.get('#error-name').should('not.exist') |     cy.get('#error-name').should('not.exist') | ||||||
|     cy.get('[data-cy=input-name]').type(guild.name) |     cy.get('[data-cy=input-name]').type(guildExample.name) | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.location('pathname').should( |     cy.location('pathname').should( | ||||||
|       'eq', |       'eq', | ||||||
|       `/application/${guild.id}/${channel.id}` |       `/application/${guildExample.id}/${channelExample.id}` | ||||||
|     ) |     ) | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
| @@ -30,7 +30,7 @@ describe('Pages > /application/guilds/create', () => { | |||||||
|     ) |     ) | ||||||
|     cy.visit('/application/guilds/create') |     cy.visit('/application/guilds/create') | ||||||
|     cy.get('#error-name').should('not.exist') |     cy.get('#error-name').should('not.exist') | ||||||
|     cy.get('[data-cy=input-name]').type(guild.name) |     cy.get('[data-cy=input-name]').type(guildExample.name) | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should('have.text', 'Error: Internal Server Error.') |     cy.get('#message').should('have.text', 'Error: Internal Server Error.') | ||||||
|   }) |   }) | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ describe('Pages > /application/guilds/join', () => { | |||||||
|       getGuildsPublicEmptyHandler |       getGuildsPublicEmptyHandler | ||||||
|     ]).setCookie('refreshToken', 'refresh-token') |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|     cy.visit('/application/guilds/join') |     cy.visit('/application/guilds/join') | ||||||
|     cy.get('.guilds-list').children().should('have.length', 0) |     cy.get('.guilds-public-list').children().should('have.length', 0) | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
|   it('should shows loader with internal api server error', () => { |   it('should shows loader with internal api server error', () => { | ||||||
| @@ -25,7 +25,7 @@ describe('Pages > /application/guilds/join', () => { | |||||||
|       'refresh-token' |       'refresh-token' | ||||||
|     ) |     ) | ||||||
|     cy.visit('/application/guilds/join') |     cy.visit('/application/guilds/join') | ||||||
|     cy.get('.guilds-list').children().should('have.length', 1) |     cy.get('.guilds-public-list').children().should('have.length', 1) | ||||||
|     cy.get('[data-testid=progress-spinner]').should('be.visible') |     cy.get('[data-testid=progress-spinner]').should('be.visible') | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
| @@ -35,8 +35,8 @@ describe('Pages > /application/guilds/join', () => { | |||||||
|       getGuildsPublicHandler |       getGuildsPublicHandler | ||||||
|     ]).setCookie('refreshToken', 'refresh-token') |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|     cy.visit('/application/guilds/join') |     cy.visit('/application/guilds/join') | ||||||
|     cy.get('.guilds-list').children().should('have.length', 2) |     cy.get('.guilds-public-list').children().should('have.length', 2) | ||||||
|     cy.get('.guilds-list [data-cy=guild-name]:first').should( |     cy.get('.guilds-public-list [data-cy=guild-name]:first').should( | ||||||
|       'have.text', |       'have.text', | ||||||
|       'GuildExample' |       'GuildExample' | ||||||
|     ) |     ) | ||||||
| @@ -49,7 +49,10 @@ describe('Pages > /application/guilds/join', () => { | |||||||
|     ]).setCookie('refreshToken', 'refresh-token') |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|     cy.visit('/application/guilds/join') |     cy.visit('/application/guilds/join') | ||||||
|     cy.get('[data-cy=search-guild-input]').type('app') |     cy.get('[data-cy=search-guild-input]').type('app') | ||||||
|     cy.get('.guilds-list').children().should('have.length', 1) |     cy.get('.guilds-public-list').children().should('have.length', 1) | ||||||
|     cy.get('.guilds-list [data-cy=guild-name]:first').should('have.text', 'app') |     cy.get('.guilds-public-list [data-cy=guild-name]:first').should( | ||||||
|  |       'have.text', | ||||||
|  |       'app' | ||||||
|  |     ) | ||||||
|   }) |   }) | ||||||
| }) | }) | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { getGuildsHandler } from '../../../fixtures/guilds/get' | ||||||
| import { authenticationHandlers } from '../../../fixtures/handler' | import { authenticationHandlers } from '../../../fixtures/handler' | ||||||
|  |  | ||||||
| const applicationPaths = [ | const applicationPaths = [ | ||||||
| @@ -22,14 +23,23 @@ describe('Pages > /application', () => { | |||||||
|   }) |   }) | ||||||
|  |  | ||||||
|   it('should not redirect the user if signed in', () => { |   it('should not redirect the user if signed in', () => { | ||||||
|     cy.task('startMockServer', authenticationHandlers).setCookie( |     cy.task('startMockServer', [ | ||||||
|       'refreshToken', |       ...authenticationHandlers, | ||||||
|       'refresh-token' |       getGuildsHandler | ||||||
|     ) |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|     for (const applicationPath of applicationPaths) { |     for (const applicationPath of applicationPaths) { | ||||||
|       cy.visit(applicationPath) |       cy.visit(applicationPath) | ||||||
|         .location('pathname') |         .location('pathname') | ||||||
|         .should('eq', applicationPath) |         .should('eq', applicationPath) | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
|  |   it('should shows all the guilds of the current user in left sidebar', () => { | ||||||
|  |     cy.task('startMockServer', [ | ||||||
|  |       ...authenticationHandlers, | ||||||
|  |       getGuildsHandler | ||||||
|  |     ]).setCookie('refreshToken', 'refresh-token') | ||||||
|  |     cy.visit('/application') | ||||||
|  |     cy.get('.guilds-list').children().should('have.length', 2) | ||||||
|  |   }) | ||||||
| }) | }) | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { postUsersResetPasswordHandler } from '../../../fixtures/users/reset-password/post' | import { postUsersResetPasswordHandler } from '../../../fixtures/users/reset-password/post' | ||||||
| import { user } from '../../../fixtures/users/user' | import { userExample } from '../../../fixtures/users/user' | ||||||
|  |  | ||||||
| describe('Pages > /authentication/forgot-password', () => { | describe('Pages > /authentication/forgot-password', () => { | ||||||
|   beforeEach(() => { |   beforeEach(() => { | ||||||
| @@ -10,7 +10,7 @@ describe('Pages > /authentication/forgot-password', () => { | |||||||
|   it('should succeeds and sends a password-reset request', () => { |   it('should succeeds and sends a password-reset request', () => { | ||||||
|     cy.task('startMockServer', [postUsersResetPasswordHandler]) |     cy.task('startMockServer', [postUsersResetPasswordHandler]) | ||||||
|     cy.get('#message').should('not.exist') |     cy.get('#message').should('not.exist') | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should( |     cy.get('#message').should( | ||||||
|       'have.text', |       'have.text', | ||||||
| @@ -20,7 +20,7 @@ describe('Pages > /authentication/forgot-password', () => { | |||||||
|  |  | ||||||
|   it('should fails with unreachable api server', () => { |   it('should fails with unreachable api server', () => { | ||||||
|     cy.get('#message').should('not.exist') |     cy.get('#message').should('not.exist') | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should('have.text', 'Error: Internal Server Error.') |     cy.get('#message').should('have.text', 'Error: Internal Server Error.') | ||||||
|   }) |   }) | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import { | |||||||
|   postUsersSigninHandler, |   postUsersSigninHandler, | ||||||
|   postUsersSigninInvalidCredentialsHandler |   postUsersSigninInvalidCredentialsHandler | ||||||
| } from 'cypress/fixtures/users/signin/post' | } from 'cypress/fixtures/users/signin/post' | ||||||
| import { user } from '../../../fixtures/users/user' | import { userExample } from '../../../fixtures/users/user' | ||||||
|  |  | ||||||
| describe('Pages > /authentication/signin', () => { | describe('Pages > /authentication/signin', () => { | ||||||
|   beforeEach(() => { |   beforeEach(() => { | ||||||
| @@ -18,7 +18,7 @@ describe('Pages > /authentication/signin', () => { | |||||||
|     ]) |     ]) | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.location('pathname').should('eq', '/application') |     cy.location('pathname').should('eq', '/application') | ||||||
| @@ -27,7 +27,7 @@ describe('Pages > /authentication/signin', () => { | |||||||
|   it('should fails with unreachable api server', () => { |   it('should fails with unreachable api server', () => { | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should('have.text', 'Error: Internal Server Error.') |     cy.get('#message').should('have.text', 'Error: Internal Server Error.') | ||||||
| @@ -42,7 +42,7 @@ describe('Pages > /authentication/signin', () => { | |||||||
|     ]) |     ]) | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should( |     cy.get('#message').should( | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { user } from '../../../fixtures/users/user' | import { userExample } from '../../../fixtures/users/user' | ||||||
| import { | import { | ||||||
|   postUsersSignupHandler, |   postUsersSignupHandler, | ||||||
|   postUsersSignupAlreadyUsedHandler |   postUsersSignupAlreadyUsedHandler | ||||||
| @@ -15,8 +15,8 @@ describe('Pages > /authentication/signup', () => { | |||||||
|     cy.get('#error-name').should('not.exist') |     cy.get('#error-name').should('not.exist') | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-name]').type(user.name) |     cy.get('[data-cy=input-name]').type(userExample.name) | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should( |     cy.get('#message').should( | ||||||
| @@ -30,8 +30,8 @@ describe('Pages > /authentication/signup', () => { | |||||||
|     cy.get('#error-name').should('not.exist') |     cy.get('#error-name').should('not.exist') | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-name]').type(user.name) |     cy.get('[data-cy=input-name]').type(userExample.name) | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should('have.text', 'Error: Name or Email already used.') |     cy.get('#message').should('have.text', 'Error: Name or Email already used.') | ||||||
| @@ -44,8 +44,8 @@ describe('Pages > /authentication/signup', () => { | |||||||
|     cy.get('#error-name').should('not.exist') |     cy.get('#error-name').should('not.exist') | ||||||
|     cy.get('#error-email').should('not.exist') |     cy.get('#error-email').should('not.exist') | ||||||
|     cy.get('#error-password').should('not.exist') |     cy.get('#error-password').should('not.exist') | ||||||
|     cy.get('[data-cy=input-name]').type(user.name) |     cy.get('[data-cy=input-name]').type(userExample.name) | ||||||
|     cy.get('[data-cy=input-email]').type(user.email) |     cy.get('[data-cy=input-email]').type(userExample.email) | ||||||
|     cy.get('[data-cy=input-password]').type('randompassword') |     cy.get('[data-cy=input-password]').type('randompassword') | ||||||
|     cy.get('[data-cy=submit]').click() |     cy.get('[data-cy=submit]').click() | ||||||
|     cy.get('#message').should('have.text', 'Error: Internal Server Error.') |     cy.get('#message').should('have.text', 'Error: Internal Server Error.') | ||||||
|   | |||||||
| @@ -12,20 +12,30 @@ export const guildSchema = { | |||||||
|   createdAt: date.createdAt, |   createdAt: date.createdAt, | ||||||
|   updatedAt: date.updatedAt |   updatedAt: date.updatedAt | ||||||
| } | } | ||||||
|  | export const guildObjectSchema = Type.Object(guildSchema) | ||||||
|  | export type Guild = Static<typeof guildObjectSchema> | ||||||
|  |  | ||||||
|  | export const guildWithDefaultChannelIdSchema = { | ||||||
|  |   ...guildSchema, | ||||||
|  |   defaultChannelId: id | ||||||
|  | } | ||||||
|  | export const guildWithDefaultChannelObjectSchema = Type.Object( | ||||||
|  |   guildWithDefaultChannelIdSchema | ||||||
|  | ) | ||||||
|  | export type GuildWithDefaultChannelId = Static< | ||||||
|  |   typeof guildWithDefaultChannelObjectSchema | ||||||
|  | > | ||||||
|  |  | ||||||
| export const guildCompleteSchema = { | export const guildCompleteSchema = { | ||||||
|   ...guildSchema, |   ...guildSchema, | ||||||
|   channels: Type.Array(Type.Object(channelSchema)), |   channels: Type.Array(Type.Object(channelSchema)), | ||||||
|   members: Type.Array(Type.Object(memberSchema)) |   members: Type.Array(Type.Object(memberSchema)) | ||||||
| } | } | ||||||
|  | export const guildCompleteObjectSchema = Type.Object(guildCompleteSchema) | ||||||
|  | export type GuildComplete = Static<typeof guildCompleteObjectSchema> | ||||||
|  |  | ||||||
| export const guildPublicObjectSchema = Type.Object({ | export const guildPublicObjectSchema = Type.Object({ | ||||||
|   ...guildSchema, |   ...guildSchema, | ||||||
|   membersCount: Type.Integer({ min: 1 }) |   membersCount: Type.Integer({ min: 1 }) | ||||||
| }) | }) | ||||||
|  |  | ||||||
| export const guildCompleteObjectSchema = Type.Object(guildCompleteSchema) |  | ||||||
|  |  | ||||||
| export type GuildComplete = Static<typeof guildCompleteObjectSchema> |  | ||||||
|  |  | ||||||
| export type GuildPublic = Static<typeof guildPublicObjectSchema> | export type GuildPublic = Static<typeof guildPublicObjectSchema> | ||||||
|   | |||||||
							
								
								
									
										2095
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2095
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								package.json
									
									
									
									
									
								
							| @@ -37,8 +37,8 @@ | |||||||
|     "@fontsource/montserrat": "4.5.1", |     "@fontsource/montserrat": "4.5.1", | ||||||
|     "@fontsource/roboto": "4.5.1", |     "@fontsource/roboto": "4.5.1", | ||||||
|     "@heroicons/react": "1.0.5", |     "@heroicons/react": "1.0.5", | ||||||
|     "@sinclair/typebox": "0.20.5", |     "@sinclair/typebox": "0.21.0", | ||||||
|     "ajv": "8.7.1", |     "ajv": "8.8.1", | ||||||
|     "ajv-formats": "2.1.1", |     "ajv-formats": "2.1.1", | ||||||
|     "axios": "0.24.0", |     "axios": "0.24.0", | ||||||
|     "classnames": "2.3.1", |     "classnames": "2.3.1", | ||||||
| @@ -55,13 +55,13 @@ | |||||||
|     "react-swipeable": "6.2.0", |     "react-swipeable": "6.2.0", | ||||||
|     "react-textarea-autosize": "8.3.3", |     "react-textarea-autosize": "8.3.3", | ||||||
|     "read-pkg": "7.0.0", |     "read-pkg": "7.0.0", | ||||||
|     "sharp": "0.29.2", |     "sharp": "0.29.3", | ||||||
|     "socket.io-client": "4.3.2", |     "socket.io-client": "4.4.0", | ||||||
|     "universal-cookie": "4.0.4" |     "universal-cookie": "4.0.4" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@commitlint/cli": "14.1.0", |     "@commitlint/cli": "15.0.0", | ||||||
|     "@commitlint/config-conventional": "14.1.0", |     "@commitlint/config-conventional": "15.0.0", | ||||||
|     "@lhci/cli": "0.8.2", |     "@lhci/cli": "0.8.2", | ||||||
|     "@saithodev/semantic-release-backmerge": "2.1.0", |     "@saithodev/semantic-release-backmerge": "2.1.0", | ||||||
|     "@storybook/addon-essentials": "6.3.12", |     "@storybook/addon-essentials": "6.3.12", | ||||||
| @@ -71,9 +71,9 @@ | |||||||
|     "@testing-library/jest-dom": "5.15.0", |     "@testing-library/jest-dom": "5.15.0", | ||||||
|     "@testing-library/react": "12.1.2", |     "@testing-library/react": "12.1.2", | ||||||
|     "@types/date-and-time": "0.13.0", |     "@types/date-and-time": "0.13.0", | ||||||
|     "@types/jest": "27.0.2", |     "@types/jest": "27.0.3", | ||||||
|     "@types/node": "16.11.7", |     "@types/node": "16.11.8", | ||||||
|     "@types/react": "17.0.34", |     "@types/react": "17.0.35", | ||||||
|     "@types/react-responsive": "8.0.4", |     "@types/react-responsive": "8.0.4", | ||||||
|     "@typescript-eslint/eslint-plugin": "4.33.0", |     "@typescript-eslint/eslint-plugin": "4.33.0", | ||||||
|     "autoprefixer": "10.4.0", |     "autoprefixer": "10.4.0", | ||||||
| @@ -94,7 +94,7 @@ | |||||||
|     "eslint-plugin-unicorn": "38.0.1", |     "eslint-plugin-unicorn": "38.0.1", | ||||||
|     "husky": "7.0.4", |     "husky": "7.0.4", | ||||||
|     "jest": "27.3.1", |     "jest": "27.3.1", | ||||||
|     "lint-staged": "11.2.6", |     "lint-staged": "12.0.3", | ||||||
|     "markdownlint-cli": "0.29.0", |     "markdownlint-cli": "0.29.0", | ||||||
|     "mockttp": "2.4.0", |     "mockttp": "2.4.0", | ||||||
|     "plop": "2.7.6", |     "plop": "2.7.6", | ||||||
| @@ -105,7 +105,7 @@ | |||||||
|     "start-server-and-test": "1.14.0", |     "start-server-and-test": "1.14.0", | ||||||
|     "storybook-tailwind-dark-mode": "1.0.11", |     "storybook-tailwind-dark-mode": "1.0.11", | ||||||
|     "tailwindcss": "2.2.19", |     "tailwindcss": "2.2.19", | ||||||
|     "typescript": "4.4.4", |     "typescript": "4.5.2", | ||||||
|     "vercel": "23.1.2" |     "vercel": "23.1.2" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user