diff --git a/packages/frontend/src/assets/members.json b/packages/frontend/src/assets/members.json index 680be790..c8c7cb0e 100644 --- a/packages/frontend/src/assets/members.json +++ b/packages/frontend/src/assets/members.json @@ -2,19 +2,19 @@ { "name": "Saugat Yadav", "email": "saugaty@airfoil.studio", - "isOwner": true, - "id": 1 + "id": 1, + "permissions": [] }, { "name": "Gideon Low", "email": "gideonl@airfoil.studio", - "isOwner": false, - "id": 2 + "id": 2, + "permissions": ["view", "edit"] }, { "name": "Sushan Yadav", "email": "sushany@airfoil.studio", - "isOwner": false, - "id": 3 + "id": 3, + "permissions": ["view"] } ] diff --git a/packages/frontend/src/assets/projects.json b/packages/frontend/src/assets/projects.json index 1c73fe87..091df143 100644 --- a/packages/frontend/src/assets/projects.json +++ b/packages/frontend/src/assets/projects.json @@ -17,7 +17,8 @@ "branch": "main" }, "repositoryId": 1, - "members": [1, 2, 3] + "members": [1, 2, 3], + "ownerId": 1 }, { "id": 2, @@ -37,7 +38,8 @@ "branch": "staging" }, "repositoryId": 1, - "members": [2, 3] + "members": [2, 3], + "ownerId": 2 }, { "id": 3, @@ -57,7 +59,8 @@ "branch": "main" }, "repositoryId": 1, - "members": [1] + "members": [1], + "ownerId": 1 }, { "id": 4, @@ -77,7 +80,8 @@ "branch": "main" }, "repositoryId": 1, - "members": [1] + "members": [1], + "ownerId": 1 }, { "id": 5, @@ -97,7 +101,8 @@ "branch": "main" }, "repositoryId": 1, - "members": [1] + "members": [1], + "ownerId": 1 }, { "id": 6, @@ -117,6 +122,7 @@ "branch": "prod" }, "repositoryId": 1, - "members": [1] + "members": [1], + "ownerId": 1 } ] diff --git a/packages/frontend/src/components/projects/project/settings/MemberCard.tsx b/packages/frontend/src/components/projects/project/settings/MemberCard.tsx index feb0e7a0..702a9ba3 100644 --- a/packages/frontend/src/components/projects/project/settings/MemberCard.tsx +++ b/packages/frontend/src/components/projects/project/settings/MemberCard.tsx @@ -1,17 +1,53 @@ -import React from 'react'; +import React, { useCallback, useState } from 'react'; import { Select, Typography, Option } from '@material-tailwind/react'; import { Member } from '../../../../types/project'; +import ConfirmDialog from '../../../shared/ConfirmDialog'; -const PERMISSION_OPTIONS = ['View only', 'View and edit']; +const PERMISSION_OPTIONS = [ + { + label: 'View only', + value: 'view', + }, + { + label: 'View and edit', + value: 'view+edit', + }, +]; + +const DROPDOWN_OPTIONS = [ + ...PERMISSION_OPTIONS, + { label: 'Remove member', value: 'remove' }, +]; interface MemberCardProps { member: Member; isFirstCard: boolean; + isOwner: boolean; } -const MemberCard = ({ member, isFirstCard }: MemberCardProps) => { +const MemberCard = ({ member, isFirstCard, isOwner }: MemberCardProps) => { + const [selectedPermission, setSelectedPermission] = useState( + member.permissions.join('+'), + ); + const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false); + + const handlePermissionChange = useCallback( + (value: string) => { + setSelectedPermission(value); + + if (value === 'remove') { + setRemoveMemberDialogOpen((prevVal) => !prevVal); + // To display updated label in next render + setTimeout(() => { + setSelectedPermission(selectedPermission); + }); + } + }, + [removeMemberDialogOpen, selectedPermission], + ); + return (
{ {member.name} {member.email}
-
- handlePermissionChange(value!)} + selected={(_, index) => ( + {DROPDOWN_OPTIONS[index!]?.label} + )} + > + {DROPDOWN_OPTIONS.map((permission, key) => ( + ))} -
+ setRemoveMemberDialogOpen((preVal) => !preVal)} + open={removeMemberDialogOpen} + confirmButtonTitle="Yes, Remove member" + handleConfirm={() => { + setRemoveMemberDialogOpen((preVal) => !preVal); + }} + color="red" + > + + Once removed, {member.name} ({member.email}) will not be able to + access this project. + + ); }; diff --git a/packages/frontend/src/components/projects/project/settings/MembersTabPanel.tsx b/packages/frontend/src/components/projects/project/settings/MembersTabPanel.tsx index 3ca386b7..db2a2976 100644 --- a/packages/frontend/src/components/projects/project/settings/MembersTabPanel.tsx +++ b/packages/frontend/src/components/projects/project/settings/MembersTabPanel.tsx @@ -27,7 +27,7 @@ const MembersTabPanel = () => { }, [currProject]); return ( -
+
Members @@ -49,6 +49,7 @@ const MembersTabPanel = () => { member={member} key={member.id} isFirstCard={index === FIRST_MEMBER_CARD} + isOwner={member.id === currProject?.ownerId} /> ); })} diff --git a/packages/frontend/src/types/project.ts b/packages/frontend/src/types/project.ts index a3f558cb..924706e0 100644 --- a/packages/frontend/src/types/project.ts +++ b/packages/frontend/src/types/project.ts @@ -17,6 +17,7 @@ export interface ProjectDetails { }; repositoryId: number; members: number[]; + ownerId: number; } export interface DeploymentDetails { @@ -83,9 +84,14 @@ export interface DomainDetails { isRedirectedto: boolean; } +export enum Permission { + VIEW = 'view', + EDIT = 'edit', +} + export interface Member { name: string; email: string; - isOwner: boolean; id: number; + permissions: Permission[]; }