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/components/Roles/forms/RoleFormCreateProposal.tsx b/src/components/Roles/forms/RoleFormCreateProposal.tsx index 97a91d619..8c19af9c5 100644 --- a/src/components/Roles/forms/RoleFormCreateProposal.tsx +++ b/src/components/Roles/forms/RoleFormCreateProposal.tsx @@ -132,13 +132,12 @@ export function RoleFormCreateProposal({ close }: { close: () => void }) { }; return ( - + 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/pages/dao/roles/edit/summary/SafeRolesEditProposalSummaryPage.tsx b/src/pages/dao/roles/edit/summary/SafeRolesEditProposalSummaryPage.tsx index 3ab44699b..f3da8732d 100644 --- a/src/pages/dao/roles/edit/summary/SafeRolesEditProposalSummaryPage.tsx +++ b/src/pages/dao/roles/edit/summary/SafeRolesEditProposalSummaryPage.tsx @@ -1,19 +1,17 @@ -import { Box, Flex, Icon, Portal, Show, Text } from '@chakra-ui/react'; -import { ArrowLeft } from '@phosphor-icons/react'; +import { Box, Flex } from '@chakra-ui/react'; import { useFormikContext } from 'formik'; import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { RoleFormCreateProposal } from '../../../../../components/Roles/forms/RoleFormCreateProposal'; import PageHeader from '../../../../../components/ui/page/Header/PageHeader'; -import { SIDEBAR_WIDTH, useFooterHeight, useHeaderHeight } from '../../../../../constants/common'; +import { CONTENT_MAXW } from '../../../../../constants/common'; import { DAO_ROUTES } from '../../../../../constants/routes'; import { useNetworkConfig } from '../../../../../providers/NetworkConfig/NetworkConfigProvider'; import { useDaoInfoStore } from '../../../../../store/daoInfo/useDaoInfoStore'; import { RoleFormValues } from '../../../../../types/roles'; export function SafeRolesEditProposalSummaryPage() { - const headerHeight = useHeaderHeight(); const navigate = useNavigate(); const { safe } = useDaoInfoStore(); const { t } = useTranslation(['roles', 'breadcrumbs']); @@ -22,8 +20,6 @@ export function SafeRolesEditProposalSummaryPage() { const safeAddress = safe?.address; - const footerHeight = useFooterHeight(); - // @dev redirects back to roles edit page if no roles are edited (user refresh) useEffect(() => { const editedRoles = values.hats.filter(hat => !!hat.editedRole); @@ -35,74 +31,24 @@ export function SafeRolesEditProposalSummaryPage() { if (!safeAddress) return null; return ( - - - - - - { - navigate(DAO_ROUTES.rolesEdit.relative(addressPrefix, safeAddress)); - }} - > - - {t('proposalNew', { ns: 'breadcrumbs' })} - - - navigate(DAO_ROUTES.rolesEdit.relative(addressPrefix, safeAddress))} - /> - - - - - - - - navigate(DAO_ROUTES.rolesEdit.relative(addressPrefix, safeAddress))} - /> - - - + + + + navigate(DAO_ROUTES.rolesEdit.relative(addressPrefix, safeAddress))} + /> + ); } 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: ,