Skip to content

Commit

Permalink
Merge pull request #293 from DAOmasons/grantsDisplays
Browse files Browse the repository at this point in the history
Grants displays
  • Loading branch information
jordanlesich authored Aug 9, 2024
2 parents 1fce3d5 + a66dfaf commit 47e162f
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 57 deletions.
49 changes: 49 additions & 0 deletions src/.graphclient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9843,6 +9843,12 @@ const merger = new(BareMerger as any)({
return printWithCache(GetProjectGrantsDocument);
},
location: 'GetProjectGrantsDocument.graphql'
},{
document: GetAllProjectGrantsDocument,
get rawSDL() {
return printWithCache(GetAllProjectGrantsDocument);
},
location: 'GetAllProjectGrantsDocument.graphql'
},{
document: GetProjectsDocument,
get rawSDL() {
Expand Down Expand Up @@ -10238,6 +10244,26 @@ export type getProjectGrantsQuery = { grants: Array<(
)> }
)> };

export type getAllProjectGrantsQueryVariables = Exact<{
userAddress: Scalars['String'];
gameId: Scalars['String'];
}>;


export type getAllProjectGrantsQuery = { grants: Array<(
Pick<Grant, 'amountDistributed' | 'amountAllocated' | 'id' | 'status' | 'lastUpdated' | 'amount' | 'grantCompleted' | 'hasPendingMilestones' | 'hasRejectedMilestones' | 'allMilestonesApproved'>
& { ship?: Maybe<(
Pick<GrantShip, 'id' | 'name' | 'shipContractAddress'>
& { profileMetadata?: Maybe<Pick<RawMetadata, 'pointer'>> }
)>, project?: Maybe<(
Pick<Project, 'id' | 'name'>
& { metadata?: Maybe<Pick<RawMetadata, 'pointer'>> }
)>, currentMilestones?: Maybe<(
Pick<MilestoneSet, 'id' | 'milestoneLength' | 'milestonesCompleted' | 'milestonesRejected' | 'milestonesPending'>
& { milestones: Array<Pick<Milestone, 'id' | 'index' | 'percentage' | 'status'>> }
)> }
)> };

export type ProjectDetailsFragment = Pick<Project, 'id' | 'name' | 'profileId' | 'nonce' | 'anchor' | 'owner'>;

export type RawMetadataFragment = Pick<RawMetadata, 'protocol' | 'pointer'>;
Expand Down Expand Up @@ -10874,6 +10900,25 @@ export const getProjectGrantsDocument = gql`
}
${GrantBasicFragmentDoc}
${ShipDisplayFragmentDoc}` as unknown as DocumentNode<getProjectGrantsQuery, getProjectGrantsQueryVariables>;
export const getAllProjectGrantsDocument = gql`
query getAllProjectGrants($userAddress: String!, $gameId: String!) {
grants: Grant(
where: {gameManager_id: {_eq: $gameId}, project: {owner: {_eq: $userAddress}}}
) {
...GrantBasic
amountDistributed
amountAllocated
ship {
...ShipDisplay
}
project {
...ProjectDisplay
}
}
}
${GrantBasicFragmentDoc}
${ShipDisplayFragmentDoc}
${ProjectDisplayFragmentDoc}` as unknown as DocumentNode<getAllProjectGrantsQuery, getAllProjectGrantsQueryVariables>;
export const GetProjectsDocument = gql`
query GetProjects($chainId: Int!) {
Project(
Expand Down Expand Up @@ -11108,6 +11153,7 @@ export const ShipsPageQueryDocument = gql`






export type Requester<C = {}, E = unknown> = <R, V>(doc: DocumentNode, vars?: V, options?: C) => Promise<R> | AsyncIterable<R>
Expand Down Expand Up @@ -11137,6 +11183,9 @@ export function getSdk<C, E>(requester: Requester<C, E>) {
getProjectGrants(variables: getProjectGrantsQueryVariables, options?: C): Promise<getProjectGrantsQuery> {
return requester<getProjectGrantsQuery, getProjectGrantsQueryVariables>(getProjectGrantsDocument, variables, options) as Promise<getProjectGrantsQuery>;
},
getAllProjectGrants(variables: getAllProjectGrantsQueryVariables, options?: C): Promise<getAllProjectGrantsQuery> {
return requester<getAllProjectGrantsQuery, getAllProjectGrantsQueryVariables>(getAllProjectGrantsDocument, variables, options) as Promise<getAllProjectGrantsQuery>;
},
GetProjects(variables: GetProjectsQueryVariables, options?: C): Promise<GetProjectsQuery> {
return requester<GetProjectsQuery, GetProjectsQueryVariables>(GetProjectsDocument, variables, options) as Promise<GetProjectsQuery>;
},
Expand Down
88 changes: 53 additions & 35 deletions src/components/grant/GrantCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Avatar,
Box,
Group,
Indicator,
Paper,
Text,
Tooltip,
Expand All @@ -22,7 +22,7 @@ import {
IconShieldX,
} from '@tabler/icons-react';
import { Link } from 'react-router-dom';
import { ReactNode } from 'react';
import { ReactNode, useMemo } from 'react';

export const GrantCard = ({
avatarUrls,
Expand All @@ -33,6 +33,7 @@ export const GrantCard = ({
hasPending,
hasRejected,
allCompleted,
notify,
}: {
linkUrl: string;
isActive: boolean;
Expand All @@ -42,43 +43,60 @@ export const GrantCard = ({
hasPending: boolean;
hasRejected: boolean;
allCompleted: boolean;
notify?: boolean;
}) => {
const theme = useMantineTheme();

return (
<Paper
w="100%"
bg={theme.colors.dark[6]}
p="lg"
component={Link}
to={linkUrl}
>
<Group justify="space-between">
<Group gap={8}>
<Avatar.Group>
{avatarUrls.map((url) => (
<Avatar size={32} src={url} key={url} />
))}
</Avatar.Group>
<Text fz="sm" fw={500}>
{label}
</Text>
<Tooltip label={isActive ? 'Active' : 'Inactive'}>
<IconCheck
size={16}
color={isActive ? theme.colors.blue[6] : theme.colors.dark[5]}
/>
</Tooltip>
const cardGuts = useMemo(() => {
return (
<Paper
w="100%"
bg={theme.colors.dark[6]}
p="lg"
component={Link}
to={linkUrl}
>
<Group justify="space-between">
<Group gap={8}>
<Avatar.Group>
{avatarUrls.map((url) => (
<Avatar size={32} src={url} key={url} />
))}
</Avatar.Group>
<Text fz="sm" fw={500}>
{label}
</Text>
<Tooltip label={isActive ? 'Active' : 'Inactive'}>
<IconCheck
size={16}
color={isActive ? theme.colors.blue[6] : theme.colors.dark[5]}
/>
</Tooltip>
</Group>
<GrantStatusIndicator
hasPending={hasPending}
hasRejected={hasRejected}
allCompleted={allCompleted}
status={status}
/>
</Group>
<GrantStatusIndicator
hasPending={hasPending}
hasRejected={hasRejected}
allCompleted={allCompleted}
status={status}
/>
</Group>
</Paper>
);
</Paper>
);
}, [
avatarUrls,
label,
isActive,
linkUrl,
status,
hasPending,
hasRejected,
allCompleted,
]);

if (notify) {
return <Indicator>{cardGuts}</Indicator>;
}
return cardGuts;
};

const GrantStatusIndicator = ({
Expand Down
19 changes: 19 additions & 0 deletions src/graphql/newQueries/getProjectGrants.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,22 @@ query getProjectGrants($projectId: String!, $gameId: String!) {
}
}
}

query getAllProjectGrants($userAddress: String!, $gameId: String!) {
grants: Grant(
where: {
gameManager_id: { _eq: $gameId }
project: { owner: { _eq: $userAddress } }
}
) {
...GrantBasic
amountDistributed
amountAllocated
ship {
...ShipDisplay
}
project {
...ProjectDisplay
}
}
}
26 changes: 26 additions & 0 deletions src/layout/DesktopNav/DesktoNavStyles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,29 @@
.full-width {
width: 100%;
}

.grantLink {
display: block;
text-decoration: none;
max-width: 230px;
padding: var(--mantine-spacing-xs);
&:hover {
background-color: var(--mantine-color-dark-6);
}
border-radius: var(--mantine-radius-sm);

&[data-active] {
&,
&:hover {
background-color: var(--mantine-color-blue-light);
color: var(--mantine-color-blue-light-color);
}
}
}

.grantLinkText {
flexgrow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
12 changes: 10 additions & 2 deletions src/layout/DesktopNav/DesktopNav.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Group, Code, Title, useMantineTheme, Tooltip } from '@mantine/core';
import {
Group,
Code,
Title,
useMantineTheme,
Tooltip,
Divider,
} from '@mantine/core';
import {
IconRocket,
IconAward,
Expand All @@ -16,6 +23,7 @@ import { useUserData } from '../../hooks/useUserState';
import { useAccount } from 'wagmi';
import { navItems } from '../../constants/navItems';
import { useTablet } from '../../hooks/useBreakpoint';
import { GrantsNavSection } from './GrantsNavSection';

export function DesktopNav() {
const location = useLocation();
Expand Down Expand Up @@ -156,11 +164,11 @@ export function DesktopNav() {
)}
</Group>
{links}
<GrantsNavSection />
</div>

<div className={classes.footer}>{dashboardLink}</div>
<ConnectButton />

{!isTablet && (
<Code w="fit-content" ml={'sm'} mt={'lg'}>
v{process.env.PACKAGE_VERSION}
Expand Down
94 changes: 94 additions & 0 deletions src/layout/DesktopNav/GrantsNavSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
Avatar,
AvatarGroup,
Box,
Divider,
Flex,
Group,
Text,
useMantineTheme,
} from '@mantine/core';
import { useQuery } from '@tanstack/react-query';
import { useAccount, useChainId } from 'wagmi';
import { useUserData } from '../../hooks/useUserState';
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';

export const GrantsNavSection = () => {
const { address } = useAccount();
const theme = useMantineTheme();

const {
data: grants,
isLoading,
error,
} = useQuery({
queryKey: ['user-project-grants', address, GAME_MANAGER.ADDRESS],
queryFn: () => getAllUserGrants(address as Address, GAME_MANAGER.ADDRESS),
enabled: !!address,
});

if (isLoading || error || !grants || grants.length === 0) return null;

return (
<Box>
<Divider mt="md" mb="sm" />
<Text fz="sm" mb={'md'} c={theme.colors.gray[6]}>
Grants
</Text>
{grants?.map((grant) => (
<NavGrantLink
key={grant.id}
grantId={grant.id}
projectImgUrl={grant.project?.metadata?.imgUrl || ''}
shipImgUrl={grant.ship?.profileMetadata?.imgUrl || ''}
collabText={`${grant.project.name} <> ${grant.ship?.name}`}
/>
))}
</Box>
);
};

const NavGrantLink = ({
projectImgUrl,
shipImgUrl,
collabText,
grantId,
}: {
projectImgUrl: string;
shipImgUrl: string;
collabText: string;
grantId: string;
}) => {
const location = useLocation();
const isActive = location.pathname.includes(grantId);

return (
<Link
to={`grant/${grantId}`}
data-active={isActive ? grantId : undefined}
className={classes.grantLink}
>
<Flex align="center" gap={8}>
<AvatarGroup>
<Avatar src={projectImgUrl} size={24} />
<Avatar src={shipImgUrl} size={24} />
</AvatarGroup>
<Text
fz="sm"
style={{
flexGrow: 1,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{collabText}
</Text>
</Flex>
</Link>
);
};
Loading

0 comments on commit 47e162f

Please sign in to comment.