From 6d2138d200558ad436991d56798616553ee231b2 Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Mon, 1 Dec 2025 23:41:54 +0700
Subject: [PATCH 1/9] fix: migrate role selection modal to new page

---
 src/ROUTES.ts                                 |   4 +
 src/SCREENS.ts                                |   1 +
 .../ModalStackNavigators/index.tsx            |   1 +
 .../RELATIONS/WORKSPACE_TO_RHP.ts             |   1 +
 src/libs/Navigation/linkingConfig/config.ts   |   3 +
 src/libs/Navigation/types.ts                  |   4 +
 .../members/WorkspaceMemberDetailsPage.tsx    |  65 +---------
 .../WorkspaceMemberDetailsRolePage.tsx        | 115 ++++++++++++++++++
 src/pages/workspace/withPolicy.tsx            |   1 +
 9 files changed, 132 insertions(+), 63 deletions(-)
 create mode 100644 src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx

diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 3893661d7645..170677f60bc1 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -2003,6 +2003,10 @@ const ROUTES = {
         route: 'workspaces/:policyID/members/:accountID',
         getRoute: (policyID: string, accountID: number) => `workspaces/${policyID}/members/${accountID}` as const,
     },
+    WORKSPACE_MEMBER_DETAILS_ROLE: {
+        route: 'workspaces/:policyID/members/:accountID/role',
+        getRoute: (policyID: string, accountID: number) => `workspaces/${policyID}/members/${accountID}/role` as const,
+    },
     WORKSPACE_CUSTOM_FIELDS: {
         route: 'workspaces/:policyID/members/:accountID/:customFieldType',
         getRoute: (policyID: string, accountID: number, customFieldType: CustomFieldType) => `/workspaces/${policyID}/members/${accountID}/${customFieldType}` as const,
diff --git a/src/SCREENS.ts b/src/SCREENS.ts
index 9584b2a5f359..7660954e0dec 100644
--- a/src/SCREENS.ts
+++ b/src/SCREENS.ts
@@ -671,6 +671,7 @@ const SCREENS = {
         CATEGORIES_IMPORTED: 'Categories_Imported',
         MORE_FEATURES: 'Workspace_More_Features',
         MEMBER_DETAILS: 'Workspace_Member_Details',
+        MEMBER_DETAILS_ROLE: 'Workspace_Member_Details_Role',
         MEMBER_CUSTOM_FIELD: 'Workspace_Member_Custom_Field',
         MEMBER_NEW_CARD: 'Workspace_Member_NewCard',
         OWNER_CHANGE_CHECK: 'Workspace_Owner_Change_Check',
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
index 14698f195184..76d6018517ae 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx
@@ -486,6 +486,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
     [SCREENS.WORKSPACE.DOWNGRADE]: () => require<ReactComponentModule>('../../../../pages/workspace/downgrade/WorkspaceDowngradePage').default,
     [SCREENS.WORKSPACE.PAY_AND_DOWNGRADE]: () => require<ReactComponentModule>('../../../../pages/workspace/downgrade/PayAndDowngradePage').default,
     [SCREENS.WORKSPACE.MEMBER_DETAILS]: () => require<ReactComponentModule>('../../../../pages/workspace/members/WorkspaceMemberDetailsPage').default,
+    [SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE]: () => require<ReactComponentModule>('../../../../pages/workspace/members/WorkspaceMemberDetailsRolePage').default,
     [SCREENS.WORKSPACE.MEMBER_CUSTOM_FIELD]: () => require<ReactComponentModule>('../../../../pages/workspace/members/WorkspaceMemberCustomFieldPage').default,
     [SCREENS.WORKSPACE.MEMBER_NEW_CARD]: () => require<ReactComponentModule>('../../../../pages/workspace/members/WorkspaceMemberNewCardPage').default,
     [SCREENS.WORKSPACE.OWNER_CHANGE_CHECK]: () => require<ReactComponentModule>('@pages/workspace/members/WorkspaceOwnerChangeWrapperPage').default,
diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts
index 3bb9ceba4f8b..382a694c514b 100755
--- a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts
+++ b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts
@@ -15,6 +15,7 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
     ],
     [SCREENS.WORKSPACE.MEMBERS]: [
         SCREENS.WORKSPACE.MEMBER_DETAILS,
+        SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE,
         SCREENS.WORKSPACE.MEMBER_CUSTOM_FIELD,
         SCREENS.WORKSPACE.MEMBER_NEW_CARD,
         SCREENS.WORKSPACE.OWNER_CHANGE_CHECK,
diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts
index 06618b62dc7b..df73fe30292c 100644
--- a/src/libs/Navigation/linkingConfig/config.ts
+++ b/src/libs/Navigation/linkingConfig/config.ts
@@ -834,6 +834,9 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
                         [SCREENS.WORKSPACE.MEMBER_DETAILS]: {
                             path: ROUTES.WORKSPACE_MEMBER_DETAILS.route,
                         },
+                        [SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE]: {
+                            path: ROUTES.WORKSPACE_MEMBER_DETAILS_ROLE.route,
+                        },
                         [SCREENS.WORKSPACE.MEMBER_CUSTOM_FIELD]: {
                             path: ROUTES.WORKSPACE_CUSTOM_FIELDS.route,
                         },
diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts
index b2ef587a0955..7373ebbba9db 100644
--- a/src/libs/Navigation/types.ts
+++ b/src/libs/Navigation/types.ts
@@ -574,6 +574,10 @@ type SettingsNavigatorParamList = {
         policyID: string;
         accountID: string;
     };
+    [SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE]: {
+        policyID: string;
+        accountID: string;
+    };
     [SCREENS.WORKSPACE.MEMBER_CUSTOM_FIELD]: {
         policyID: string;
         accountID: string;
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx
index ac6798f24ee4..2f231567e1c2 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx
@@ -52,18 +52,9 @@ import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
 import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
 import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
 import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
-import type {ListItemType} from '@pages/workspace/WorkspaceMemberRoleSelectionModal';
-import WorkspaceMemberDetailsRoleSelectionModal from '@pages/workspace/WorkspaceMemberRoleSelectionModal';
 import variables from '@styles/variables';
 import {setIssueNewCardStepAndData} from '@userActions/Card';
-import {
-    clearWorkspaceOwnerChangeFlow,
-    isApprover as isApproverUserAction,
-    openPolicyMemberProfilePage,
-    removeMembers,
-    requestWorkspaceOwnerChange,
-    updateWorkspaceMembersRole,
-} from '@userActions/Policy/Member';
+import {clearWorkspaceOwnerChangeFlow, isApprover as isApproverUserAction, openPolicyMemberProfilePage, removeMembers, requestWorkspaceOwnerChange} from '@userActions/Policy/Member';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
@@ -96,7 +87,6 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM
     const expensifyCardSettings = useExpensifyCardFeeds(policyID);
 
     const [isRemoveMemberConfirmModalVisible, setIsRemoveMemberConfirmModalVisible] = useState(false);
-    const [isRoleSelectionModalVisible, setIsRoleSelectionModalVisible] = useState(false);
 
     const accountID = Number(route.params.accountID);
     const memberLogin = personalDetails?.[accountID]?.login ?? '';
@@ -189,37 +179,6 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM
         });
     }, [policy, memberLogin, details.login, isReimburser, translate, displayName, policyOwnerDisplayName]);
 
-    const roleItems: ListItemType[] = useMemo(() => {
-        const items: ListItemType[] = [
-            {
-                value: CONST.POLICY.ROLE.ADMIN,
-                text: translate('common.admin'),
-                alternateText: translate('workspace.common.adminAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.ADMIN,
-                keyForList: CONST.POLICY.ROLE.ADMIN,
-            },
-            {
-                value: CONST.POLICY.ROLE.AUDITOR,
-                text: translate('common.auditor'),
-                alternateText: translate('workspace.common.auditorAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.AUDITOR,
-                keyForList: CONST.POLICY.ROLE.AUDITOR,
-            },
-            {
-                value: CONST.POLICY.ROLE.USER,
-                text: translate('common.member'),
-                alternateText: translate('workspace.common.memberAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.USER,
-                keyForList: CONST.POLICY.ROLE.USER,
-            },
-        ];
-
-        if (isControlPolicy(policy)) {
-            return items;
-        }
-        return member?.role === CONST.POLICY.ROLE.AUDITOR ? items : items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
-    }, [member?.role, translate, policy]);
-
     useEffect(() => {
         if (!prevMember || prevMember?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || member?.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
             return;
@@ -327,20 +286,6 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM
         Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID, activeRoute));
     }, [accountID, hasMultipleFeeds, memberLogin, policyID, isAccountLocked, showLockedAccountModal]);
 
-    const openRoleSelectionModal = useCallback(() => {
-        setIsRoleSelectionModalVisible(true);
-    }, []);
-
-    const changeRole = useCallback(
-        ({value}: ListItemType) => {
-            setIsRoleSelectionModalVisible(false);
-            if (value !== member?.role) {
-                updateWorkspaceMembersRole(policyID, [memberLogin], [accountID], value);
-            }
-        },
-        [accountID, member?.role, memberLogin, policyID],
-    );
-
     const startChangeOwnershipFlow = useCallback(() => {
         clearWorkspaceOwnerChangeFlow(policyID);
         requestWorkspaceOwnerChange(policyID);
@@ -445,7 +390,7 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM
                                 title={translate(`workspace.common.roleName`, {role: member?.role})}
                                 description={translate('common.role')}
                                 shouldShowRightIcon
-                                onPress={openRoleSelectionModal}
+                                onPress={() => Navigation.navigate(ROUTES.WORKSPACE_MEMBER_DETAILS_ROLE.getRoute(policyID, accountID))}
                             />
                             {isControlPolicy(policy) && (
                                 <>
@@ -474,12 +419,6 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM
                                 onPress={navigateToProfile}
                                 shouldShowRightIcon
                             />
-                            <WorkspaceMemberDetailsRoleSelectionModal
-                                isVisible={isRoleSelectionModalVisible}
-                                items={roleItems}
-                                onRoleChange={changeRole}
-                                onClose={() => setIsRoleSelectionModalVisible(false)}
-                            />
                             {shouldShowCardsSection && (
                                 <>
                                     <View style={[styles.ph5, styles.pv3]}>
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
new file mode 100644
index 000000000000..7850c855dcf7
--- /dev/null
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -0,0 +1,115 @@
+import React, {useCallback, useMemo} from 'react';
+import {View} from 'react-native';
+import type {OnyxEntry} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import ScreenWrapper from '@components/ScreenWrapper';
+import SelectionList from '@components/SelectionList';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
+import type {ListItem} from '@components/SelectionList/types';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import {updateWorkspaceMembersRole} from '@libs/actions/Policy/Member';
+import Navigation from '@libs/Navigation/Navigation';
+import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
+import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
+import {isControlPolicy} from '@libs/PolicyUtils';
+import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
+import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
+import CONST from '@src/CONST';
+import type SCREENS from '@src/SCREENS';
+import type {PersonalDetailsList} from '@src/types/onyx';
+import AccessOrNotFoundWrapper from '../AccessOrNotFoundWrapper';
+
+type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
+    value: ValueOf<typeof CONST.POLICY.ROLE>;
+    text: string;
+    alternateText: string;
+    isSelected: boolean;
+};
+
+type WorkspaceMemberDetailsRolePageProps = Omit<WithPolicyAndFullscreenLoadingProps, 'route'> &
+    PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE> & {
+        /** Personal details of all users */
+        personalDetails: OnyxEntry<PersonalDetailsList>;
+    };
+
+function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: WorkspaceMemberDetailsRolePageProps) {
+    const {translate} = useLocalize();
+    const styles = useThemeStyles();
+    const accountID = Number(route.params.accountID);
+    const policyID = route.params.policyID;
+    const memberLogin = personalDetails?.[accountID]?.login ?? '';
+    const member = policy?.employeeList?.[memberLogin];
+
+    const roleItems: ListItemType[] = useMemo(() => {
+        const items: ListItemType[] = [
+            {
+                value: CONST.POLICY.ROLE.ADMIN,
+                text: translate('common.admin'),
+                alternateText: translate('workspace.common.adminAlternateText'),
+                isSelected: member?.role === CONST.POLICY.ROLE.ADMIN,
+                keyForList: CONST.POLICY.ROLE.ADMIN,
+            },
+            {
+                value: CONST.POLICY.ROLE.AUDITOR,
+                text: translate('common.auditor'),
+                alternateText: translate('workspace.common.auditorAlternateText'),
+                isSelected: member?.role === CONST.POLICY.ROLE.AUDITOR,
+                keyForList: CONST.POLICY.ROLE.AUDITOR,
+            },
+            {
+                value: CONST.POLICY.ROLE.USER,
+                text: translate('common.member'),
+                alternateText: translate('workspace.common.memberAlternateText'),
+                isSelected: member?.role === CONST.POLICY.ROLE.USER,
+                keyForList: CONST.POLICY.ROLE.USER,
+            },
+        ];
+
+        if (isControlPolicy(policy)) {
+            return items;
+        }
+        return member?.role === CONST.POLICY.ROLE.AUDITOR ? items : items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
+    }, [member?.role, translate, policy]);
+
+    const changeRole = useCallback(
+        ({value}: ListItemType) => {
+            if (value === member?.role) {
+                return;
+            }
+            updateWorkspaceMembersRole(policyID, [memberLogin], [accountID], value);
+            Navigation.goBack();
+        },
+        [accountID, member?.role, memberLogin, policyID],
+    );
+
+    return (
+        <AccessOrNotFoundWrapper
+            policyID={policyID}
+            accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
+        >
+            <ScreenWrapper
+                testID={WorkspaceMemberDetailsRolePage.displayName}
+                includePaddingTop={false}
+                enableEdgeToEdgeBottomSafeAreaPadding
+            >
+                <HeaderWithBackButton title={translate('common.role')} />
+                <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
+                    <SelectionList
+                        data={roleItems}
+                        ListItem={RadioListItem}
+                        onSelectRow={changeRole}
+                        shouldSingleExecuteRowSelect
+                        initiallyFocusedItemKey={roleItems.find((item) => item.isSelected)?.keyForList}
+                        addBottomSafeAreaPadding
+                    />
+                </View>
+            </ScreenWrapper>
+        </AccessOrNotFoundWrapper>
+    );
+}
+
+WorkspaceMemberDetailsRolePage.displayName = 'WorkspaceMemberDetailsRolePage';
+
+export default withPolicyAndFullscreenLoading(WorkspaceMemberDetailsRolePage);
diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx
index af306528aec6..2f5b48d990df 100644
--- a/src/pages/workspace/withPolicy.tsx
+++ b/src/pages/workspace/withPolicy.tsx
@@ -32,6 +32,7 @@ type PolicyRouteName =
     | typeof SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET
     | typeof SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY
     | typeof SCREENS.WORKSPACE.MEMBER_DETAILS
+    | typeof SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE
     | typeof SCREENS.WORKSPACE.MEMBER_CUSTOM_FIELD
     | typeof SCREENS.WORKSPACE.MEMBER_NEW_CARD
     | typeof SCREENS.WORKSPACE.INVOICES

From b184de4cafbefb14b0ec7e5e7e626f7749c4013e Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Fri, 5 Dec 2025 17:11:16 +0700
Subject: [PATCH 2/9] refactor: dry workspace role list

---
 src/components/WorkspaceMemberRoleList.tsx    | 90 +++++++++++++++++++
 .../WorkspaceInviteMessageRolePage.tsx        | 74 +++------------
 .../WorkspaceMemberDetailsRolePage.tsx        | 61 ++-----------
 3 files changed, 111 insertions(+), 114 deletions(-)
 create mode 100644 src/components/WorkspaceMemberRoleList.tsx

diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
new file mode 100644
index 000000000000..0fa0c824b232
--- /dev/null
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -0,0 +1,90 @@
+import React, {useMemo} from 'react';
+import {View} from 'react-native';
+import {OnyxEntry} from 'react-native-onyx';
+import {ValueOf} from 'type-fest';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@hooks/useThemeStyles';
+import Navigation from '@libs/Navigation/Navigation';
+import {isControlPolicy} from '@libs/PolicyUtils';
+import CONST from '@src/CONST';
+import {Route} from '@src/ROUTES';
+import {Policy} from '@src/types/onyx';
+import HeaderWithBackButton from './HeaderWithBackButton';
+import SelectionList from './SelectionList';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
+import {ListItem} from './SelectionList/types';
+
+type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
+    value: ValueOf<typeof CONST.POLICY.ROLE>;
+    text: string;
+    alternateText: string;
+    isSelected: boolean;
+};
+
+type WorkspaceMemberRoleListProps = {
+    role: string | undefined;
+    policy: OnyxEntry<Policy>;
+    navigateBackTo?: Route;
+    isLoading?: boolean;
+    onSelectRole?: (value: ListItemType) => void;
+};
+
+function WorkspaceMemberRoleList({role, policy, navigateBackTo = undefined, isLoading = false, onSelectRole = () => {}}: WorkspaceMemberRoleListProps) {
+    const {translate} = useLocalize();
+    const styles = useThemeStyles();
+
+    const roleItems: ListItemType[] = useMemo(() => {
+        const items: ListItemType[] = [
+            {
+                value: CONST.POLICY.ROLE.ADMIN,
+                text: translate('common.admin'),
+                alternateText: translate('workspace.common.adminAlternateText'),
+                isSelected: role === CONST.POLICY.ROLE.ADMIN,
+                keyForList: CONST.POLICY.ROLE.ADMIN,
+            },
+            {
+                value: CONST.POLICY.ROLE.AUDITOR,
+                text: translate('common.auditor'),
+                alternateText: translate('workspace.common.auditorAlternateText'),
+                isSelected: role === CONST.POLICY.ROLE.AUDITOR,
+                keyForList: CONST.POLICY.ROLE.AUDITOR,
+            },
+            {
+                value: CONST.POLICY.ROLE.USER,
+                text: translate('common.member'),
+                alternateText: translate('workspace.common.memberAlternateText'),
+                isSelected: role === CONST.POLICY.ROLE.USER,
+                keyForList: CONST.POLICY.ROLE.USER,
+            },
+        ];
+
+        if (!isControlPolicy(policy)) {
+            return items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
+        }
+        return items;
+    }, [role, translate, policy]);
+
+    return (
+        <>
+            <HeaderWithBackButton
+                title={translate('common.role')}
+                onBackButtonPress={() => Navigation.goBack(navigateBackTo)}
+            />
+            {!isLoading && (
+                <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
+                    <SelectionList
+                        data={roleItems}
+                        ListItem={RadioListItem}
+                        onSelectRow={onSelectRole}
+                        shouldSingleExecuteRowSelect
+                        initiallyFocusedItemKey={roleItems.find((item) => item.isSelected)?.keyForList}
+                        addBottomSafeAreaPadding
+                    />
+                </View>
+            )}
+        </>
+    );
+}
+
+WorkspaceMemberRoleList.displayName = 'WorkspaceMemberRoleList';
+export default WorkspaceMemberRoleList;
diff --git a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
index f8054aa3cb11..05bf97a0e5ec 100644
--- a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
+++ b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
@@ -1,20 +1,15 @@
-import React, {useMemo} from 'react';
-import {View} from 'react-native';
+import React from 'react';
 import type {ValueOf} from 'type-fest';
-import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import ScreenWrapper from '@components/ScreenWrapper';
-import SelectionList from '@components/SelectionList';
-import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
 import type {ListItem} from '@components/SelectionList/types';
-import useLocalize from '@hooks/useLocalize';
+import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList';
 import useOnyx from '@hooks/useOnyx';
-import useThemeStyles from '@hooks/useThemeStyles';
 import useViewportOffsetTop from '@hooks/useViewportOffsetTop';
 import {setWorkspaceInviteRoleDraft} from '@libs/actions/Policy/Member';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
-import {goBackFromInvalidPolicy, isControlPolicy} from '@libs/PolicyUtils';
+import {goBackFromInvalidPolicy} from '@libs/PolicyUtils';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type SCREENS from '@src/SCREENS';
@@ -34,45 +29,12 @@ type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
 type WorkspaceInviteMessageRolePageProps = WithPolicyAndFullscreenLoadingProps & PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE>;
 
 function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageRolePageProps) {
-    const styles = useThemeStyles();
-    const {translate} = useLocalize();
     const [role = CONST.POLICY.ROLE.USER, roleResult] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_ROLE_DRAFT}${route.params.policyID}`, {
         canBeMissing: true,
     });
     const viewportOffsetTop = useViewportOffsetTop();
     const isOnyxLoading = isLoadingOnyxValue(roleResult);
 
-    const roleItems: ListItemType[] = useMemo(() => {
-        const items: ListItemType[] = [
-            {
-                value: CONST.POLICY.ROLE.ADMIN,
-                text: translate('common.admin'),
-                alternateText: translate('workspace.common.adminAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.ADMIN,
-                keyForList: CONST.POLICY.ROLE.ADMIN,
-            },
-            {
-                value: CONST.POLICY.ROLE.AUDITOR,
-                text: translate('common.auditor'),
-                alternateText: translate('workspace.common.auditorAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.AUDITOR,
-                keyForList: CONST.POLICY.ROLE.AUDITOR,
-            },
-            {
-                value: CONST.POLICY.ROLE.USER,
-                text: translate('common.member'),
-                alternateText: translate('workspace.common.memberAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.USER,
-                keyForList: CONST.POLICY.ROLE.USER,
-            },
-        ];
-
-        if (!isControlPolicy(policy)) {
-            return items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
-        }
-        return items;
-    }, [role, translate, policy]);
-
     return (
         <AccessOrNotFoundWrapper
             policyID={route.params.policyID}
@@ -85,27 +47,17 @@ function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageR
                 shouldEnableMaxHeight
                 style={{marginTop: viewportOffsetTop}}
             >
-                <HeaderWithBackButton
-                    title={translate('common.role')}
-                    onBackButtonPress={() => Navigation.goBack(route.params.backTo)}
+                <WorkspaceMemberRoleList
+                    role={role}
+                    policy={policy}
+                    isLoading={isOnyxLoading}
+                    onSelectRole={({value}: ListItemType) => {
+                        setWorkspaceInviteRoleDraft(route.params.policyID, value);
+                        Navigation.setNavigationActionToMicrotaskQueue(() => {
+                            Navigation.goBack(route.params.backTo);
+                        });
+                    }}
                 />
-                {!isOnyxLoading && (
-                    <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
-                        <SelectionList
-                            data={roleItems}
-                            ListItem={RadioListItem}
-                            onSelectRow={({value}: ListItemType) => {
-                                setWorkspaceInviteRoleDraft(route.params.policyID, value);
-                                Navigation.setNavigationActionToMicrotaskQueue(() => {
-                                    Navigation.goBack(route.params.backTo);
-                                });
-                            }}
-                            shouldSingleExecuteRowSelect
-                            initiallyFocusedItemKey={roleItems.find((item) => item.isSelected)?.keyForList}
-                            addBottomSafeAreaPadding
-                        />
-                    </View>
-                )}
             </ScreenWrapper>
         </AccessOrNotFoundWrapper>
     );
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index 7850c855dcf7..b59fa1b38aaf 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -1,25 +1,19 @@
-import React, {useCallback, useMemo} from 'react';
-import {View} from 'react-native';
+import React, {useCallback} from 'react';
 import type {OnyxEntry} from 'react-native-onyx';
 import type {ValueOf} from 'type-fest';
-import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import ScreenWrapper from '@components/ScreenWrapper';
-import SelectionList from '@components/SelectionList';
-import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
 import type {ListItem} from '@components/SelectionList/types';
-import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
+import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList';
 import {updateWorkspaceMembersRole} from '@libs/actions/Policy/Member';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
 import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
-import {isControlPolicy} from '@libs/PolicyUtils';
+import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
 import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
 import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
 import CONST from '@src/CONST';
 import type SCREENS from '@src/SCREENS';
 import type {PersonalDetailsList} from '@src/types/onyx';
-import AccessOrNotFoundWrapper from '../AccessOrNotFoundWrapper';
 
 type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
     value: ValueOf<typeof CONST.POLICY.ROLE>;
@@ -35,44 +29,11 @@ type WorkspaceMemberDetailsRolePageProps = Omit<WithPolicyAndFullscreenLoadingPr
     };
 
 function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: WorkspaceMemberDetailsRolePageProps) {
-    const {translate} = useLocalize();
-    const styles = useThemeStyles();
     const accountID = Number(route.params.accountID);
     const policyID = route.params.policyID;
     const memberLogin = personalDetails?.[accountID]?.login ?? '';
     const member = policy?.employeeList?.[memberLogin];
 
-    const roleItems: ListItemType[] = useMemo(() => {
-        const items: ListItemType[] = [
-            {
-                value: CONST.POLICY.ROLE.ADMIN,
-                text: translate('common.admin'),
-                alternateText: translate('workspace.common.adminAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.ADMIN,
-                keyForList: CONST.POLICY.ROLE.ADMIN,
-            },
-            {
-                value: CONST.POLICY.ROLE.AUDITOR,
-                text: translate('common.auditor'),
-                alternateText: translate('workspace.common.auditorAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.AUDITOR,
-                keyForList: CONST.POLICY.ROLE.AUDITOR,
-            },
-            {
-                value: CONST.POLICY.ROLE.USER,
-                text: translate('common.member'),
-                alternateText: translate('workspace.common.memberAlternateText'),
-                isSelected: member?.role === CONST.POLICY.ROLE.USER,
-                keyForList: CONST.POLICY.ROLE.USER,
-            },
-        ];
-
-        if (isControlPolicy(policy)) {
-            return items;
-        }
-        return member?.role === CONST.POLICY.ROLE.AUDITOR ? items : items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
-    }, [member?.role, translate, policy]);
-
     const changeRole = useCallback(
         ({value}: ListItemType) => {
             if (value === member?.role) {
@@ -94,17 +55,11 @@ function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: Worksp
                 includePaddingTop={false}
                 enableEdgeToEdgeBottomSafeAreaPadding
             >
-                <HeaderWithBackButton title={translate('common.role')} />
-                <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
-                    <SelectionList
-                        data={roleItems}
-                        ListItem={RadioListItem}
-                        onSelectRow={changeRole}
-                        shouldSingleExecuteRowSelect
-                        initiallyFocusedItemKey={roleItems.find((item) => item.isSelected)?.keyForList}
-                        addBottomSafeAreaPadding
-                    />
-                </View>
+                <WorkspaceMemberRoleList
+                    role={member?.role}
+                    policy={policy}
+                    onSelectRole={changeRole}
+                />
             </ScreenWrapper>
         </AccessOrNotFoundWrapper>
     );

From b04fdee9d23d8776ed2b0c63858e6d832d0bed4a Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Fri, 5 Dec 2025 17:14:04 +0700
Subject: [PATCH 3/9] refactor types

---
 src/components/WorkspaceMemberRoleList.tsx             |  1 +
 src/pages/workspace/WorkspaceInviteMessageRolePage.tsx |  9 +--------
 .../members/WorkspaceMemberDetailsRolePage.tsx         | 10 +---------
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
index 0fa0c824b232..f249acb3f41b 100644
--- a/src/components/WorkspaceMemberRoleList.tsx
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -88,3 +88,4 @@ function WorkspaceMemberRoleList({role, policy, navigateBackTo = undefined, isLo
 
 WorkspaceMemberRoleList.displayName = 'WorkspaceMemberRoleList';
 export default WorkspaceMemberRoleList;
+export type {ListItemType};
diff --git a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
index 05bf97a0e5ec..95a65fd3d9e4 100644
--- a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
+++ b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
@@ -19,13 +19,6 @@ import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper';
 import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading';
 import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading';
 
-type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
-    value: ValueOf<typeof CONST.POLICY.ROLE>;
-    text: string;
-    alternateText: string;
-    isSelected: boolean;
-};
-
 type WorkspaceInviteMessageRolePageProps = WithPolicyAndFullscreenLoadingProps & PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE>;
 
 function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageRolePageProps) {
@@ -51,7 +44,7 @@ function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageR
                     role={role}
                     policy={policy}
                     isLoading={isOnyxLoading}
-                    onSelectRole={({value}: ListItemType) => {
+                    onSelectRole={({value}) => {
                         setWorkspaceInviteRoleDraft(route.params.policyID, value);
                         Navigation.setNavigationActionToMicrotaskQueue(() => {
                             Navigation.goBack(route.params.backTo);
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index b59fa1b38aaf..1e1de79a108e 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -1,9 +1,8 @@
 import React, {useCallback} from 'react';
 import type {OnyxEntry} from 'react-native-onyx';
-import type {ValueOf} from 'type-fest';
 import ScreenWrapper from '@components/ScreenWrapper';
-import type {ListItem} from '@components/SelectionList/types';
 import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList';
+import type {ListItemType} from '@components/WorkspaceMemberRoleList';
 import {updateWorkspaceMembersRole} from '@libs/actions/Policy/Member';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
@@ -15,13 +14,6 @@ import CONST from '@src/CONST';
 import type SCREENS from '@src/SCREENS';
 import type {PersonalDetailsList} from '@src/types/onyx';
 
-type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
-    value: ValueOf<typeof CONST.POLICY.ROLE>;
-    text: string;
-    alternateText: string;
-    isSelected: boolean;
-};
-
 type WorkspaceMemberDetailsRolePageProps = Omit<WithPolicyAndFullscreenLoadingProps, 'route'> &
     PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE> & {
         /** Personal details of all users */

From 1038904ed3234c6515676d58152195213ff51300 Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Fri, 5 Dec 2025 17:17:16 +0700
Subject: [PATCH 4/9] fix: lint

---
 src/components/WorkspaceMemberRoleList.tsx             | 10 +++++-----
 src/pages/workspace/WorkspaceInviteMessageRolePage.tsx |  2 --
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
index f249acb3f41b..dfa9001ad8ae 100644
--- a/src/components/WorkspaceMemberRoleList.tsx
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -1,18 +1,18 @@
 import React, {useMemo} from 'react';
 import {View} from 'react-native';
-import {OnyxEntry} from 'react-native-onyx';
-import {ValueOf} from 'type-fest';
+import type {OnyxEntry} from 'react-native-onyx';
+import type {ValueOf} from 'type-fest';
 import useLocalize from '@hooks/useLocalize';
 import useThemeStyles from '@hooks/useThemeStyles';
 import Navigation from '@libs/Navigation/Navigation';
 import {isControlPolicy} from '@libs/PolicyUtils';
 import CONST from '@src/CONST';
-import {Route} from '@src/ROUTES';
-import {Policy} from '@src/types/onyx';
+import type {Route} from '@src/ROUTES';
+import type {Policy} from '@src/types/onyx';
 import HeaderWithBackButton from './HeaderWithBackButton';
 import SelectionList from './SelectionList';
 import RadioListItem from './SelectionList/ListItem/RadioListItem';
-import {ListItem} from './SelectionList/types';
+import type {ListItem} from './SelectionList/types';
 
 type ListItemType = ListItem<ValueOf<typeof CONST.POLICY.ROLE>> & {
     value: ValueOf<typeof CONST.POLICY.ROLE>;
diff --git a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
index 95a65fd3d9e4..32e5cff9dbcc 100644
--- a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
+++ b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
@@ -1,7 +1,5 @@
 import React from 'react';
-import type {ValueOf} from 'type-fest';
 import ScreenWrapper from '@components/ScreenWrapper';
-import type {ListItem} from '@components/SelectionList/types';
 import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList';
 import useOnyx from '@hooks/useOnyx';
 import useViewportOffsetTop from '@hooks/useViewportOffsetTop';

From cc1878cd24d50af363675bbc3b0922b3fa19731d Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Tue, 9 Dec 2025 00:45:17 +0700
Subject: [PATCH 5/9] fix: add navigate back route

---
 src/pages/workspace/WorkspaceInviteMessageRolePage.tsx         | 1 +
 src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
index 32e5cff9dbcc..12234262599f 100644
--- a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
+++ b/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx
@@ -48,6 +48,7 @@ function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageR
                             Navigation.goBack(route.params.backTo);
                         });
                     }}
+                    navigateBackTo={route.params.backTo}
                 />
             </ScreenWrapper>
         </AccessOrNotFoundWrapper>
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index 1e1de79a108e..0ac3606df11f 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -11,6 +11,7 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
 import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
 import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
 import CONST from '@src/CONST';
+import ROUTES from '@src/ROUTES';
 import type SCREENS from '@src/SCREENS';
 import type {PersonalDetailsList} from '@src/types/onyx';
 
@@ -51,6 +52,7 @@ function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: Worksp
                     role={member?.role}
                     policy={policy}
                     onSelectRole={changeRole}
+                    navigateBackTo={ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(policyID, accountID)}
                 />
             </ScreenWrapper>
         </AccessOrNotFoundWrapper>

From 7c27a8ec0765061861443b7c365f039085c0113f Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Tue, 9 Dec 2025 00:46:53 +0700
Subject: [PATCH 6/9] fix: backto when select role

---
 src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index 0ac3606df11f..6bc0d0145e6f 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -33,7 +33,7 @@ function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: Worksp
                 return;
             }
             updateWorkspaceMembersRole(policyID, [memberLogin], [accountID], value);
-            Navigation.goBack();
+            Navigation.goBack(ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(policyID, accountID));
         },
         [accountID, member?.role, memberLogin, policyID],
     );

From 78c48de62fbb032fd5dbbf695df3fccd5edd5d4a Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Wed, 10 Dec 2025 17:15:38 +0700
Subject: [PATCH 7/9] fix: add padding top

---
 src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index 6bc0d0145e6f..c5b144251703 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -45,7 +45,6 @@ function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: Worksp
         >
             <ScreenWrapper
                 testID={WorkspaceMemberDetailsRolePage.displayName}
-                includePaddingTop={false}
                 enableEdgeToEdgeBottomSafeAreaPadding
             >
                 <WorkspaceMemberRoleList

From 8c985fda245496d47417b085611d5112e27eae5b Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Wed, 10 Dec 2025 18:00:40 +0700
Subject: [PATCH 8/9] fix: react compiler

---
 src/components/WorkspaceMemberRoleList.tsx    | 58 +++++++++----------
 .../WorkspaceMemberDetailsRolePage.tsx        | 19 +++---
 2 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
index dfa9001ad8ae..054114595c85 100644
--- a/src/components/WorkspaceMemberRoleList.tsx
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -33,36 +33,32 @@ function WorkspaceMemberRoleList({role, policy, navigateBackTo = undefined, isLo
     const {translate} = useLocalize();
     const styles = useThemeStyles();
 
-    const roleItems: ListItemType[] = useMemo(() => {
-        const items: ListItemType[] = [
-            {
-                value: CONST.POLICY.ROLE.ADMIN,
-                text: translate('common.admin'),
-                alternateText: translate('workspace.common.adminAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.ADMIN,
-                keyForList: CONST.POLICY.ROLE.ADMIN,
-            },
-            {
-                value: CONST.POLICY.ROLE.AUDITOR,
-                text: translate('common.auditor'),
-                alternateText: translate('workspace.common.auditorAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.AUDITOR,
-                keyForList: CONST.POLICY.ROLE.AUDITOR,
-            },
-            {
-                value: CONST.POLICY.ROLE.USER,
-                text: translate('common.member'),
-                alternateText: translate('workspace.common.memberAlternateText'),
-                isSelected: role === CONST.POLICY.ROLE.USER,
-                keyForList: CONST.POLICY.ROLE.USER,
-            },
-        ];
+    const workspaceRoles: ListItemType[] = [
+        {
+            value: CONST.POLICY.ROLE.ADMIN,
+            text: translate('common.admin'),
+            alternateText: translate('workspace.common.adminAlternateText'),
+            isSelected: role === CONST.POLICY.ROLE.ADMIN,
+            keyForList: CONST.POLICY.ROLE.ADMIN,
+        },
+        {
+            value: CONST.POLICY.ROLE.AUDITOR,
+            text: translate('common.auditor'),
+            alternateText: translate('workspace.common.auditorAlternateText'),
+            isSelected: role === CONST.POLICY.ROLE.AUDITOR,
+            keyForList: CONST.POLICY.ROLE.AUDITOR,
+        },
+        {
+            value: CONST.POLICY.ROLE.USER,
+            text: translate('common.member'),
+            alternateText: translate('workspace.common.memberAlternateText'),
+            isSelected: role === CONST.POLICY.ROLE.USER,
+            keyForList: CONST.POLICY.ROLE.USER,
+        },
+    ];
 
-        if (!isControlPolicy(policy)) {
-            return items.filter((item) => item.value !== CONST.POLICY.ROLE.AUDITOR);
-        }
-        return items;
-    }, [role, translate, policy]);
+    const isPolicyControl = isControlPolicy(policy);
+    const availableRoleItems: ListItemType[] = workspaceRoles.filter((item) => isPolicyControl || item.value !== CONST.POLICY.ROLE.AUDITOR);
 
     return (
         <>
@@ -73,11 +69,11 @@ function WorkspaceMemberRoleList({role, policy, navigateBackTo = undefined, isLo
             {!isLoading && (
                 <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
                     <SelectionList
-                        data={roleItems}
+                        data={availableRoleItems}
                         ListItem={RadioListItem}
                         onSelectRow={onSelectRole}
                         shouldSingleExecuteRowSelect
-                        initiallyFocusedItemKey={roleItems.find((item) => item.isSelected)?.keyForList}
+                        initiallyFocusedItemKey={availableRoleItems.find((item) => item.isSelected)?.keyForList}
                         addBottomSafeAreaPadding
                     />
                 </View>
diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
index c5b144251703..30e2f088279d 100644
--- a/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
+++ b/src/pages/workspace/members/WorkspaceMemberDetailsRolePage.tsx
@@ -1,4 +1,4 @@
-import React, {useCallback} from 'react';
+import React from 'react';
 import type {OnyxEntry} from 'react-native-onyx';
 import ScreenWrapper from '@components/ScreenWrapper';
 import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList';
@@ -27,16 +27,13 @@ function WorkspaceMemberDetailsRolePage({policy, personalDetails, route}: Worksp
     const memberLogin = personalDetails?.[accountID]?.login ?? '';
     const member = policy?.employeeList?.[memberLogin];
 
-    const changeRole = useCallback(
-        ({value}: ListItemType) => {
-            if (value === member?.role) {
-                return;
-            }
-            updateWorkspaceMembersRole(policyID, [memberLogin], [accountID], value);
-            Navigation.goBack(ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(policyID, accountID));
-        },
-        [accountID, member?.role, memberLogin, policyID],
-    );
+    const changeRole = ({value}: ListItemType) => {
+        if (value === member?.role) {
+            return;
+        }
+        updateWorkspaceMembersRole(policyID, [memberLogin], [accountID], value);
+        Navigation.goBack(ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(policyID, accountID));
+    };
 
     return (
         <AccessOrNotFoundWrapper

From fb6756dfd6c2c464e79c33287e5077df2f3610fe Mon Sep 17 00:00:00 2001
From: mkzie2 <mkzie2@gmail.com>
Date: Wed, 10 Dec 2025 18:01:02 +0700
Subject: [PATCH 9/9] fix: remove unused hook

---
 src/components/WorkspaceMemberRoleList.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
index 054114595c85..44983c756bd6 100644
--- a/src/components/WorkspaceMemberRoleList.tsx
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -1,4 +1,4 @@
-import React, {useMemo} from 'react';
+import React from 'react';
 import {View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import type {ValueOf} from 'type-fest';
