Skip to content

Commit 23960dc

Browse files
committed
fix: Update UI as expandable dropdown
1 parent de2c794 commit 23960dc

File tree

2 files changed

+142
-94
lines changed

2 files changed

+142
-94
lines changed

packages/grant-explorer/src/features/round/KarmaGrant/ImpactItem.tsx

Lines changed: 132 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,15 @@ import { renderToHTML } from "common/src/markdown";
1111
import { ChevronDownIcon } from "@heroicons/react/24/outline";
1212
import { ExpandableGrid } from "../../common/ExpandableGrid";
1313
import { dateFromMs } from "../../api/utils";
14-
import { useEffect, useState, FC } from "react";
14+
import { FC } from "react";
1515
import { IGapImpact, getGapProjectImpactUrl } from "../../api/gap";
16-
1716
import { ShieldCheckIcon } from "@heroicons/react/24/solid";
1817
import { useEnsName } from "wagmi";
1918

2019
interface ImpactItemProps {
2120
impact: IGapImpact;
2221
url: string;
2322
}
24-
2523
const EthereumAddressToENSName: FC<{
2624
address: `0x${string}`;
2725
shouldTruncate?: boolean;
@@ -37,71 +35,138 @@ const EthereumAddressToENSName: FC<{
3735
return <span className="font-body">{ensName || addressToDisplay}</span>;
3836
};
3937

40-
export const ImpactItem: React.FC<ImpactItemProps> = ({ impact }) => {
38+
export const ImpactItem: React.FC<ImpactItemProps> = ({ impact, url }) => {
39+
const { isOpen, onToggle } = useDisclosure();
40+
41+
const impactImageProps = {
42+
bg: "green.900",
43+
borderRadius: "full",
44+
height: 8,
45+
width: 8,
46+
bgImage: GitcoinLogo,
47+
bgRepeat: "no-repeat",
48+
bgPosition: "45% 40%",
49+
bgSize: "50%",
50+
};
51+
4152
return (
42-
<tr className="" key={impact.uid}>
43-
<td
44-
className={
45-
"py-4 border-t border-t-black pr-6 px-6 max-w-[420px] max-sm:min-w-[200px] text-black "
46-
}
47-
>
48-
<Link
49-
target="_blank"
50-
href={getGapProjectImpactUrl(impact.refUID)}
51-
className="text-lg font-semibold align-top"
52-
>
53-
{impact.data?.work}
54-
</Link>
55-
</td>
56-
<td
57-
className={
58-
"py-4 border-t border-t-black pr-6 px-6 max-w-[420px] max-sm:min-w-[200px] align-top"
59-
}
60-
>
61-
<div className="mb-2">{impact.data?.impact}</div>
62-
<Link target="_blank" href={impact.data?.proof}>
63-
{impact.data?.proof}
64-
</Link>
65-
</td>
66-
<td
67-
className={
68-
"py-4 border-t border-t-black pr-6 px-6 max-w-[420px] max-sm:min-w-[200px] px-3 align-top pr-5"
69-
}
70-
>
71-
<div className="flex flex-row gap-3 items-center justify-start ml-3 min-w-max max-w-full">
72-
{impact.verified.length ? (
73-
<div className="w-max max-w-full">
74-
{impact.verified.map((verification) => (
75-
<div className="flex flex-row gap-2 items-center justify-start">
76-
<div className="bg-teal-100 flex gap-2 rounded-full px-2 text-xs items-center font-modern-era-medium text-teal-500">
77-
<ShieldCheckIcon className="w-4 h-4" />
78-
Verified
79-
</div>
80-
<span className="text-xs">
81-
by{" "}
82-
<EthereumAddressToENSName address={verification.attester} />
83-
</span>
53+
<Box mb={4}>
54+
<Box bg="gray.50" borderRadius={4} p={5}>
55+
<Flex justifyContent="space-between" alignItems="center" gap={4}>
56+
<Flex
57+
w="full"
58+
alignItems="center"
59+
justifyContent="space-between"
60+
flexWrap="wrap"
61+
>
62+
<Box>
63+
<Text fontWeight="semibold" className="flex gap-3">
64+
<Box {...impactImageProps} className="__impact-image" />
65+
<Link href={url} target="_blank" className="ml-2 max-w-lg">
66+
{impact.data?.work}
67+
</Link>
68+
</Text>
69+
</Box>
70+
<Flex justify="flex-end" gap={5}>
71+
<Box>
72+
<small>
73+
<span className="hidden md:inline">Completed on: </span>
74+
{impact.data?.completedAt
75+
? dateFromMs(impact.data.completedAt * 1000)
76+
: "N/A"}
77+
</small>
78+
</Box>
79+
{impact.verified.length > 0 && (
80+
<div className="bg-teal-100 flex gap-2 rounded-full px-2 text-xs items-center font-modern-era-medium text-teal-500">
81+
<ShieldCheckIcon className="w-4 h-4" />
82+
Verified
8483
</div>
85-
))}
86-
</div>
87-
) : null}
88-
</div>
89-
</td>
90-
<td
91-
className={
92-
"py-4 border-t border-t-black pr-6 px-6 max-w-[420px] max-sm:min-w-[200px] border-l border-l-zinc-400"
93-
}
94-
>
95-
<p className="w-36 max-w-max text-gray-500 text-sm font-medium ">
96-
{impact.data?.startedAt
97-
? dateFromMs(impact.data?.startedAt * 1000)
98-
: "N/A"}
99-
{" → "}
100-
{impact.data?.completedAt
101-
? dateFromMs(impact.data?.completedAt * 1000)
102-
: "N/A"}
103-
</p>
104-
</td>
105-
</tr>
84+
)}
85+
</Flex>
86+
</Flex>
87+
<Box>
88+
<ChevronDownIcon
89+
className={`cursor-pointer h-5 inline ${
90+
isOpen && "rotate-180"
91+
} transition-transform`}
92+
onClick={onToggle}
93+
/>
94+
</Box>
95+
</Flex>
96+
<ExpandableGrid isOpen={isOpen}>
97+
<Box overflow="hidden">
98+
<Divider borderWidth={1} my={4} />
99+
<Box
100+
__css={{
101+
h1: {
102+
fontSize: "1.5rem",
103+
fontWeight: "bold",
104+
margin: "1rem 0",
105+
},
106+
h2: {
107+
fontSize: "1.25rem",
108+
fontWeight: "bold",
109+
margin: "1rem 0",
110+
},
111+
}}
112+
>
113+
<Text fontWeight="bold" mb={2}>
114+
Work:
115+
</Text>
116+
<Box
117+
dangerouslySetInnerHTML={{
118+
__html: renderToHTML(impact.data?.work || ""),
119+
}}
120+
/>
121+
122+
<Text fontWeight="bold" mt={4} mb={2}>
123+
Impact:
124+
</Text>
125+
<Box
126+
dangerouslySetInnerHTML={{
127+
__html: renderToHTML(impact.data?.impact || ""),
128+
}}
129+
/>
130+
131+
<Text fontWeight="bold" mt={4} mb={2}>
132+
Proof:
133+
</Text>
134+
<Link href={impact.data?.proof} target="_blank" color="blue.500">
135+
{impact.data?.proof}
136+
</Link>
137+
138+
{impact.verified.length > 0 && (
139+
<>
140+
<Text fontWeight="bold" mt={4} mb={2}>
141+
Verifications:
142+
</Text>
143+
{impact.verified.map((verification, index) => (
144+
<Text key={index}>
145+
Verified by:{" "}
146+
<EthereumAddressToENSName
147+
address={verification.attester}
148+
/>
149+
</Text>
150+
))}
151+
</>
152+
)}
153+
154+
<Text fontWeight="bold" mt={4} mb={2}>
155+
Timeframe:
156+
</Text>
157+
<Text>
158+
{impact.data?.startedAt
159+
? dateFromMs(impact.data?.startedAt * 1000)
160+
: "N/A"}
161+
{" → "}
162+
{impact.data?.completedAt
163+
? dateFromMs(impact.data?.completedAt * 1000)
164+
: "N/A"}
165+
</Text>
166+
</Box>
167+
</Box>
168+
</ExpandableGrid>
169+
</Box>
170+
</Box>
106171
);
107172
};

packages/grant-explorer/src/features/round/KarmaGrant/ImpactList.tsx

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,16 @@ export const ImpactList: React.FC<ImpactListProps> = ({ impacts }) => {
1111
<Flex gap={2} flexDir="column" py={6} px={3}>
1212
<h4 className="text-3xl">Project impacts</h4>
1313
{impacts.length > 0 ? (
14-
<table className="overflow-x-auto w-full my-5">
15-
<thead>
16-
<tr>
17-
<th className="text-black text-xs font-medium uppercase text-left px-6 py-3 font-body">
18-
Work
19-
</th>
20-
<th className="text-black text-xs font-medium uppercase text-left px-6 py-3 font-body">
21-
Impact & Proof
22-
</th>
23-
<th className="text-black text-xs font-medium uppercase text-left px-6 py-3 font-body">
24-
Verifications
25-
</th>
26-
<th className="text-black text-xs font-medium uppercase text-left px-6 py-3 font-body">
27-
Timeframe
28-
</th>
29-
</tr>
30-
</thead>
31-
<tbody className="">
32-
{impacts.map((item) => (
33-
<ImpactItem
34-
key={item.uid}
35-
impact={item}
36-
url={getGapProjectImpactUrl(item.refUID)}
37-
/>
38-
))}
39-
</tbody>
40-
</table>
14+
<>
15+
<Text className="text-[18px]">Total impacts ({impacts.length})</Text>
16+
{impacts.map((impact) => (
17+
<ImpactItem
18+
key={impact.uid}
19+
impact={impact}
20+
url={getGapProjectImpactUrl(impact.refUID)}
21+
/>
22+
))}
23+
</>
4124
) : (
4225
<Text>
4326
No previous impacts are being tracked for this project. If you're the

0 commit comments

Comments
 (0)