From d1e7760e1ecbcb3875c83901649225fdc7944642 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 16 Aug 2024 17:37:39 -0700 Subject: [PATCH 1/5] basic mobile adjustments --- src/components/feed/RichTextUpdate.tsx | 4 +- src/components/grant/ApplicationDisplay.tsx | 5 +- src/components/grant/InsetUpdate.tsx | 11 +++-- src/components/grant/MilestoneDisplay.tsx | 5 +- src/components/grant/MilestoneSetDisplay.tsx | 5 +- src/components/grant/NextStep.tsx | 4 +- src/components/grant/TopSection.tsx | 51 +++++++++++--------- src/components/grant/UserUpdate.tsx | 4 +- src/utils/config.ts | 1 + src/utils/helpers.ts | 7 +++ 10 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/components/feed/RichTextUpdate.tsx b/src/components/feed/RichTextUpdate.tsx index 9f6accbc..1b2e5cf2 100644 --- a/src/components/feed/RichTextUpdate.tsx +++ b/src/components/feed/RichTextUpdate.tsx @@ -2,7 +2,7 @@ import { MainSection, PageTitle } from '../../layout/Sections'; import { useQuery } from '@tanstack/react-query'; import { useParams } from 'react-router-dom'; import { getBuiltGraphSDK } from '../../.graphclient'; -import { useChainId } from 'wagmi'; +import { useChainId, useConfig } from 'wagmi'; import { resolveProjectMetadata } from '../../resolvers/projectResolvers'; import { Box, Divider, Group, Skeleton, Text } from '@mantine/core'; import { resolveRichTextMetadata } from '../../resolvers/updates'; @@ -16,7 +16,7 @@ import { Player } from '../../types/ui'; import { getGatewayUrl } from '../../utils/ipfs/get'; import { DAO_MASONS } from '../../constants/gameSetup'; -export const getRTUpdate = async (id: string, chainId: number) => { +const getRTUpdate = async (id: string, chainId: number) => { const { getRTUpdate } = getBuiltGraphSDK(); const { Update } = await getRTUpdate({ diff --git a/src/components/grant/ApplicationDisplay.tsx b/src/components/grant/ApplicationDisplay.tsx index 4024ee82..0c9ba1be 100644 --- a/src/components/grant/ApplicationDisplay.tsx +++ b/src/components/grant/ApplicationDisplay.tsx @@ -33,6 +33,7 @@ import { GameStatus } from '../../types/common'; import classes from '../../styles/Spoiler.module.css'; import { ApplicationVerdictControls } from './ApplicationVerdictControls'; import { useMemo } from 'react'; +import { useMobile } from '../../hooks/useBreakpoint'; export const ApplicationDisplay = ({ amountRequested, @@ -56,6 +57,8 @@ export const ApplicationDisplay = ({ const theme = useMantineTheme(); const { project, grant, isShipOperator } = useGrant(); + const isMobile = useMobile(); + const formattedTime = secondsToLongDate(dueDate); const formattedAmount = formatEther(BigInt(amountRequested)); @@ -135,7 +138,7 @@ export const ApplicationDisplay = ({ )} - + { + const isMobile = useMobile(); + const time = useMemo(() => { if (!timestamp) return ''; return secondsToShortRelativeTime(timestamp); }, [timestamp]); return ( <> - - + + {symbolUI} {posterName} {tagline} @@ -34,7 +37,7 @@ export const InsetUpdate = ({ {time} - + {bodyUI} diff --git a/src/components/grant/MilestoneDisplay.tsx b/src/components/grant/MilestoneDisplay.tsx index 9bf5e281..aff9de22 100644 --- a/src/components/grant/MilestoneDisplay.tsx +++ b/src/components/grant/MilestoneDisplay.tsx @@ -22,6 +22,7 @@ import { formatEther } from 'viem'; import { secondsToLongDate } from '../../utils/time'; import { RTDisplay } from '../RTDisplay'; import { MilestoneVerdictControls } from './MilestoneVerdictControls'; +import { useMobile } from '../../hooks/useBreakpoint'; export const MilestoneDisplay = ({ updateData, @@ -29,6 +30,8 @@ export const MilestoneDisplay = ({ updateData: GrantUpdate; }) => { const theme = useMantineTheme(); + const isMobile = useMobile(); + const { currentMilestoneSet, project, isShipOperator } = useGrant(); const milestoneId = updateData.id.split(':')[0]; @@ -88,7 +91,7 @@ export const MilestoneDisplay = ({ - + { const theme = useMantineTheme(); + const isMobile = useMobile(); + const { status, id, resolvedMilestones } = doc; const { project, grant, isShipOperator } = useGrant(); @@ -135,7 +138,7 @@ export const MilestoneSetDisplay = ({ doc }: { doc: MilestonesDisplay }) => { - + { + const isMobile = useMobile(); return ( - + {icon} {text} diff --git a/src/components/grant/TopSection.tsx b/src/components/grant/TopSection.tsx index 42e59ff5..6060014a 100644 --- a/src/components/grant/TopSection.tsx +++ b/src/components/grant/TopSection.tsx @@ -9,7 +9,7 @@ import { Tooltip, useMantineTheme, } from '@mantine/core'; -import { useBreakpoints } from '../../hooks/useBreakpoint'; +import { useBreakpoints, useMobile } from '../../hooks/useBreakpoint'; import { useGrant } from '../../hooks/useGrant'; import { IconCircle, @@ -21,6 +21,7 @@ import { ReactNode } from 'react'; import { GameStatus, GrantStatus } from '../../types/common'; import { Link } from 'react-router-dom'; import { formatEther } from 'viem'; +import { charLimit } from '../../utils/helpers'; export const TopSection = () => { const { project, ship, isLoadingGrant, grant } = useGrant(); @@ -70,35 +71,33 @@ export const TopSection = () => { {isLoadingGrant ? ( ) : ( - - - {shipName} - - + + + + {shipName ? charLimit(shipName, 18) : ''} + + {/* */} + {/* */} {' <> '} - - */} + {/* - {projectName} + > */} + + + {projectName} + )} @@ -147,7 +146,11 @@ export const TopSection = () => { px={8} py={2} bg={theme.colors.dark[8]} - style={{ borderRadius: '6px' }} + style={{ + borderRadius: '6px', + flexDirection: isTablet ? 'column' : 'row', + alignItems: 'start', + }} > diff --git a/src/components/grant/UserUpdate.tsx b/src/components/grant/UserUpdate.tsx index 6f2540dc..63a63274 100644 --- a/src/components/grant/UserUpdate.tsx +++ b/src/components/grant/UserUpdate.tsx @@ -8,6 +8,7 @@ import { ReactNode, useMemo } from 'react'; import { Player } from '../../types/ui'; import { RTDisplay } from '../RTDisplay'; import { Content } from '@tiptap/react'; +import { useMobile } from '../../hooks/useBreakpoint'; export const UserUpdate = ({ content, @@ -24,6 +25,7 @@ export const UserUpdate = ({ timestamp: number; innerUI?: ReactNode; }) => { + const isMobile = useMobile(); const time = useMemo(() => { if (!timestamp) return ''; return secondsToShortRelativeTime(timestamp); @@ -48,7 +50,7 @@ export const UserUpdate = ({ )} - + {innerUI} diff --git a/src/utils/config.ts b/src/utils/config.ts index fa33017b..5f131186 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -5,6 +5,7 @@ import { safe, walletConnect } from 'wagmi/connectors'; export const appNetwork = import.meta.env.VITE_RUNTIME_ENV === 'dev' ? arbitrumSepolia : arbitrum; + const appRpc = import.meta.env.VITE_RUNTIME_ENV === 'dev' ? import.meta.env.VITE_RPC_URL_TESTNET diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 82030346..32461f68 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -77,3 +77,10 @@ export const formatBigIntPercentage = ( displayDecimals ); }; + +export const charLimit = (str: string, limit = 18): string => { + if (str.length > limit) { + return str.slice(0, limit) + '...'; + } + return str; +}; From a0bd4b609912279000f094643292defddb4ff447 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 16 Aug 2024 18:16:35 -0700 Subject: [PATCH 2/5] actions buttons in mobile that looks like ass --- src/components/grant/FacilitatorActions.tsx | 51 ++++++- src/components/grant/ProjectActions.tsx | 145 +++++++++++++++++++- src/components/grant/ShipActions.tsx | 32 ++++- src/components/grant/TopSection.tsx | 16 +-- src/pages/Grant.tsx | 47 ++++++- 5 files changed, 268 insertions(+), 23 deletions(-) diff --git a/src/components/grant/FacilitatorActions.tsx b/src/components/grant/FacilitatorActions.tsx index a796b9b6..340f8a21 100644 --- a/src/components/grant/FacilitatorActions.tsx +++ b/src/components/grant/FacilitatorActions.tsx @@ -1,4 +1,4 @@ -import { Button, Stack, Text } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { IconPlus } from '@tabler/icons-react'; import { FacilitatorApprovalDrawer } from './FacilitatorApprovalDrawer'; @@ -50,3 +50,52 @@ export const FacilitatorActions = () => { ); }; + +export const FacActionsMobile = () => { + const [approvalOpened, { open: openApprove, close: closeApprove }] = + useDisclosure(); + const [postOpened, { open: openPost, close: closePost }] = useDisclosure(); + + const { grant, project, ship, refetchGrant } = useGrant(); + + const isReadyToApprove = grant?.status === GrantStatus.MilestonesApproved; + + return ( + <> + + {isReadyToApprove && ( + + )} + + + + + + ); +}; diff --git a/src/components/grant/ProjectActions.tsx b/src/components/grant/ProjectActions.tsx index 81ec8a45..61247ae9 100644 --- a/src/components/grant/ProjectActions.tsx +++ b/src/components/grant/ProjectActions.tsx @@ -1,7 +1,7 @@ import { useDisclosure } from '@mantine/hooks'; import { useGrant } from '../../hooks/useGrant'; import { GameStatus, GrantStatus } from '../../types/common'; -import { Button, Stack, Text } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { IconPencil, IconPlus } from '@tabler/icons-react'; import { ApplicationDrawer } from './ApplicationDrawer'; import { formatEther } from 'viem'; @@ -143,3 +143,146 @@ export const ProjectActions = () => { ); }; + +export const ProjectActionsMobile = () => { + const { + project, + ship, + refetchGrant, + applicationTemplate, + grant, + currentApplication, + } = useGrant(); + const [postOpened, { open: openPost, close: closePost }] = useDisclosure(); + const [ + applicationOpened, + { open: openApplication, close: closeApplication }, + ] = useDisclosure(); + const [milestonesOpened, { open: openMilestones, close: closeMilestones }] = + useDisclosure(); + + const isApplicationStage = + !grant || (grant?.status && grant.status < GrantStatus.MilestonesApproved); + + const isMilestonePlanning = + grant?.status && + grant.status >= GrantStatus.ApplicationApproved && + grant?.status < GrantStatus.MilestonesApproved; + + const areMilestonesLocked = + grant?.status && + grant.status === GrantStatus.Allocated && + grant?.currentMilestones?.status === GameStatus.Accepted; + + const alreadyHasApplication = !!currentApplication; + const alreadyHasMilestoneSet = !!grant?.currentMilestones; + + return ( + <> + + {isApplicationStage && alreadyHasApplication && ( + + )} + + {isMilestonePlanning && ( + + )} + {areMilestonesLocked && ( + + )} + {isApplicationStage && !alreadyHasApplication && ( + + )} + + + {alreadyHasApplication ? ( + + ) : ( + + )} + + {areMilestonesLocked ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/components/grant/ShipActions.tsx b/src/components/grant/ShipActions.tsx index b1f0d1a6..a2db2935 100644 --- a/src/components/grant/ShipActions.tsx +++ b/src/components/grant/ShipActions.tsx @@ -1,6 +1,6 @@ import { useDisclosure } from '@mantine/hooks'; import { useGrant } from '../../hooks/useGrant'; -import { Button, Stack, Text } from '@mantine/core'; +import { Button, Group, Stack, Text } from '@mantine/core'; import { IconPlus } from '@tabler/icons-react'; import { PostGrantDrawer } from './PostGrantDrawer'; import { Player } from '../../types/ui'; @@ -29,3 +29,33 @@ export const ShipActions = () => { ); }; + +export const ShipActionsMobile = () => { + const { refetchGrant, project, ship } = useGrant(); + const [postOpened, { open: openPost, close: closePost }] = useDisclosure(); + + return ( + <> + + + + + + ); +}; diff --git a/src/components/grant/TopSection.tsx b/src/components/grant/TopSection.tsx index 6060014a..04826e3d 100644 --- a/src/components/grant/TopSection.tsx +++ b/src/components/grant/TopSection.tsx @@ -9,7 +9,7 @@ import { Tooltip, useMantineTheme, } from '@mantine/core'; -import { useBreakpoints, useMobile } from '../../hooks/useBreakpoint'; +import { useBreakpoints } from '../../hooks/useBreakpoint'; import { useGrant } from '../../hooks/useGrant'; import { IconCircle, @@ -79,24 +79,12 @@ export const TopSection = () => { > {shipName ? charLimit(shipName, 18) : ''} - {/* */} - {/* */} {' <> '} - {/* */} - {/* */} - - {projectName} + {projectName ? charLimit(projectName, 18) : ''} diff --git a/src/pages/Grant.tsx b/src/pages/Grant.tsx index ab671b15..afec531b 100644 --- a/src/pages/Grant.tsx +++ b/src/pages/Grant.tsx @@ -1,5 +1,11 @@ import { MainSection, PageTitle } from '../layout/Sections'; -import { Center, Flex, SegmentedControl, useMantineTheme } from '@mantine/core'; +import { + Center, + Flex, + Group, + SegmentedControl, + useMantineTheme, +} from '@mantine/core'; import { useBreakpoints } from '../hooks/useBreakpoint'; import { Route, @@ -18,15 +24,24 @@ import { GrantContextProvider } from '../contexts/GrantContext'; import { useGrant } from '../hooks/useGrant'; import { GrantTimeline } from '../components/grant/GrantTimeline'; import { useUserData } from '../hooks/useUserState'; -import { ProjectActions } from '../components/grant/ProjectActions'; -import { FacilitatorActions } from '../components/grant/FacilitatorActions'; -import { ShipActions } from '../components/grant/ShipActions'; +import { + ProjectActions, + ProjectActionsMobile, +} from '../components/grant/ProjectActions'; +import { + FacActionsMobile, + FacilitatorActions, +} from '../components/grant/FacilitatorActions'; +import { + ShipActions, + ShipActionsMobile, +} from '../components/grant/ShipActions'; import { GrantApplication } from '../components/grant/GrantApplication'; import { GrantMilestones } from '../components/grant/GrantMilestones'; export const Grant = () => { const theme = useMantineTheme(); - const { isMobile } = useBreakpoints(); + const { isMobile, isLaptop } = useBreakpoints(); const navigate = useNavigate(); const { id } = useParams(); @@ -39,6 +54,8 @@ export const Grant = () => { + + { ]} onChange={(value) => navigate(`/grant/${id}/${value}`)} /> + } /> } /> @@ -83,7 +101,6 @@ export const Grant = () => { } /> - ); @@ -106,3 +123,21 @@ const ActionsPanel = () => { ); }; + +const ActionsPanelMobile = () => { + const { userData } = useUserData(); + + const { isFacilitator } = userData || {}; + const { isProjectMember, isShipOperator } = useGrant(); + return ( + + {isFacilitator ? ( + + ) : isShipOperator ? ( + + ) : isProjectMember ? ( + + ) : null} + + ); +}; From 6ae1ebe723c663733973b745bc48513542997b20 Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 16 Aug 2024 18:26:00 -0700 Subject: [PATCH 3/5] clean up mobile controls --- src/pages/Grant.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/Grant.tsx b/src/pages/Grant.tsx index afec531b..cdbc2799 100644 --- a/src/pages/Grant.tsx +++ b/src/pages/Grant.tsx @@ -38,10 +38,13 @@ import { } from '../components/grant/ShipActions'; import { GrantApplication } from '../components/grant/GrantApplication'; import { GrantMilestones } from '../components/grant/GrantMilestones'; +import { useMediaQuery } from '@mantine/hooks'; export const Grant = () => { const theme = useMantineTheme(); - const { isMobile, isLaptop } = useBreakpoints(); + const { isMobile } = useBreakpoints(); + + const isObstructed = useMediaQuery(`(max-width: 1064px`); const navigate = useNavigate(); const { id } = useParams(); @@ -54,7 +57,7 @@ export const Grant = () => { - + {isObstructed && } { } /> + {!isObstructed && } ); From 48cde11696ccc4060c667034767810bf3b18788f Mon Sep 17 00:00:00 2001 From: jordan Date: Fri, 16 Aug 2024 18:58:51 -0700 Subject: [PATCH 4/5] show grants in mobile nav --- src/layout/DesktopNav/GrantsNavSection.tsx | 3 ++ src/layout/MobileNav/MobileNav.tsx | 61 ++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/layout/DesktopNav/GrantsNavSection.tsx b/src/layout/DesktopNav/GrantsNavSection.tsx index 4e38f083..5ef35c3b 100644 --- a/src/layout/DesktopNav/GrantsNavSection.tsx +++ b/src/layout/DesktopNav/GrantsNavSection.tsx @@ -5,6 +5,7 @@ import { Divider, Flex, Group, + Menu, Text, useMantineTheme, } from '@mantine/core'; @@ -16,6 +17,8 @@ import { GAME_MANAGER } from '../../constants/gameSetup'; import { Address } from 'viem'; import { Link, useLocation } from 'react-router-dom'; import classes from './DesktoNavStyles.module.css'; +import { useState } from 'react'; +import { IconChevronUp } from '@tabler/icons-react'; export const GrantsNavSection = () => { const { address } = useAccount(); diff --git a/src/layout/MobileNav/MobileNav.tsx b/src/layout/MobileNav/MobileNav.tsx index 8f23d741..2c4c4c99 100644 --- a/src/layout/MobileNav/MobileNav.tsx +++ b/src/layout/MobileNav/MobileNav.tsx @@ -1,8 +1,12 @@ import { + Avatar, + AvatarGroup, Box, Button, + Divider, Flex, Menu, + MenuItem, Modal, Stack, Text, @@ -30,6 +34,11 @@ import { import { notifications } from '@mantine/notifications'; import { useUserData } from '../../hooks/useUserState'; +import { getAllUserGrants } from '../../queries/getProjectGrants'; +import { GAME_MANAGER } from '../../constants/gameSetup'; +import { Address } from 'viem'; +import { useQuery } from '@tanstack/react-query'; + export const MobileNav = () => { const theme = useMantineTheme(); const location = useLocation(); @@ -40,6 +49,16 @@ export const MobileNav = () => { const [menuOpen, setMenuOpen] = useState(false); + const { + data: grants, + isLoading, + error, + } = useQuery({ + queryKey: ['user-project-grants', address, GAME_MANAGER.ADDRESS], + queryFn: () => getAllUserGrants(address as Address, GAME_MANAGER.ADDRESS), + enabled: !!address, + }); + const isCorrectNetwork = appNetwork.id === chain?.id; return ( @@ -77,12 +96,54 @@ export const MobileNav = () => { ); })} + {isConnected ? ( + {grants?.length && grants.length > 0 && ( + + + Grants + + {grants?.map((grant, index) => ( + + + + + + + + {grant.project?.name} {'<>'} {grant.ship?.name} + + + + ))} + + + + )} {!isCorrectNetwork && ( { From 5c63f26c8c72f5747ad193cb5a1b89163f4d6ea5 Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 21 Aug 2024 22:30:03 -0700 Subject: [PATCH 5/5] clean --- src/layout/DesktopNav/GrantsNavSection.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/layout/DesktopNav/GrantsNavSection.tsx b/src/layout/DesktopNav/GrantsNavSection.tsx index 5ef35c3b..b878a3cc 100644 --- a/src/layout/DesktopNav/GrantsNavSection.tsx +++ b/src/layout/DesktopNav/GrantsNavSection.tsx @@ -4,21 +4,16 @@ import { Box, Divider, Flex, - Group, - Menu, Text, useMantineTheme, } from '@mantine/core'; import { useQuery } from '@tanstack/react-query'; -import { useAccount, useChainId } from 'wagmi'; -import { useUserData } from '../../hooks/useUserState'; +import { useAccount } from 'wagmi'; import { getAllUserGrants } from '../../queries/getProjectGrants'; import { GAME_MANAGER } from '../../constants/gameSetup'; import { Address } from 'viem'; import { Link, useLocation } from 'react-router-dom'; import classes from './DesktoNavStyles.module.css'; -import { useState } from 'react'; -import { IconChevronUp } from '@tabler/icons-react'; export const GrantsNavSection = () => { const { address } = useAccount();