diff --git a/src/components/Roles/RoleDetails.tsx b/src/components/Roles/RoleDetails.tsx new file mode 100644 index 000000000..d0e88589a --- /dev/null +++ b/src/components/Roles/RoleDetails.tsx @@ -0,0 +1,238 @@ +import { Badge, Box, Flex, Grid, GridItem, Icon, Text } from '@chakra-ui/react'; +import { CheckSquare, List, User } from '@phosphor-icons/react'; +import { RefObject, useMemo, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; +import PencilWithLineIcon from '../../assets/theme/custom/icons/PencilWithLineIcon'; +import { DAO_ROUTES } from '../../constants/routes'; +import useAddress from '../../hooks/utils/useAddress'; +import useAvatar from '../../hooks/utils/useAvatar'; +import { useCanUserCreateProposal } from '../../hooks/utils/useCanUserSubmitProposal'; +import { useCopyText } from '../../hooks/utils/useCopyText'; +import { useGetAccountName } from '../../hooks/utils/useGetAccountName'; +import { useNetworkConfig } from '../../providers/NetworkConfig/NetworkConfigProvider'; +import { useDaoInfoStore } from '../../store/daoInfo/useDaoInfoStore'; +import { + paymentSorterByActiveStatus, + paymentSorterByStartDate, + paymentSorterByWithdrawAmount, +} from '../../store/roles/rolesStoreUtils'; +import { + RoleDetailsDrawerEditingRoleHatProp, + RoleDetailsDrawerRoleHatProp, +} from '../../types/roles'; +import { BarLoader } from '../ui/loaders/BarLoader'; +import ModalTooltip from '../ui/modals/ModalTooltip'; +import Avatar from '../ui/page/Header/Avatar'; +import PageHeader from '../ui/page/Header/PageHeader'; +import Markdown from '../ui/proposal/Markdown'; +import Divider from '../ui/utils/Divider'; +import RoleDetailsTabs from './RoleDetailsTabs'; + +export function RoleProposalPermissionBadge({ + containerRef, +}: { + containerRef: RefObject; +}) { + const { t } = useTranslation('roles'); + return ( + + + {t('permissionsProposals')} + + + ); +} +function RoleAndDescriptionLabel({ label, icon }: { label: string; icon: React.ElementType }) { + return ( + + + + {label} + + + ); +} + +export default function RolesDetails({ + roleHat, +}: { + roleHat: RoleDetailsDrawerRoleHatProp | RoleDetailsDrawerEditingRoleHatProp; +}) { + const { safe } = useDaoInfoStore(); + const navigate = useNavigate(); + const { addressPrefix } = useNetworkConfig(); + const permissionsContainerRef = useRef(null); + + const roleHatWearer = 'wearer' in roleHat ? roleHat.wearer : roleHat.wearerAddress; + + const { address: roleHatWearerAddress, isLoading: loadingRoleHatWearerAddress } = + useAddress(roleHatWearer); + + const { displayName } = useGetAccountName(roleHatWearerAddress); + + const { t } = useTranslation(['roles']); + const avatarURL = useAvatar(roleHatWearer); + + const sortedPayments = useMemo( + () => + roleHat.payments + ? [...roleHat.payments] + .sort(paymentSorterByWithdrawAmount) + .sort(paymentSorterByStartDate) + .sort(paymentSorterByActiveStatus) + : [], + [roleHat.payments], + ); + + const { canUserCreateProposal } = useCanUserCreateProposal(); + const copyToClipboard = useCopyText(); + + if (!safe?.address) return null; + + return ( + <> + + + + ), + gap: 0, + children: t('editRoles'), + onClick: () => navigate(DAO_ROUTES.rolesEdit.relative(addressPrefix, safe.address)), + } + : undefined + } + /> + + {roleHat.name} + + + + + + + + + + {roleHat.canCreateProposals && ( + + )} + + + copyToClipboard(roleHatWearerAddress)} + > + {loadingRoleHatWearerAddress || !roleHatWearerAddress ? ( + + ) : ( + + )} + {displayName} + + + + + + + {roleHat.canCreateProposals && ( + + )} + + + + + + ); +} diff --git a/src/pages/dao/roles/details/SafeRoleDetailsPage.tsx b/src/pages/dao/roles/details/SafeRoleDetailsPage.tsx index 51789f8f3..a2ced722c 100644 --- a/src/pages/dao/roles/details/SafeRoleDetailsPage.tsx +++ b/src/pages/dao/roles/details/SafeRoleDetailsPage.tsx @@ -1,16 +1,11 @@ -import { Show } from '@chakra-ui/react'; -import { useNavigate, useSearchParams } from 'react-router-dom'; -import RolesDetailsDrawer from '../../../../components/Roles/RolesDetailsDrawer'; -import RolesDetailsDrawerMobile from '../../../../components/Roles/RolesDetailsDrawerMobile'; -import { DAO_ROUTES } from '../../../../constants/routes'; -import { useNetworkConfig } from '../../../../providers/NetworkConfig/NetworkConfigProvider'; +import { useSearchParams } from 'react-router-dom'; +import RolesDetails from '../../../../components/Roles/RoleDetails'; + import { useDaoInfoStore } from '../../../../store/daoInfo/useDaoInfoStore'; import { useRolesStore } from '../../../../store/roles/useRolesStore'; export function SafeRoleDetailsPage() { const { safe } = useDaoInfoStore(); - const navigate = useNavigate(); - const { addressPrefix } = useNetworkConfig(); const { hatsTree } = useRolesStore(); const [searchParams] = useSearchParams(); @@ -21,31 +16,6 @@ export function SafeRoleDetailsPage() { // @todo add logic for loading // @todo add redirect for hat not found if (!roleHat || !safeAddress) return null; - const handleDrawerClose = () => { - navigate(DAO_ROUTES.roles.relative(addressPrefix, safeAddress), { replace: true }); - }; - const handleEditRoleClick = () => { - navigate(DAO_ROUTES.rolesEditDetails.relative(addressPrefix, safeAddress, roleHat.id), { - replace: true, - }); - }; - return ( - <> - - - - - - - - ); + return ; } diff --git a/src/router.tsx b/src/router.tsx index f17ec215c..b39abde96 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -83,8 +83,11 @@ export const router = (addressPrefix: string, daoAddress: string | undefined) => }, { path: DAO_ROUTES.roles.path, - element: , children: [ + { + index: true, + element: , + }, { path: 'details', element: ,