feat: add guilds and channels CRUD (#14)
This commit is contained in:
@ -1,9 +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 } from 'models/Channel'
|
||||
import { Channel, ChannelWithDefaultChannelId } from 'models/Channel'
|
||||
import { GuildsChannelsPath } from 'components/Application'
|
||||
import { handleSocketData, SocketData } from 'tools/handleSocketData'
|
||||
|
||||
export interface Channels {
|
||||
channels: Channel[]
|
||||
@ -20,19 +22,38 @@ export interface ChannelsProviderProps {
|
||||
|
||||
export const ChannelsProvider: React.FC<ChannelsProviderProps> = (props) => {
|
||||
const { path, children } = props
|
||||
|
||||
const router = useRouter()
|
||||
const { authentication } = useAuthentication()
|
||||
|
||||
const {
|
||||
items: channels,
|
||||
hasMore,
|
||||
nextPage,
|
||||
resetPagination
|
||||
resetPagination,
|
||||
setItems
|
||||
} = usePagination<Channel>({
|
||||
api: authentication.api,
|
||||
url: `/guilds/${path.guildId}/channels`
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
authentication.socket.on(
|
||||
'channels',
|
||||
async (data: SocketData<ChannelWithDefaultChannelId>) => {
|
||||
handleSocketData({ data, setItems })
|
||||
if (data.action === 'delete') {
|
||||
await router.push(
|
||||
`/application/${path.guildId}/${data.item.defaultChannelId}`
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return () => {
|
||||
authentication.socket.off('channels')
|
||||
}
|
||||
}, [authentication.socket, path.guildId, router, setItems])
|
||||
|
||||
useEffect(() => {
|
||||
resetPagination()
|
||||
nextPage()
|
||||
|
@ -1,48 +1,92 @@
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import { Guild } from 'models/Guild'
|
||||
import { GuildWithDefaultChannelId } from 'models/Guild'
|
||||
import { Member } from 'models/Member'
|
||||
import { GuildsChannelsPath } from 'components/Application'
|
||||
import { useAuthentication } from 'tools/authentication'
|
||||
import { SocketData } from 'tools/handleSocketData'
|
||||
|
||||
export interface GuildMember {
|
||||
guild: Guild
|
||||
guild: GuildWithDefaultChannelId
|
||||
member: Member
|
||||
}
|
||||
|
||||
export interface GuildMemberResult extends GuildMember {
|
||||
setGuildMember: React.Dispatch<React.SetStateAction<GuildMember>>
|
||||
}
|
||||
|
||||
export interface GuildMemberProps {
|
||||
guildMember: GuildMember
|
||||
path: GuildsChannelsPath
|
||||
path: {
|
||||
guildId: number
|
||||
}
|
||||
}
|
||||
|
||||
const defaultGuildMemberContext = {} as any
|
||||
const GuildMemberContext = createContext<GuildMember>(defaultGuildMemberContext)
|
||||
const GuildMemberContext = createContext<GuildMemberResult>(
|
||||
defaultGuildMemberContext
|
||||
)
|
||||
|
||||
export const GuildMemberProvider: React.FC<GuildMemberProps> = (props) => {
|
||||
const { path, children } = props
|
||||
const router = useRouter()
|
||||
const [guildMember, setGuildMember] = useState(props.guildMember)
|
||||
const { authentication } = useAuthentication()
|
||||
|
||||
useEffect(() => {
|
||||
const fetchGuildMember = async (): Promise<void> => {
|
||||
const { data } = await authentication.api.get(
|
||||
`/guilds/${props.path.guildId}`
|
||||
)
|
||||
const { data } = await authentication.api.get(`/guilds/${path.guildId}`)
|
||||
setGuildMember(data)
|
||||
}
|
||||
|
||||
fetchGuildMember().catch((error) => {
|
||||
console.error(error)
|
||||
})
|
||||
}, [props.path, authentication.api])
|
||||
}, [path, authentication.api])
|
||||
|
||||
useEffect(() => {
|
||||
authentication.socket.on(
|
||||
'guilds',
|
||||
async (data: SocketData<GuildWithDefaultChannelId>) => {
|
||||
if (data.item.id === path.guildId) {
|
||||
switch (data.action) {
|
||||
case 'delete':
|
||||
await router.push('/application')
|
||||
break
|
||||
case 'update':
|
||||
setGuildMember((oldGuildMember) => {
|
||||
return {
|
||||
...oldGuildMember,
|
||||
guild: {
|
||||
...oldGuildMember.guild,
|
||||
...data.item
|
||||
}
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return () => {
|
||||
authentication.socket.off('guilds')
|
||||
}
|
||||
}, [authentication.socket, path.guildId, router])
|
||||
|
||||
return (
|
||||
<GuildMemberContext.Provider value={guildMember}>
|
||||
{props.children}
|
||||
<GuildMemberContext.Provider
|
||||
value={{
|
||||
...guildMember,
|
||||
setGuildMember
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</GuildMemberContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useGuildMember = (): GuildMember => {
|
||||
export const useGuildMember = (): GuildMemberResult => {
|
||||
const guildMember = useContext(GuildMemberContext)
|
||||
if (guildMember === defaultGuildMemberContext) {
|
||||
throw new Error('useGuildMember must be used within GuildMemberProvider')
|
||||
|
@ -3,6 +3,7 @@ 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'
|
||||
|
||||
export interface Guilds {
|
||||
guilds: GuildWithDefaultChannelId[]
|
||||
@ -22,12 +23,26 @@ export const GuildsProvider: React.FC = (props) => {
|
||||
items: guilds,
|
||||
hasMore,
|
||||
nextPage,
|
||||
resetPagination
|
||||
resetPagination,
|
||||
setItems
|
||||
} = usePagination<GuildWithDefaultChannelId>({
|
||||
api: authentication.api,
|
||||
url: '/guilds'
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
authentication.socket.on(
|
||||
'guilds',
|
||||
(data: SocketData<GuildWithDefaultChannelId>) => {
|
||||
handleSocketData({ data, setItems })
|
||||
}
|
||||
)
|
||||
|
||||
return () => {
|
||||
authentication.socket.off('guilds')
|
||||
}
|
||||
}, [authentication.socket, setItems])
|
||||
|
||||
useEffect(() => {
|
||||
resetPagination()
|
||||
nextPage()
|
||||
|
@ -4,6 +4,8 @@ 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[]
|
||||
@ -27,12 +29,45 @@ export const MembersProviders: React.FC<MembersProviderProps> = (props) => {
|
||||
items: members,
|
||||
hasMore,
|
||||
nextPage,
|
||||
resetPagination
|
||||
resetPagination,
|
||||
setItems
|
||||
} = usePagination<MemberWithPublicUser>({
|
||||
api: authentication.api,
|
||||
url: `/guilds/${path.guildId}/members`
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
authentication.socket.on(
|
||||
'members',
|
||||
(data: SocketData<MemberWithPublicUser>) => {
|
||||
handleSocketData({ data, setItems })
|
||||
}
|
||||
)
|
||||
|
||||
authentication.socket.on('users', (data: SocketData<User>) => {
|
||||
setItems((oldItems) => {
|
||||
const newItems = [...oldItems]
|
||||
switch (data.action) {
|
||||
case 'update': {
|
||||
for (const member of newItems) {
|
||||
if (member.user.id === data.item.id) {
|
||||
member.user = data.item
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return newItems
|
||||
})
|
||||
})
|
||||
|
||||
return () => {
|
||||
authentication.socket.off('members')
|
||||
authentication.socket.off('users')
|
||||
}
|
||||
}, [authentication.socket, setItems])
|
||||
|
||||
useEffect(() => {
|
||||
resetPagination()
|
||||
nextPage()
|
||||
|
Reference in New Issue
Block a user