11import { useSideBarOptionSetter } from '@/context/SideBarOptionCtx' ;
22import { getOrCreateDMChannel } from '@/lib/DMChannelHelper' ;
3- import { useDMChannels , useSetChannel } from '@/lib/store' ;
3+ import {
4+ useChannel ,
5+ useDMChannels ,
6+ useGetAllServerUserProfiles ,
7+ useServerRoles ,
8+ useServerUserProfileHighestRolePosition ,
9+ useServerUserProfilePermissions ,
10+ useSetChannel
11+ } from '@/lib/store' ;
412import { createMessage } from '@/services/message.service' ;
5- import { Role , ServerUser , User } from '@/types/dbtypes' ;
13+ import { ServerUserProfile } from '@/types/dbtypes' ;
614import { useSupabaseClient , useUser } from '@supabase/auth-helpers-react' ;
7- import { memo , } from 'react' ;
815import UserIcon from '../icons/UserIcon' ;
916import { SearchBar } from './Styles' ;
17+ import { ServerPermissions } from '@/types/permissions' ;
18+ import * as DropdownMenu from '@radix-ui/react-dropdown-menu' ;
19+ import { grantRoleToUser , revokeRoleFromUser } from '@/services/roles.service' ;
20+ import { toast } from 'react-toastify' ;
21+ import { XIcon } from '@/components/icons/XIcon' ;
1022
11- // TODO: Once DMs are implemented, this component will need to be updated to handle DMs as well.
12- function WrappedComponent ( {
13- profile,
14- server_user,
15- roles,
16- } : {
17- profile : User ;
18- server_user : ServerUser ;
19- roles : Role [ ] ;
20- } ) {
23+
24+ export function MiniProfile ( { server_user_profile } : { server_user_profile : ServerUserProfile } ) {
2125 const user = useUser ( ) ;
2226 const supabase = useSupabaseClient ( ) ;
2327 const dmChannels = useDMChannels ( ) ;
2428 const setChannel = useSetChannel ( ) ;
2529 const setSideBarOption = useSideBarOptionSetter ( ) ;
30+ const channel = useChannel ( ) ;
31+
32+ const serverRoles = useServerRoles ( channel ! . server_id ! ) ;
33+ const userHighestRole = useServerUserProfileHighestRolePosition (
34+ server_user_profile . server_user . server_id ,
35+ user ! . id
36+ ) ;
37+ const currentUserPerms = useServerUserProfilePermissions (
38+ server_user_profile . server_user . server_id ,
39+ user ! . id
40+ ) ;
41+
42+ const getAllServerProfiles = useGetAllServerUserProfiles ( ) ;
43+
44+ const filteredRoles = serverRoles
45+ . filter (
46+ role => (
47+ role . position > userHighestRole
48+ && role . position !== serverRoles . length - 1
49+ && ! server_user_profile . roles . some ( r => r . id === role . id )
50+ )
51+ ) ;
2652
2753 return (
2854 < div className = "flex flex-col space-y-2 items-center p-3" >
29- < UserIcon user = { profile } className = "!w-9 !h-9" />
30- { server_user . nickname && (
31- < h2 className = "text-lg" > { server_user . nickname } </ h2 >
55+ < UserIcon user = { server_user_profile } className = "!w-9 !h-9" />
56+ { server_user_profile . server_user . nickname && (
57+ < h2 className = "text-lg" > { server_user_profile . server_user . nickname } </ h2 >
3258 ) }
33- < h2 className = { server_user . nickname ? 'text-base' : 'text-lg' } >
34- { profile . username }
59+ < h2 className = { server_user_profile . server_user . nickname ? 'text-base' : 'text-lg' } >
60+ { server_user_profile . username }
3561 </ h2 >
3662 < hr />
3763 < h2 className = "text-sm text-gray-400 text-left w-full" > Roles</ h2 >
64+
3865 < div className = "flex flex-col w-full items-center space-y-1" >
39- { roles . map ( ( role ) => (
66+ { server_user_profile . roles . map ( ( role ) => (
4067 < span
4168 key = { role . id }
42- className = "text-sm text-gray-400 py-1 px-2 border-2 border-solid w-full rounded-sm"
69+ className = "text-sm text-gray-400 py-1 px-2 border-2 border-solid w-full rounded-sm flex flex-row items-center "
4370 style = { {
4471 border : `1px solid #${ ! ! role . color ? role . color : 'cacacacc' } ` ,
4572 color : `#${ ! ! role . color ? role . color : 'cacacacc' } ` ,
4673 } }
4774 >
48- { role . name }
75+ < p className = "flex-grow" > { role . name } </ p >
76+ { (
77+ ( currentUserPerms & ServerPermissions . MANAGE_ROLES ) === ServerPermissions . MANAGE_ROLES
78+ && role . position > userHighestRole
79+ && role . position !== serverRoles . length - 1
80+ ) && (
81+ < button
82+ type = "button"
83+ className = "align-middle self-end"
84+ style = { {
85+ fill : `#${ ! ! role . color ? role . color : 'cacacacc' } ` ,
86+ } }
87+ onClick = { async ( ) => {
88+ const { error } = await revokeRoleFromUser (
89+ supabase ,
90+ role . id ,
91+ server_user_profile . server_user . id ,
92+ ) ;
93+
94+ if ( error ) {
95+ console . error ( error ) ;
96+ toast . error ( 'Failed to revoke role from user' ) ;
97+ return ;
98+ }
99+
100+ toast . success ( 'Role revoked from user' ) ;
101+ } }
102+ >
103+ < XIcon className = "w-4 h-4" />
104+ </ button >
105+ ) }
49106 </ span >
50107 ) ) }
108+
109+ { (
110+ ( currentUserPerms & ServerPermissions . MANAGE_ROLES ) === ServerPermissions . MANAGE_ROLES
111+ && filteredRoles . length > 0
112+ ) && (
113+ < DropdownMenu . Root >
114+ < DropdownMenu . Trigger
115+ asChild
116+ >
117+ < button
118+ type = "button"
119+ className = "text-sm text-gray-400 py-1 px-2 border-2 border-solid w-full rounded-sm text-center"
120+ style = { {
121+ border : '1px solid #cacacacc'
122+ } }
123+ >
124+ +
125+ </ button >
126+ </ DropdownMenu . Trigger >
127+ < DropdownMenu . Content
128+ side = "right"
129+ className = "ContextMenuContent"
130+ >
131+ { filteredRoles . map ( ( role ) => (
132+ < DropdownMenu . Item
133+ key = { role . id }
134+ className = "ContextMenuItem"
135+ style = { {
136+ color : `#${ ! ! role . color ? role . color : 'cacacacc' } ` ,
137+ } }
138+ onSelect = { async ( ) => {
139+ const { error } = await grantRoleToUser (
140+ supabase ,
141+ role . id ,
142+ server_user_profile . server_user . id ,
143+ ) ;
144+
145+ if ( error ) {
146+ console . error ( error ) ;
147+ toast . error ( 'Failed to grant role to user' ) ;
148+ return ;
149+ }
150+
151+ toast . success ( 'Role granted to user' ) ;
152+ } }
153+ >
154+ { role . name }
155+ </ DropdownMenu . Item >
156+ ) ) }
157+ </ DropdownMenu . Content >
158+ </ DropdownMenu . Root >
159+ ) }
51160 </ div >
52161 < hr />
53- { profile . id !== user ?. id && ( < form >
162+ { server_user_profile . id !== user ?. id && ( < form >
54163 < input
55164 type = "text"
56165 className = { `${ SearchBar ( 'bg-grey-900' ) } ` }
57- placeholder = { `Message ${ profile . username } ` }
166+ placeholder = { `Message ${ server_user_profile . username } ` }
58167 onKeyDown = { async ( e ) => {
59168 if ( e . key === 'Enter' ) {
60169 e . preventDefault ( ) ;
61170 const dmChannel = await getOrCreateDMChannel (
62171 supabase ,
63- profile ,
172+ server_user_profile ,
64173 dmChannels
65174 ) ;
66175
@@ -74,6 +183,7 @@ function WrappedComponent({
74183 }
75184 ) ;
76185
186+ getAllServerProfiles ( supabase , dmChannel . server_id ) ;
77187 setSideBarOption ( 'friends' ) ;
78188 setChannel ( dmChannel ) ;
79189 }
@@ -84,5 +194,3 @@ function WrappedComponent({
84194 </ div >
85195 ) ;
86196}
87-
88- export const MiniProfile = memo ( WrappedComponent ) ;
0 commit comments