@@ -11,17 +11,15 @@ import { renderToHTML } from "common/src/markdown";
11
11
import { ChevronDownIcon } from "@heroicons/react/24/outline" ;
12
12
import { ExpandableGrid } from "../../common/ExpandableGrid" ;
13
13
import { dateFromMs } from "../../api/utils" ;
14
- import { useEffect , useState , FC } from "react" ;
14
+ import { FC } from "react" ;
15
15
import { IGapImpact , getGapProjectImpactUrl } from "../../api/gap" ;
16
-
17
16
import { ShieldCheckIcon } from "@heroicons/react/24/solid" ;
18
17
import { useEnsName } from "wagmi" ;
19
18
20
19
interface ImpactItemProps {
21
20
impact : IGapImpact ;
22
21
url : string ;
23
22
}
24
-
25
23
const EthereumAddressToENSName : FC < {
26
24
address : `0x${string } `;
27
25
shouldTruncate ?: boolean ;
@@ -37,71 +35,138 @@ const EthereumAddressToENSName: FC<{
37
35
return < span className = "font-body" > { ensName || addressToDisplay } </ span > ;
38
36
} ;
39
37
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
+
41
52
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
84
83
</ 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 >
106
171
) ;
107
172
} ;
0 commit comments