Project member management

This commit is contained in:
Takeshi Kimata
2024-05-31 23:15:03 +09:00
parent db121940d8
commit 191d8c0a72
10 changed files with 194 additions and 61 deletions

View File

@@ -7,9 +7,8 @@ import { MemberType, UserType } from '@/types/user';
import { SettingsMessages } from '@/types/settings';
import { TokenContext } from '@/utils/TokenProvider';
import MembersTable from './MembersTable';
import Config from '@/config/config';
import AddMemberDialog from './AddMemberDialog';
const apiServer = Config.apiServer;
import { fetchProjectMembers, addMember, deleteMember, updateMember } from './membersControl';
type Props = {
projectId: string;
@@ -17,53 +16,6 @@ type Props = {
locale: string;
};
// Member Search
async function fetchProjectMembers(jwt: string, projectId: string) {
const fetchOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
};
const url = `${apiServer}/members?projectId=${projectId}`;
try {
const response = await fetch(url, fetchOptions);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error: any) {
console.error('Error fetching data:', error.message);
}
}
async function addMember(jwt: string, userId: string, projectId: string) {
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwt}`,
},
};
const url = `${apiServer}/members?userId=${userId}&projectId=${projectId}`;
try {
const response = await fetch(url, fetchOptions);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error: any) {
console.error('Error fetching data:', error.message);
}
}
export default function SettingsPage({ projectId, messages, locale }: Props) {
const context = useContext(TokenContext);
const [members, setMembers] = useState<MemberType[]>([]);
@@ -86,9 +38,9 @@ export default function SettingsPage({ projectId, messages, locale }: Props) {
fetchDataEffect();
}, [context]);
const handleAddMember = async (memberAdded: UserType) => {
const newMember = await addMember(context.token.access_token, memberAdded.id, projectId);
newMember.User = memberAdded;
const handleAddMember = async (userAdded: UserType) => {
const newMember = await addMember(context.token.access_token, userAdded.id, projectId);
newMember.User = userAdded;
const updateMembers = [...members];
updateMembers.push(newMember);
setMembers(updateMembers);
@@ -96,6 +48,23 @@ export default function SettingsPage({ projectId, messages, locale }: Props) {
setIsDialogOpen(false);
};
const handleDeleteMember = async (userDeleted: UserType) => {
await deleteMember(context.token.access_token, userDeleted.id, projectId);
setMembers(members.filter((member) => member.User.id !== userDeleted.id));
};
const handleChangeRole = async (userEdit: UserType, role: number) => {
await updateMember(context.token.access_token, userEdit.id, projectId, role);
setMembers((prevMembers) => {
return prevMembers.map((member) => {
if (member.User.id === userEdit.id) {
return { ...member, role: role };
}
return member;
});
});
};
return (
<div className="container mx-auto max-w-3xl pt-16 px-6 flex-grow">
<div className="w-full p-3 flex items-center justify-between">
@@ -105,7 +74,12 @@ export default function SettingsPage({ projectId, messages, locale }: Props) {
</Button>
</div>
<MembersTable members={members} messages={messages} />
<MembersTable
members={members}
onChangeRole={handleChangeRole}
onDeleteMember={handleDeleteMember}
messages={messages}
/>
<AddMemberDialog
isOpen={isDialogOpen}