added ability to remove and add administrators
This commit is contained in:
@@ -122,7 +122,7 @@ function ContactForm({ InitializeContact, setContactsList }: ContactFormProps) {
|
||||
<input
|
||||
className="text-black bg-green-50 pl-2 shadow-lg rounded-md h-8 mb-2 mt-2"
|
||||
type="text"
|
||||
placeholder="Enter contact"
|
||||
placeholder="Search for user"
|
||||
onKeyDown={handleKeyDown}
|
||||
{...register('contact', {
|
||||
minLength: 4,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
import { axiosClient } from '@/App.tsx';
|
||||
import { ContactsProps } from '@/pages/Chat.tsx';
|
||||
import { socket } from '@/socket/socket.tsx';
|
||||
import { Sword } from 'lucide-react';
|
||||
import { Crown, Sword } from 'lucide-react';
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
@@ -11,38 +11,35 @@ import {
|
||||
} from '@/components/ui/context-menu';
|
||||
import { UsernameType } from '@/utils/ProtectedRoutes.tsx';
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import LoadingWheel from '@/components/chat/LoadingWheel.tsx';
|
||||
|
||||
type ParticipantsProps = {
|
||||
user_id: string;
|
||||
username: string;
|
||||
isadmin: boolean;
|
||||
isowner: boolean;
|
||||
};
|
||||
|
||||
type ParticipantsBarProps = {
|
||||
contact: ContactsProps | null;
|
||||
initializeContact: (contact: ContactsProps) => void;
|
||||
currentContact: ContactsProps | null;
|
||||
};
|
||||
|
||||
function ParticipantsBar({
|
||||
contact,
|
||||
initializeContact,
|
||||
currentContact,
|
||||
}: ParticipantsBarProps) {
|
||||
const [participants, setParticipants] = useState<ParticipantsProps[]>([]);
|
||||
const [isGroupAdmin, setIsGroupAdmin] = useState<boolean>(false);
|
||||
const user: UsernameType = useOutletContext();
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const getParticipants = async () => {
|
||||
try {
|
||||
const response = await axiosClient.get(
|
||||
`/api/chat/groups/getMembers/${contact?.conversation_id}`,
|
||||
`/api/chat/groups/getMembers/${currentContact?.conversation_id}`,
|
||||
);
|
||||
console.log(
|
||||
'getParticipants for: ',
|
||||
contact?.conversation_id,
|
||||
currentContact?.conversation_id,
|
||||
'response: ',
|
||||
response.data,
|
||||
);
|
||||
@@ -52,6 +49,60 @@ function ParticipantsBar({
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveUser = async (userId: string) => {
|
||||
socket?.emit(
|
||||
'remove user from group',
|
||||
{
|
||||
group_id: currentContact?.conversation_id,
|
||||
user_id: userId,
|
||||
},
|
||||
(response: { status: 'ok' | 'error'; message: string }) => {
|
||||
if (response.status == 'ok') {
|
||||
console.log(response.message);
|
||||
} else {
|
||||
console.error('Failed to remove user from group: ', response.message);
|
||||
}
|
||||
},
|
||||
);
|
||||
// setParticipants((prevMembers) =>
|
||||
// prevMembers.filter((member) => member.user_id !== userId),
|
||||
// );
|
||||
};
|
||||
|
||||
const handleAddToAdministrators = async (userId: string) => {
|
||||
socket?.emit(
|
||||
'added administrator',
|
||||
{ group_id: currentContact?.conversation_id, user_id: userId },
|
||||
(response: { status: 'ok' | 'error'; message: string }) => {
|
||||
if (response.status == 'ok') {
|
||||
console.log(response.message);
|
||||
} else {
|
||||
console.error(
|
||||
'Failed to add user to administrators: ',
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleRemoveFromAdministrators = async (userId: string) => {
|
||||
socket?.emit(
|
||||
'removed administrator',
|
||||
{ group_id: currentContact?.conversation_id, user_id: userId },
|
||||
(response: { status: 'ok' | 'error'; message: string }) => {
|
||||
if (response.status == 'ok') {
|
||||
console.log(response.message);
|
||||
} else {
|
||||
console.error(
|
||||
'Failed to remove user from administrators: ',
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (participants.length > 0 && user?.user_id) {
|
||||
const userIsAdmin = participants.some(
|
||||
@@ -63,19 +114,20 @@ function ParticipantsBar({
|
||||
}, [participants, user?.user_id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (contact) {
|
||||
if (currentContact) {
|
||||
getParticipants();
|
||||
}
|
||||
}, [contact]);
|
||||
}, [currentContact]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket || !contact) return;
|
||||
if (!socket || !currentContact) return;
|
||||
|
||||
const handleAddedToGroup = (msg: {
|
||||
username: string;
|
||||
user_id: string;
|
||||
group_id: string;
|
||||
isadmin: false;
|
||||
isadmin: boolean;
|
||||
isowner: boolean;
|
||||
}) => {
|
||||
const { group_id } = msg;
|
||||
if (
|
||||
@@ -93,7 +145,7 @@ function ParticipantsBar({
|
||||
});
|
||||
}
|
||||
|
||||
if (group_id === contact.conversation_id) {
|
||||
if (group_id === currentContact.conversation_id) {
|
||||
setParticipants((prevMembers) => {
|
||||
const existingMember = prevMembers.some(
|
||||
(m) => m.user_id === msg.user_id,
|
||||
@@ -111,6 +163,7 @@ function ParticipantsBar({
|
||||
msg.group_id == currentContact?.conversation_id &&
|
||||
msg.user_id == user?.user_id
|
||||
) {
|
||||
setParticipants([]);
|
||||
initializeContact(currentContact);
|
||||
}
|
||||
setParticipants((prevMembers) =>
|
||||
@@ -118,6 +171,36 @@ function ParticipantsBar({
|
||||
);
|
||||
};
|
||||
|
||||
const handleAddToAdmins = (msg: { user_id: string; group_id: string }) => {
|
||||
if (msg.group_id === currentContact.conversation_id) {
|
||||
setParticipants((prevMembers) =>
|
||||
prevMembers.map((member) =>
|
||||
member.user_id === msg.user_id
|
||||
? { ...member, isadmin: true }
|
||||
: member,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveFromAdmins = (msg: {
|
||||
user_id: string;
|
||||
group_id: string;
|
||||
}) => {
|
||||
console.log('(socket) removed administrator: ', msg);
|
||||
if (msg.group_id === currentContact.conversation_id) {
|
||||
setParticipants((prevMembers) =>
|
||||
prevMembers.map((member) =>
|
||||
member.user_id === msg.user_id
|
||||
? { ...member, isadmin: false }
|
||||
: member,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
socket.on('added administrator', handleAddToAdmins);
|
||||
socket.on('removed administrator', handleRemoveFromAdmins);
|
||||
socket.on('added to group', handleAddedToGroup);
|
||||
socket.on('left group', handleLeftGroup);
|
||||
|
||||
@@ -125,36 +208,7 @@ function ParticipantsBar({
|
||||
socket?.off('added to group', handleAddedToGroup);
|
||||
socket?.off('left group', handleLeftGroup);
|
||||
};
|
||||
}, [socket, contact, currentContact, user?.user_id]);
|
||||
|
||||
const handleRemoveUser = async (userId: string) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
socket?.emit(
|
||||
'remove user from group',
|
||||
{
|
||||
group_id: contact?.conversation_id,
|
||||
user_id: userId,
|
||||
},
|
||||
(response: { status: 'ok' | 'error'; message: string }) => {
|
||||
if (response.status == 'ok') {
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
console.error(
|
||||
'Failed to remove user from group: ',
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
// setParticipants((prevMembers) =>
|
||||
// prevMembers.filter((member) => member.user_id !== userId),
|
||||
// );
|
||||
} catch (error) {
|
||||
console.error('Failed to remove user:', error);
|
||||
}
|
||||
};
|
||||
}, [socket, currentContact, currentContact, user?.user_id]);
|
||||
|
||||
const ParticipantsList = participants?.map(
|
||||
(participant: ParticipantsProps) => (
|
||||
@@ -163,6 +217,11 @@ function ParticipantsBar({
|
||||
<li className="p-2 hover:bg-gray-700 rounded-md flex items-center justify-between group">
|
||||
<span className="flex items-center gap-2">
|
||||
{participant.username}
|
||||
{participant.isowner ? (
|
||||
<span className="flex items-center text-yellow-400 text-xs">
|
||||
<Crown className="h-3 w-3" />
|
||||
</span>
|
||||
) : null}
|
||||
{participant.isadmin && (
|
||||
<span className="flex items-center text-green-300 text-xs">
|
||||
<Sword className="h-3 w-3" />
|
||||
@@ -174,21 +233,39 @@ function ParticipantsBar({
|
||||
</span>
|
||||
</li>
|
||||
</ContextMenuTrigger>
|
||||
{isGroupAdmin && user.user_id !== participant.user_id && (
|
||||
{user.user_id !== participant.user_id && isGroupAdmin ? (
|
||||
<ContextMenuContent className="p-0">
|
||||
<ContextMenuItem
|
||||
className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
|
||||
onClick={() => handleRemoveUser(participant.user_id)}
|
||||
>
|
||||
{isLoading ? <LoadingWheel /> : <p>Remove from group</p>}
|
||||
<p>Remove from group</p>
|
||||
</ContextMenuItem>
|
||||
{!participant.isadmin ? (
|
||||
<ContextMenuItem
|
||||
className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
|
||||
onClick={() => handleAddToAdministrators(participant.user_id)}
|
||||
>
|
||||
<p>Add to group administrator</p>
|
||||
</ContextMenuItem>
|
||||
) : null}
|
||||
{participant.isadmin ? (
|
||||
<ContextMenuItem
|
||||
className="bg-zinc-900 text-white outline-1 hover:bg-zinc-800 hover:cursor-pointer"
|
||||
onClick={() =>
|
||||
handleRemoveFromAdministrators(participant.user_id)
|
||||
}
|
||||
>
|
||||
<p>Remove from administrator</p>
|
||||
</ContextMenuItem>
|
||||
) : null}
|
||||
</ContextMenuContent>
|
||||
)}
|
||||
) : null}
|
||||
</ContextMenu>
|
||||
),
|
||||
);
|
||||
|
||||
if (!contact) {
|
||||
if (!currentContact) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -238,7 +238,6 @@ function Chat() {
|
||||
{currentContact?.type == 'group' ? (
|
||||
<div className="w-80 bg-[#1E1E1E] flex-shrink-0">
|
||||
<ParticipantsBar
|
||||
contact={currentContact}
|
||||
initializeContact={initializeContact}
|
||||
currentContact={currentContact}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user