@turtleclub/ui 0.3.0-beta.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/.prettierrc.json +4 -0
  2. package/.turbo/turbo-build.log +152 -26
  3. package/CHANGELOG.md +338 -0
  4. package/dist/index.cjs +178 -36
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.js +25526 -4757
  7. package/dist/index.js.map +1 -1
  8. package/dist/styles.css +1 -1
  9. package/dist/types/components/features/data-table.d.ts +9 -0
  10. package/dist/types/components/features/data-table.d.ts.map +1 -0
  11. package/dist/types/components/features/index.d.ts +5 -0
  12. package/dist/types/components/features/index.d.ts.map +1 -0
  13. package/dist/types/components/features/page-heading.d.ts +10 -0
  14. package/dist/types/components/features/page-heading.d.ts.map +1 -0
  15. package/dist/types/components/features/search-bar.d.ts +10 -0
  16. package/dist/types/components/features/search-bar.d.ts.map +1 -0
  17. package/dist/types/components/features/segmented-navigation.d.ts +7 -0
  18. package/dist/types/components/features/segmented-navigation.d.ts.map +1 -0
  19. package/dist/types/components/features/sidebar-layout.d.ts +36 -0
  20. package/dist/types/components/features/sidebar-layout.d.ts.map +1 -0
  21. package/dist/types/components/icons/arrow.d.ts +4 -0
  22. package/dist/types/components/icons/arrow.d.ts.map +1 -0
  23. package/dist/types/components/icons/beta.d.ts +4 -0
  24. package/dist/types/components/icons/beta.d.ts.map +1 -0
  25. package/dist/types/components/icons/dot.d.ts +4 -0
  26. package/dist/types/components/icons/dot.d.ts.map +1 -0
  27. package/dist/types/components/icons/index.d.ts +8 -0
  28. package/dist/types/components/icons/index.d.ts.map +1 -0
  29. package/dist/types/components/icons/issue.d.ts +4 -0
  30. package/dist/types/components/icons/issue.d.ts.map +1 -0
  31. package/dist/types/components/icons/turtle.d.ts +4 -0
  32. package/dist/types/components/icons/turtle.d.ts.map +1 -0
  33. package/dist/types/components/icons/update.d.ts +4 -0
  34. package/dist/types/components/icons/update.d.ts.map +1 -0
  35. package/dist/types/components/icons/warning.d.ts +4 -0
  36. package/dist/types/components/icons/warning.d.ts.map +1 -0
  37. package/dist/types/components/molecules/index.d.ts +2 -0
  38. package/dist/types/components/molecules/index.d.ts.map +1 -1
  39. package/dist/types/components/molecules/opportunity/index.d.ts +3 -1
  40. package/dist/types/components/molecules/opportunity/index.d.ts.map +1 -1
  41. package/dist/types/components/molecules/opportunity/opportunity-apr.d.ts +8 -3
  42. package/dist/types/components/molecules/opportunity/opportunity-apr.d.ts.map +1 -1
  43. package/dist/types/components/molecules/opportunity/opportunity-disclaimer.d.ts +1 -2
  44. package/dist/types/components/molecules/opportunity/opportunity-disclaimer.d.ts.map +1 -1
  45. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/index.d.ts +3 -0
  46. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/index.d.ts.map +1 -0
  47. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-filtering.d.ts +11 -0
  48. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-filtering.d.ts.map +1 -0
  49. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.d.ts +9 -0
  50. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.d.ts.map +1 -0
  51. package/dist/types/components/molecules/opportunity/opportunity-list/index.d.ts +2 -0
  52. package/dist/types/components/molecules/opportunity/opportunity-list/index.d.ts.map +1 -0
  53. package/dist/types/components/molecules/opportunity/opportunity-list/opportunity-list.d.ts +22 -0
  54. package/dist/types/components/molecules/opportunity/opportunity-list/opportunity-list.d.ts.map +1 -0
  55. package/dist/types/components/molecules/opportunity/opportunity-rate-estimator.d.ts +1 -2
  56. package/dist/types/components/molecules/opportunity/opportunity-rate-estimator.d.ts.map +1 -1
  57. package/dist/types/components/molecules/opportunity/opportunity-section.d.ts +4 -0
  58. package/dist/types/components/molecules/opportunity/opportunity-section.d.ts.map +1 -1
  59. package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts +1 -2
  60. package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts.map +1 -1
  61. package/dist/types/components/molecules/opportunity/opportunity-type.d.ts +1 -2
  62. package/dist/types/components/molecules/opportunity/opportunity-type.d.ts.map +1 -1
  63. package/dist/types/components/molecules/route-details.d.ts +1 -1
  64. package/dist/types/components/molecules/route-details.d.ts.map +1 -1
  65. package/dist/types/components/molecules/slippage-selector.d.ts +1 -2
  66. package/dist/types/components/molecules/slippage-selector.d.ts.map +1 -1
  67. package/dist/types/components/molecules/swap-details.d.ts.map +1 -1
  68. package/dist/types/components/molecules/swap-input.d.ts +5 -1
  69. package/dist/types/components/molecules/swap-input.d.ts.map +1 -1
  70. package/dist/types/components/molecules/tabs.d.ts +18 -0
  71. package/dist/types/components/molecules/tabs.d.ts.map +1 -0
  72. package/dist/types/components/molecules/token-selector.d.ts +1 -1
  73. package/dist/types/components/molecules/token-selector.d.ts.map +1 -1
  74. package/dist/types/components/molecules/tx-status.d.ts.map +1 -1
  75. package/dist/types/components/molecules/widget/asset-list/asset-filters.d.ts +20 -0
  76. package/dist/types/components/molecules/widget/asset-list/asset-filters.d.ts.map +1 -0
  77. package/dist/types/components/molecules/widget/asset-list/asset-list.d.ts +35 -0
  78. package/dist/types/components/molecules/widget/asset-list/asset-list.d.ts.map +1 -0
  79. package/dist/types/components/molecules/widget/asset-list/asset-row.d.ts +12 -0
  80. package/dist/types/components/molecules/widget/asset-list/asset-row.d.ts.map +1 -0
  81. package/dist/types/components/molecules/widget/asset-list/hooks/index.d.ts +3 -0
  82. package/dist/types/components/molecules/widget/asset-list/hooks/index.d.ts.map +1 -0
  83. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-filtering.d.ts +10 -0
  84. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-filtering.d.ts.map +1 -0
  85. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-grouping.d.ts +9 -0
  86. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-grouping.d.ts.map +1 -0
  87. package/dist/types/components/molecules/widget/asset-list/index.d.ts +4 -0
  88. package/dist/types/components/molecules/widget/asset-list/index.d.ts.map +1 -0
  89. package/dist/types/components/molecules/widget/base-selector.d.ts +17 -0
  90. package/dist/types/components/molecules/widget/base-selector.d.ts.map +1 -0
  91. package/dist/types/components/molecules/widget/campaign-item.d.ts +20 -0
  92. package/dist/types/components/molecules/widget/campaign-item.d.ts.map +1 -0
  93. package/dist/types/components/molecules/widget/deal-item.d.ts +20 -0
  94. package/dist/types/components/molecules/widget/deal-item.d.ts.map +1 -0
  95. package/dist/types/components/molecules/widget/index.d.ts +14 -0
  96. package/dist/types/components/molecules/widget/index.d.ts.map +1 -0
  97. package/dist/types/components/molecules/widget/opportunity-item.d.ts +33 -0
  98. package/dist/types/components/molecules/widget/opportunity-item.d.ts.map +1 -0
  99. package/dist/types/components/molecules/widget/widget-item-stats.d.ts +14 -0
  100. package/dist/types/components/molecules/widget/widget-item-stats.d.ts.map +1 -0
  101. package/dist/types/components/molecules/widget/widget-item.d.ts +26 -0
  102. package/dist/types/components/molecules/widget/widget-item.d.ts.map +1 -0
  103. package/dist/types/components/molecules/widget/widget-list-items.d.ts +20 -0
  104. package/dist/types/components/molecules/widget/widget-list-items.d.ts.map +1 -0
  105. package/dist/types/components/ui/alert-dialog.d.ts +15 -0
  106. package/dist/types/components/ui/alert-dialog.d.ts.map +1 -0
  107. package/dist/types/components/ui/animated-background/animated-background.d.ts +9 -0
  108. package/dist/types/components/ui/animated-background/animated-background.d.ts.map +1 -0
  109. package/dist/types/components/ui/animated-background/index.d.ts +2 -0
  110. package/dist/types/components/ui/animated-background/index.d.ts.map +1 -0
  111. package/dist/types/components/ui/avatar.d.ts +18 -4
  112. package/dist/types/components/ui/avatar.d.ts.map +1 -1
  113. package/dist/types/components/ui/badge.d.ts +5 -4
  114. package/dist/types/components/ui/badge.d.ts.map +1 -1
  115. package/dist/types/components/ui/banner.d.ts +7 -0
  116. package/dist/types/components/ui/banner.d.ts.map +1 -0
  117. package/dist/types/components/ui/button.d.ts +8 -6
  118. package/dist/types/components/ui/button.d.ts.map +1 -1
  119. package/dist/types/components/ui/card.d.ts +10 -11
  120. package/dist/types/components/ui/card.d.ts.map +1 -1
  121. package/dist/types/components/ui/checkbox.d.ts +5 -0
  122. package/dist/types/components/ui/checkbox.d.ts.map +1 -0
  123. package/dist/types/components/ui/chip.d.ts +1 -1
  124. package/dist/types/components/ui/chip.d.ts.map +1 -1
  125. package/dist/types/components/ui/collapsible.d.ts +7 -0
  126. package/dist/types/components/ui/collapsible.d.ts.map +1 -0
  127. package/dist/types/components/ui/combobox.d.ts +148 -0
  128. package/dist/types/components/ui/combobox.d.ts.map +1 -0
  129. package/dist/types/components/ui/command.d.ts +19 -0
  130. package/dist/types/components/ui/command.d.ts.map +1 -0
  131. package/dist/types/components/ui/dialog.d.ts +10 -10
  132. package/dist/types/components/ui/dialog.d.ts.map +1 -1
  133. package/dist/types/components/ui/dropdown.d.ts +30 -0
  134. package/dist/types/components/ui/dropdown.d.ts.map +1 -0
  135. package/dist/types/components/ui/field.d.ts +26 -0
  136. package/dist/types/components/ui/field.d.ts.map +1 -0
  137. package/dist/types/components/ui/heading.d.ts +12 -0
  138. package/dist/types/components/ui/heading.d.ts.map +1 -0
  139. package/dist/types/components/ui/hover-card.d.ts +7 -7
  140. package/dist/types/components/ui/hover-card.d.ts.map +1 -1
  141. package/dist/types/components/ui/icon-animation.d.ts +1 -1
  142. package/dist/types/components/ui/icon-animation.d.ts.map +1 -1
  143. package/dist/types/components/ui/icon-list.d.ts +17 -0
  144. package/dist/types/components/ui/icon-list.d.ts.map +1 -0
  145. package/dist/types/components/ui/index.d.ts +28 -8
  146. package/dist/types/components/ui/index.d.ts.map +1 -1
  147. package/dist/types/components/ui/info-card.d.ts +4 -4
  148. package/dist/types/components/ui/info-card.d.ts.map +1 -1
  149. package/dist/types/components/ui/input-group.d.ts +17 -0
  150. package/dist/types/components/ui/input-group.d.ts.map +1 -0
  151. package/dist/types/components/ui/input.d.ts +1 -3
  152. package/dist/types/components/ui/input.d.ts.map +1 -1
  153. package/dist/types/components/ui/label-with-icon.d.ts +3 -3
  154. package/dist/types/components/ui/label-with-icon.d.ts.map +1 -1
  155. package/dist/types/components/ui/label.d.ts +1 -1
  156. package/dist/types/components/ui/label.d.ts.map +1 -1
  157. package/dist/types/components/ui/multi-select.d.ts +192 -0
  158. package/dist/types/components/ui/multi-select.d.ts.map +1 -0
  159. package/dist/types/components/ui/navigation-bar.d.ts +2 -2
  160. package/dist/types/components/ui/navigation-bar.d.ts.map +1 -1
  161. package/dist/types/components/ui/navigation-menu.d.ts +15 -0
  162. package/dist/types/components/ui/navigation-menu.d.ts.map +1 -0
  163. package/dist/types/components/ui/opportunity-details-v1.d.ts +1 -1
  164. package/dist/types/components/ui/opportunity-details-v1.d.ts.map +1 -1
  165. package/dist/types/components/ui/popover.d.ts +8 -0
  166. package/dist/types/components/ui/popover.d.ts.map +1 -0
  167. package/dist/types/components/ui/scroll-area.d.ts +2 -2
  168. package/dist/types/components/ui/scroll-area.d.ts.map +1 -1
  169. package/dist/types/components/ui/segment-control.d.ts +19 -0
  170. package/dist/types/components/ui/segment-control.d.ts.map +1 -0
  171. package/dist/types/components/ui/select.d.ts +14 -13
  172. package/dist/types/components/ui/select.d.ts.map +1 -1
  173. package/dist/types/components/ui/separator.d.ts +1 -1
  174. package/dist/types/components/ui/separator.d.ts.map +1 -1
  175. package/dist/types/components/ui/sheet.d.ts +14 -0
  176. package/dist/types/components/ui/sheet.d.ts.map +1 -0
  177. package/dist/types/components/ui/sidebar.d.ts +69 -0
  178. package/dist/types/components/ui/sidebar.d.ts.map +1 -0
  179. package/dist/types/components/ui/skeleton.d.ts +4 -0
  180. package/dist/types/components/ui/skeleton.d.ts.map +1 -0
  181. package/dist/types/components/ui/slider.d.ts +5 -0
  182. package/dist/types/components/ui/slider.d.ts.map +1 -0
  183. package/dist/types/components/ui/sonner.d.ts +1 -2
  184. package/dist/types/components/ui/sonner.d.ts.map +1 -1
  185. package/dist/types/components/ui/switch.d.ts +1 -1
  186. package/dist/types/components/ui/switch.d.ts.map +1 -1
  187. package/dist/types/components/ui/table-shadcn.d.ts +11 -0
  188. package/dist/types/components/ui/table-shadcn.d.ts.map +1 -0
  189. package/dist/types/components/ui/table.d.ts +2 -2
  190. package/dist/types/components/ui/table.d.ts.map +1 -1
  191. package/dist/types/components/ui/textarea.d.ts +4 -0
  192. package/dist/types/components/ui/textarea.d.ts.map +1 -0
  193. package/dist/types/components/ui/toggle-group.d.ts +2 -2
  194. package/dist/types/components/ui/toggle-group.d.ts.map +1 -1
  195. package/dist/types/components/ui/toggle.d.ts +2 -2
  196. package/dist/types/components/ui/toggle.d.ts.map +1 -1
  197. package/dist/types/components/ui/tooltip.d.ts +7 -4
  198. package/dist/types/components/ui/tooltip.d.ts.map +1 -1
  199. package/dist/types/hooks/useIsMobile.d.ts +7 -0
  200. package/dist/types/hooks/useIsMobile.d.ts.map +1 -0
  201. package/dist/types/index.d.ts +2 -0
  202. package/dist/types/index.d.ts.map +1 -1
  203. package/package.json +39 -28
  204. package/src/components/features/data-table.tsx +96 -0
  205. package/src/components/features/index.ts +4 -0
  206. package/src/components/features/page-heading.tsx +22 -0
  207. package/src/components/features/search-bar.tsx +50 -0
  208. package/src/components/features/segmented-navigation.tsx +18 -0
  209. package/src/components/features/sidebar-layout.tsx +190 -0
  210. package/src/components/icons/arrow.tsx +23 -0
  211. package/src/components/icons/beta.tsx +86 -0
  212. package/src/components/icons/dot.tsx +89 -0
  213. package/src/components/icons/index.ts +7 -0
  214. package/src/components/icons/issue.tsx +97 -0
  215. package/src/components/icons/turtle.tsx +143 -0
  216. package/src/components/icons/update.tsx +108 -0
  217. package/src/components/icons/warning.tsx +86 -0
  218. package/src/components/molecules/index.ts +2 -1
  219. package/src/components/molecules/opportunity/index.ts +5 -1
  220. package/src/components/molecules/opportunity/opportunity-apr.tsx +99 -16
  221. package/src/components/molecules/opportunity/opportunity-list/hooks/index.ts +2 -0
  222. package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-filtering.ts +45 -0
  223. package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.ts +81 -0
  224. package/src/components/molecules/opportunity/opportunity-list/index.ts +1 -0
  225. package/src/components/molecules/opportunity/opportunity-list/opportunity-list.tsx +136 -0
  226. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +4 -1
  227. package/src/components/molecules/opportunity/opportunity-section.tsx +37 -19
  228. package/src/components/molecules/opportunity/opportunity-selector.tsx +2 -3
  229. package/src/components/molecules/route-details.tsx +48 -37
  230. package/src/components/molecules/swap-details.tsx +2 -4
  231. package/src/components/molecules/swap-input.tsx +56 -21
  232. package/src/components/molecules/tabs.tsx +67 -0
  233. package/src/components/molecules/token-selector.tsx +2 -2
  234. package/src/components/molecules/tx-status.tsx +1 -5
  235. package/src/components/molecules/widget/asset-list/asset-filters.tsx +111 -0
  236. package/src/components/molecules/widget/asset-list/asset-list.tsx +171 -0
  237. package/src/components/molecules/widget/asset-list/asset-row.tsx +45 -0
  238. package/src/components/molecules/widget/asset-list/hooks/index.ts +2 -0
  239. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +42 -0
  240. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +78 -0
  241. package/src/components/molecules/widget/asset-list/index.ts +3 -0
  242. package/src/components/molecules/widget/base-selector.tsx +104 -0
  243. package/src/components/molecules/widget/campaign-item.tsx +76 -0
  244. package/src/components/molecules/widget/deal-item.tsx +80 -0
  245. package/src/components/molecules/widget/index.ts +33 -0
  246. package/src/components/molecules/widget/opportunity-item.tsx +91 -0
  247. package/src/components/molecules/widget/widget-item-stats.tsx +50 -0
  248. package/src/components/molecules/widget/widget-item.tsx +138 -0
  249. package/src/components/molecules/widget/widget-list-items.tsx +86 -0
  250. package/src/components/ui/alert-dialog.tsx +146 -0
  251. package/src/components/ui/animated-background/animated-background.tsx +174 -0
  252. package/src/components/ui/animated-background/index.ts +1 -0
  253. package/src/components/ui/avatar.tsx +34 -19
  254. package/src/components/ui/badge.tsx +18 -8
  255. package/src/components/ui/banner.tsx +78 -0
  256. package/src/components/ui/button.tsx +51 -21
  257. package/src/components/ui/card.tsx +21 -61
  258. package/src/components/ui/checkbox.tsx +29 -0
  259. package/src/components/ui/collapsible.tsx +22 -0
  260. package/src/components/ui/combobox.tsx +617 -0
  261. package/src/components/ui/command.tsx +164 -0
  262. package/src/components/ui/dialog.tsx +5 -9
  263. package/src/components/ui/dropdown.tsx +263 -0
  264. package/src/components/ui/field.tsx +232 -0
  265. package/src/components/ui/heading.tsx +49 -0
  266. package/src/components/ui/hover-card.tsx +10 -10
  267. package/src/components/ui/icon-list.tsx +141 -0
  268. package/src/components/ui/index.ts +29 -9
  269. package/src/components/ui/info-card.tsx +1 -1
  270. package/src/components/ui/input-group.tsx +158 -0
  271. package/src/components/ui/input.tsx +17 -25
  272. package/src/components/ui/label-with-icon.tsx +40 -30
  273. package/src/components/ui/label.tsx +8 -9
  274. package/src/components/ui/multi-select.tsx +1000 -0
  275. package/src/components/ui/navigation-menu.tsx +181 -0
  276. package/src/components/ui/opportunity-details-v1.tsx +2 -2
  277. package/src/components/ui/popover.tsx +42 -0
  278. package/src/components/ui/scroll-area.tsx +11 -11
  279. package/src/components/ui/segment-control.tsx +140 -0
  280. package/src/components/ui/select.tsx +26 -31
  281. package/src/components/ui/sheet.tsx +130 -0
  282. package/src/components/ui/sidebar.tsx +693 -0
  283. package/src/components/ui/skeleton.tsx +14 -0
  284. package/src/components/ui/slider.tsx +58 -0
  285. package/src/components/ui/switch.tsx +8 -11
  286. package/src/components/ui/{table-shad.tsx → table-shadcn.tsx} +25 -39
  287. package/src/components/ui/table.tsx +3 -2
  288. package/src/components/ui/textarea.tsx +22 -0
  289. package/src/components/ui/tooltip.tsx +11 -7
  290. package/src/hooks/useIsMobile.ts +74 -0
  291. package/src/index.ts +2 -0
  292. package/src/styles/globals.css +87 -20
  293. package/src/styles/themes/semantic.css +11 -5
  294. package/src/styles/tokens/colors.css +64 -53
  295. package/src/styles/tokens/radius.css +3 -34
  296. package/tsconfig.json +11 -15
  297. package/vite.config.js +41 -57
  298. package/dist/types/components/molecules/opportunity/opportunity-item.d.ts +0 -15
  299. package/dist/types/components/molecules/opportunity/opportunity-item.d.ts.map +0 -1
  300. package/dist/types/components/ui/table-shad.d.ts +0 -11
  301. package/dist/types/components/ui/table-shad.d.ts.map +0 -1
  302. package/src/components/molecules/opportunity/opportunity-item.tsx +0 -93
@@ -0,0 +1,143 @@
1
+ export const TurtleIcon = ({ className }: { className?: string }) => {
2
+ return (
3
+ <svg className={className} viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
4
+ <g filter="url(#filter0_di_10359_4283)">
5
+ <rect
6
+ x="7.5"
7
+ y="8"
8
+ width="72.4228"
9
+ height="72.4228"
10
+ rx="36.2114"
11
+ fill="url(#paint0_linear_10359_4283)"
12
+ fill-opacity="0.6"
13
+ shape-rendering="crispEdges"
14
+ />
15
+ <rect
16
+ x="8.19637"
17
+ y="8.69637"
18
+ width="71.03"
19
+ height="71.03"
20
+ rx="35.515"
21
+ stroke="url(#paint1_linear_10359_4283)"
22
+ stroke-width="1.39275"
23
+ shape-rendering="crispEdges"
24
+ />
25
+ <path
26
+ d="M34.6871 29.2702C37.3282 27.8148 40.3611 26.987 43.5867 26.987C47.0527 26.987 50.2964 27.9428 53.0703 29.6061C52.9841 24.5814 48.8993 20.5347 43.8728 20.5347C38.9589 20.5347 34.9449 24.4022 34.6871 29.2702Z"
27
+ fill="#73F36C"
28
+ />
29
+ <path
30
+ d="M61.9247 48.1844C62.0439 47.3321 62.1056 46.4612 62.1056 45.5758C62.1056 39.9145 59.5843 34.8444 55.6074 31.4349C55.7426 31.3415 55.8855 31.2593 56.0359 31.1891C58.6171 29.9842 62.4476 32.759 64.5915 37.3868C66.7355 42.0145 66.381 46.7428 63.7998 47.9476C63.2258 48.2156 62.59 48.2867 61.9247 48.1844Z"
31
+ fill="#73F36C"
32
+ />
33
+ <path
34
+ d="M49.4152 63.2252C54.8437 61.4199 59.1587 57.1616 61.0565 51.7588C61.7421 53.8589 61.416 56.9595 59.9999 60.0162C57.8559 64.6439 54.0254 67.4187 51.4442 66.2138C50.391 65.7222 49.7085 64.6439 49.4152 63.2252Z"
35
+ fill="#73F36C"
36
+ />
37
+ <path
38
+ d="M26.2523 52.1315C28.2428 57.4318 32.5769 61.5788 37.9865 63.2995C37.6841 64.6775 37.0078 65.7236 35.9751 66.2056C33.3939 67.4105 29.5634 64.6357 27.4194 60.008C26.0866 57.1311 25.7193 54.2154 26.2523 52.1315Z"
39
+ fill="#73F36C"
40
+ />
41
+ <path
42
+ d="M31.6668 31.349C27.6317 34.7589 25.0678 39.8668 25.0678 45.5758C25.0678 46.4742 25.1313 47.3578 25.254 48.2222C24.6761 48.2748 24.124 48.1913 23.6196 47.9559C21.0384 46.751 20.6839 42.0228 22.8279 37.395C24.9718 32.7673 28.8023 29.9925 31.3835 31.1974C31.4812 31.243 31.5756 31.2936 31.6668 31.349Z"
43
+ fill="#73F36C"
44
+ />
45
+ <path
46
+ d="M39.6853 53.4068C40.058 52.892 40.6537 52.5874 41.2876 52.5875L46.1925 52.5876C46.8264 52.5876 47.422 52.8921 47.7947 53.4068L50.8539 57.6315C51.519 58.55 51.2894 59.8539 50.2825 60.3714C46.4401 62.3463 42.3705 62.6008 37.393 60.3329C36.3127 59.8407 36.0176 58.4719 36.7152 57.5086L39.6853 53.4068Z"
47
+ fill="#73F36C"
48
+ />
49
+ <path
50
+ d="M49.985 51.6751C49.6093 51.1588 49.5038 50.4927 49.7016 49.8849L51.238 45.1637C51.4349 44.5586 51.9085 44.0848 52.5119 43.8891L57.4894 42.2746C58.5908 41.9173 59.7728 42.5815 59.8858 43.7378C59.9368 44.2608 59.963 44.7911 59.963 45.3275C59.9631 48.3548 59.963 49.6928 57.7854 53.45C57.2304 54.4078 56.5793 55.3026 55.8462 56.123C55.0748 56.9861 53.7331 56.8254 53.0517 55.8891L49.985 51.6751Z"
51
+ fill="#73F36C"
52
+ />
53
+ <path
54
+ d="M56.6678 39.8485C57.7673 39.4878 58.3347 38.2546 57.7523 37.2515C57.3454 36.5507 56.8884 35.8831 56.3861 35.2539C56.3092 35.1576 56.2419 35.0548 56.1752 34.9513C55.2007 33.4387 51.6044 30.8455 49.9469 30.3589C49.8438 30.3286 49.7411 30.2975 49.6412 30.2581C48.859 29.9496 48.0473 29.7006 47.2116 29.5166C46.0799 29.2673 45.085 30.1927 45.0849 31.3557L45.0845 36.6302C45.0845 37.2649 45.3863 37.8615 45.8969 38.2359L49.9259 41.1903C50.4403 41.5675 51.1041 41.6734 51.7097 41.4748L56.6678 39.8485Z"
55
+ fill="#73F36C"
56
+ />
57
+ <path
58
+ d="M31.6337 56.1229C30.9006 55.3026 30.2494 54.4077 29.6943 53.4499C28.1573 50.9571 27.5167 48.1968 27.5167 45.3272C27.5167 44.7909 27.5429 44.2606 27.594 43.7377C27.707 42.5814 28.8891 41.9173 29.9905 42.2745L34.9679 43.889C35.5713 44.0847 36.0449 44.5585 36.2418 45.1636L37.7781 49.885C37.9759 50.4928 37.8704 51.1589 37.4947 51.6751L34.4283 55.889C33.7469 56.8253 32.4051 56.9861 31.6337 56.1229Z"
59
+ fill="#73F36C"
60
+ />
61
+ <path
62
+ d="M35.7706 41.4748C36.3761 41.6734 37.0399 41.5675 37.5543 41.1903L41.5832 38.2361C42.0937 37.8617 42.3956 37.2651 42.3955 36.6304L42.3951 31.356C42.395 30.1929 41.4003 29.2762 40.2725 29.5431C39.39 29.7519 38.5318 30.026 37.6893 30.3181C34.9542 31.2662 32.4593 33.5809 31.2103 35.1101C30.6621 35.7811 30.1659 36.497 29.7278 37.2515C29.1454 38.2546 29.7128 39.4877 30.8122 39.8483L35.7706 41.4748Z"
63
+ fill="#73F36C"
64
+ />
65
+ <path
66
+ d="M42.0281 49.8882C41.1669 49.8882 40.4043 49.3297 40.1417 48.5064L39.0647 45.1309C38.8054 44.3183 39.0916 43.4302 39.7759 42.9239L42.5646 40.861C43.2634 40.344 44.2161 40.344 44.9149 40.861L47.7035 42.9239C48.3879 43.4302 48.6741 44.3183 48.4148 45.1309L47.3378 48.5064C47.0751 49.3297 46.3126 49.8882 45.4514 49.8882H42.0281Z"
67
+ fill="#73F36C"
68
+ />
69
+ </g>
70
+ <defs>
71
+ <filter
72
+ id="filter0_di_10359_4283"
73
+ x="0.257725"
74
+ y="0.757725"
75
+ width="86.9074"
76
+ height="86.9074"
77
+ filterUnits="userSpaceOnUse"
78
+ color-interpolation-filters="sRGB"
79
+ >
80
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
81
+ <feColorMatrix
82
+ in="SourceAlpha"
83
+ type="matrix"
84
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
85
+ result="hardAlpha"
86
+ />
87
+ <feOffset />
88
+ <feGaussianBlur stdDeviation="3.62114" />
89
+ <feComposite in2="hardAlpha" operator="out" />
90
+ <feColorMatrix
91
+ type="matrix"
92
+ values="0 0 0 0 0.45098 0 0 0 0 0.952941 0 0 0 0 0.423529 0 0 0 0.34 0"
93
+ />
94
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_10359_4283" />
95
+ <feBlend
96
+ mode="normal"
97
+ in="SourceGraphic"
98
+ in2="effect1_dropShadow_10359_4283"
99
+ result="shape"
100
+ />
101
+ <feColorMatrix
102
+ in="SourceAlpha"
103
+ type="matrix"
104
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
105
+ result="hardAlpha"
106
+ />
107
+ <feOffset />
108
+ <feGaussianBlur stdDeviation="3" />
109
+ <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
110
+ <feColorMatrix
111
+ type="matrix"
112
+ values="0 0 0 0 0.45098 0 0 0 0 0.952941 0 0 0 0 0.423529 0 0 0 1 0"
113
+ />
114
+ <feBlend mode="normal" in2="shape" result="effect2_innerShadow_10359_4283" />
115
+ </filter>
116
+ <linearGradient
117
+ id="paint0_linear_10359_4283"
118
+ x1="7.5"
119
+ y1="44.2114"
120
+ x2="79.9228"
121
+ y2="44.2114"
122
+ gradientUnits="userSpaceOnUse"
123
+ >
124
+ <stop stop-color="#121312" />
125
+ <stop offset="1" stop-color="#73F36C" stop-opacity="0" />
126
+ </linearGradient>
127
+ <linearGradient
128
+ id="paint1_linear_10359_4283"
129
+ x1="12.5736"
130
+ y1="7.99998"
131
+ x2="47.0785"
132
+ y2="87.4357"
133
+ gradientUnits="userSpaceOnUse"
134
+ >
135
+ <stop stop-color="white" stop-opacity="0.4" />
136
+ <stop offset="0.405687" stop-color="white" stop-opacity="0.01" />
137
+ <stop offset="0.574372" stop-color="white" stop-opacity="0.01" />
138
+ <stop offset="1" stop-color="white" stop-opacity="0.1" />
139
+ </linearGradient>
140
+ </defs>
141
+ </svg>
142
+ );
143
+ };
@@ -0,0 +1,108 @@
1
+ export const UpdateIcon = ({ className }: { className?: string }) => (
2
+ <svg
3
+ width="25"
4
+ height="24"
5
+ viewBox="0 0 25 24"
6
+ fill="none"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ className={className}
9
+ >
10
+ <g clip-path="url(#clip0_223_2)">
11
+ <g filter="url(#filter0_i_223_2)">
12
+ <path
13
+ d="M24.6357 12C24.6357 5.37258 19.2632 0 12.6357 0C6.00832 0 0.635742 5.37258 0.635742 12C0.635742 18.6274 6.00832 24 12.6357 24C19.2632 24 24.6357 18.6274 24.6357 12Z"
14
+ fill="url(#paint0_linear_223_2)"
15
+ fill-opacity="0.6"
16
+ />
17
+ <path
18
+ d="M12.6358 0.288454H12.6357C6.16761 0.288454 0.924196 5.53187 0.924196 12V12.0001C0.924196 18.4681 6.16761 23.7116 12.6357 23.7116H12.6358C19.1039 23.7116 24.3473 18.4681 24.3473 12.0001V12C24.3473 5.53187 19.1039 0.288454 12.6358 0.288454Z"
19
+ stroke="url(#paint1_linear_223_2)"
20
+ stroke-width="0.576907"
21
+ />
22
+ <path
23
+ d="M7.93685 14.9376C7.12435 15.6201 6.85352 17.6459 6.85352 17.6459C6.85352 17.6459 8.87935 17.3751 9.56185 16.5626C9.94643 16.1076 9.94102 15.4088 9.5131 14.9863C9.30256 14.7853 9.02522 14.6692 8.7343 14.6602C8.44339 14.6512 8.15941 14.75 7.93685 14.9376Z"
24
+ stroke="#73F36C"
25
+ stroke-width="0.846154"
26
+ stroke-linecap="round"
27
+ stroke-linejoin="round"
28
+ />
29
+ <path
30
+ d="M11.999 14.1248L10.374 12.4998C10.6623 11.752 11.0252 11.0352 11.4574 10.3602C12.0885 9.35109 12.9673 8.52021 14.0102 7.94661C15.0531 7.37301 16.2255 7.07576 17.4157 7.08314C17.4157 8.55648 16.9932 11.1456 14.1657 13.0415C13.4815 13.4741 12.7556 13.837 11.999 14.1248Z"
31
+ stroke="#73F36C"
32
+ stroke-width="0.846154"
33
+ stroke-linecap="round"
34
+ stroke-linejoin="round"
35
+ />
36
+ <path
37
+ d="M10.3739 12.4999H7.66553C7.66553 12.4999 7.96344 10.8587 8.74886 10.3332C9.62636 9.74824 11.4572 10.3332 11.4572 10.3332"
38
+ stroke="#73F36C"
39
+ stroke-width="0.846154"
40
+ stroke-linecap="round"
41
+ stroke-linejoin="round"
42
+ />
43
+ <path
44
+ d="M11.999 14.1248V16.8332C11.999 16.8332 13.6403 16.5353 14.1657 15.7498C14.7507 14.8723 14.1657 13.0415 14.1657 13.0415"
45
+ stroke="#73F36C"
46
+ stroke-width="0.846154"
47
+ stroke-linecap="round"
48
+ stroke-linejoin="round"
49
+ />
50
+ </g>
51
+ </g>
52
+ <defs>
53
+ <filter
54
+ id="filter0_i_223_2"
55
+ x="0.635742"
56
+ y="0"
57
+ width="24"
58
+ height="24"
59
+ filterUnits="userSpaceOnUse"
60
+ color-interpolation-filters="sRGB"
61
+ >
62
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
63
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
64
+ <feColorMatrix
65
+ in="SourceAlpha"
66
+ type="matrix"
67
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
68
+ result="hardAlpha"
69
+ />
70
+ <feOffset />
71
+ <feGaussianBlur stdDeviation="1.24267" />
72
+ <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
73
+ <feColorMatrix
74
+ type="matrix"
75
+ values="0 0 0 0 0.45098 0 0 0 0 0.952941 0 0 0 0 0.423529 0 0 0 1 0"
76
+ />
77
+ <feBlend mode="normal" in2="shape" result="effect1_innerShadow_223_2" />
78
+ </filter>
79
+ <linearGradient
80
+ id="paint0_linear_223_2"
81
+ x1="0.635742"
82
+ y1="12"
83
+ x2="24.6357"
84
+ y2="12"
85
+ gradientUnits="userSpaceOnUse"
86
+ >
87
+ <stop stop-color="#121312" />
88
+ <stop offset="1" stop-color="#73F36C" stop-opacity="0" />
89
+ </linearGradient>
90
+ <linearGradient
91
+ id="paint1_linear_223_2"
92
+ x1="2.31706"
93
+ y1="-5.57125e-06"
94
+ x2="13.7516"
95
+ y2="26.324"
96
+ gradientUnits="userSpaceOnUse"
97
+ >
98
+ <stop stop-color="white" stop-opacity="0.4" />
99
+ <stop offset="0.405687" stop-color="white" stop-opacity="0.01" />
100
+ <stop offset="0.574372" stop-color="white" stop-opacity="0.01" />
101
+ <stop offset="1" stop-color="white" stop-opacity="0.1" />
102
+ </linearGradient>
103
+ <clipPath id="clip0_223_2">
104
+ <rect width="25" height="24" fill="white" />
105
+ </clipPath>
106
+ </defs>
107
+ </svg>
108
+ );
@@ -0,0 +1,86 @@
1
+ export const WarningIcon = ({ className }: { className?: string }) => (
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="25"
5
+ height="24"
6
+ viewBox="0 0 25 24"
7
+ fill="none"
8
+ className={className}
9
+ >
10
+ <g filter="url(#filter0_i_11400_35620)">
11
+ <rect
12
+ x="0.635742"
13
+ width="24"
14
+ height="24"
15
+ rx="12"
16
+ fill="url(#paint0_linear_11400_35620)"
17
+ fill-opacity="0.6"
18
+ />
19
+ <rect
20
+ x="0.924196"
21
+ y="0.288454"
22
+ width="23.4231"
23
+ height="23.4231"
24
+ rx="11.7115"
25
+ stroke="url(#paint1_linear_11400_35620)"
26
+ stroke-width="0.576907"
27
+ />
28
+ <path
29
+ d="M18.3927 15.5487L13.8966 6.55226C13.7253 6.21349 13.3781 6 12.999 6C12.6198 6 12.2726 6.21349 12.1013 6.55226L7.60521 15.5487C7.44943 15.8599 7.46596 16.2292 7.64879 16.5249C7.83212 16.8211 8.15521 17.0005 8.50285 17H17.4952C17.8428 17.0005 18.1659 16.8211 18.3493 16.5249C18.5321 16.2292 18.5485 15.8599 18.3927 15.5487ZM17.6674 16.102C17.6298 16.1611 17.5652 16.1972 17.4951 16.1982H8.50271C8.43259 16.1972 8.36797 16.1611 8.33039 16.102C8.29783 16.0418 8.29783 15.9697 8.33039 15.9095L12.8186 6.9091C12.8541 6.84245 12.9232 6.80085 12.9989 6.80085C13.0745 6.80085 13.1436 6.84245 13.1792 6.9091L17.6753 15.9095C17.7059 15.9707 17.7029 16.0433 17.6674 16.102ZM13.3997 14.5945C13.3997 14.7569 13.302 14.9027 13.1522 14.9649C13.0024 15.027 12.8301 14.9924 12.7154 14.8782C12.6012 14.7634 12.5666 14.591 12.6288 14.4412C12.6909 14.2913 12.8366 14.1936 12.9989 14.1936C13.1051 14.1936 13.2073 14.2357 13.2824 14.3109C13.3576 14.3861 13.3997 14.4883 13.3997 14.5945ZM13.3997 10.1845V12.9909C13.3997 13.2124 13.2203 13.3918 12.9989 13.3918C12.7775 13.3918 12.5982 13.2124 12.5982 12.9909V10.1845C12.5982 9.963 12.7775 9.7836 12.9989 9.7836C13.2203 9.7836 13.3997 9.963 13.3997 10.1845Z"
30
+ fill="#F7931A"
31
+ />
32
+ </g>
33
+ <defs>
34
+ <filter
35
+ id="filter0_i_11400_35620"
36
+ x="0.635742"
37
+ y="0"
38
+ width="24"
39
+ height="24"
40
+ filterUnits="userSpaceOnUse"
41
+ color-interpolation-filters="sRGB"
42
+ >
43
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
44
+ <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
45
+ <feColorMatrix
46
+ in="SourceAlpha"
47
+ type="matrix"
48
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
49
+ result="hardAlpha"
50
+ />
51
+ <feOffset />
52
+ <feGaussianBlur stdDeviation="1.24267" />
53
+ <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
54
+ <feColorMatrix
55
+ type="matrix"
56
+ values="0 0 0 0 0.968627 0 0 0 0 0.576471 0 0 0 0 0.101961 0 0 0 0.8 0"
57
+ />
58
+ <feBlend mode="normal" in2="shape" result="effect1_innerShadow_11400_35620" />
59
+ </filter>
60
+ <linearGradient
61
+ id="paint0_linear_11400_35620"
62
+ x1="0.635742"
63
+ y1="12"
64
+ x2="24.6357"
65
+ y2="12"
66
+ gradientUnits="userSpaceOnUse"
67
+ >
68
+ <stop stop-color="#121312" />
69
+ <stop offset="1" stop-color="#F7931A" stop-opacity="0" />
70
+ </linearGradient>
71
+ <linearGradient
72
+ id="paint1_linear_11400_35620"
73
+ x1="2.31706"
74
+ y1="-5.32127e-06"
75
+ x2="13.7516"
76
+ y2="26.324"
77
+ gradientUnits="userSpaceOnUse"
78
+ >
79
+ <stop stop-color="white" stop-opacity="0.4" />
80
+ <stop offset="0.405687" stop-color="white" stop-opacity="0.01" />
81
+ <stop offset="0.574372" stop-color="white" stop-opacity="0.01" />
82
+ <stop offset="1" stop-color="white" stop-opacity="0.1" />
83
+ </linearGradient>
84
+ </defs>
85
+ </svg>
86
+ );
@@ -4,5 +4,6 @@ export * from "./swap-details";
4
4
  export * from "./route-details";
5
5
  export * from "./token-selector";
6
6
  export * from "./slippage-selector";
7
-
7
+ export * from "./tabs";
8
+ export * from "./widget";
8
9
  export * from "./opportunity";
@@ -1,7 +1,11 @@
1
1
  export * from "./opportunity-apr";
2
2
  export * from "./opportunity-rate-estimator";
3
3
  export * from "./opportunity-section";
4
- export * from "./opportunity-item";
5
4
  export * from "./opportunity-disclaimer";
6
5
  export * from "./opportunity-type";
7
6
  export * from "./opportunity-selector";
7
+ export * from "./opportunity-list";
8
+
9
+ // Re-export OpportunityItem from widget folder
10
+ export { OpportunityItem } from "../widget/opportunity-item";
11
+ export type { OpportunityItemProps } from "../widget/opportunity-item";
@@ -1,42 +1,125 @@
1
1
  import React from "react";
2
- import { HoverCard, HoverCardContent, HoverCardTrigger } from "../../ui/hover-card";
2
+ import {
3
+ HoverCard,
4
+ HoverCardContent,
5
+ HoverCardTrigger,
6
+ } from "../../ui/hover-card";
3
7
  import { InfoIcon } from "lucide-react";
4
- import { Separator } from "../../ui";
8
+ import { LabelWithIcon, Separator } from "../../ui";
9
+ import NumberFlow, { type Value } from "@number-flow/react";
5
10
 
11
+ // TODO: Extract aprBreakdown to a type
6
12
  interface OpportunityAprProps {
7
- apr: string;
13
+ apr: Value;
8
14
  aprBreakdown: {
15
+ iconUrl: string;
9
16
  name: string;
17
+ description: string;
10
18
  apr: string;
19
+ boost: boolean;
11
20
  }[];
21
+ showBoostedRewardsDescription?: boolean;
22
+ showBoostedRewards?: boolean;
12
23
  }
13
24
 
14
- const OpportunityApr = ({ apr, aprBreakdown }: OpportunityAprProps) => {
25
+ const OpportunityApr = ({
26
+ apr,
27
+ aprBreakdown,
28
+ showBoostedRewards = false,
29
+ showBoostedRewardsDescription = false,
30
+ }: OpportunityAprProps) => {
31
+ const boostedRewards = aprBreakdown.filter((item) => item.boost);
15
32
  return (
16
33
  <HoverCard>
17
34
  <HoverCardTrigger asChild>
18
- <span className="text-2xl text-accent font-semibold inline-flex items-center gap-1">
19
- {apr} <InfoIcon size={16} className="text-muted-foreground font-bold" />
35
+ <span className="text-accent inline-flex items-center gap-1 text-2xl font-semibold">
36
+ <NumberFlow
37
+ value={apr}
38
+ format={{
39
+ style: "percent",
40
+ minimumFractionDigits: 2,
41
+ maximumFractionDigits: 2,
42
+ }}
43
+ />
44
+ <InfoIcon
45
+ size={16}
46
+ className="text-muted-foreground cursor-pointer font-bold"
47
+ />
20
48
  </span>
21
49
  </HoverCardTrigger>
22
50
  <HoverCardContent>
51
+ <h3 className="text-accent text-sm">Rewards</h3>
23
52
  <div className="flex flex-col gap-2">
24
- {aprBreakdown.map((item) => (
25
- <div key={item.name} className="flex justify-between">
26
- <span className="text-sm text-muted-foreground">{item.name}</span>
27
- <span className="text-sm text-accent font-semibold">{item.apr}</span>
28
- </div>
29
- ))}
53
+ {aprBreakdown
54
+ .filter((item) => !item.boost)
55
+ .map((item) => (
56
+ <div key={item.name} className="flex justify-between">
57
+ <LabelWithIcon
58
+ textSize="xs"
59
+ icon={item.iconUrl}
60
+ iconSize="sm"
61
+ className="text-muted-foreground"
62
+ >
63
+ {item.name}
64
+ </LabelWithIcon>
65
+ <span className="text-accent text-sm font-semibold">
66
+ <NumberFlow
67
+ value={parseFloat(item.apr) / 100}
68
+ format={{
69
+ style: "percent",
70
+ minimumFractionDigits: 2,
71
+ maximumFractionDigits: 3,
72
+ }}
73
+ />
74
+ </span>
75
+ </div>
76
+ ))}
30
77
  <Separator />
31
78
  <div className="flex justify-between">
32
- <span className="text-sm text-accent">Net Reward Rate</span>
33
- <span className="text-sm text-accent font-semibold">{apr}</span>
79
+ <span className="text-accent text-sm">Net Reward Rate</span>
80
+ <span className="text-accent text-sm font-semibold">
81
+ <NumberFlow
82
+ value={apr}
83
+ format={{
84
+ style: "percent",
85
+ minimumFractionDigits: 3,
86
+ maximumFractionDigits: 3,
87
+ }}
88
+ />
89
+ </span>
34
90
  </div>
35
- <p className="text-sm text-muted-foreground text-center">
91
+ {showBoostedRewards && boostedRewards.length > 0 && (
92
+ <>
93
+ <Separator />
94
+ <h3 className="text-accent text-sm">Boosted Rewards</h3>
95
+ <div className="flex justify-between">
96
+ <span className="text-accent text-sm font-semibold">
97
+ {boostedRewards.map((item) => (
98
+ <div key={item.name} className="flex flex-col gap-2">
99
+ <LabelWithIcon
100
+ textSize="xs"
101
+ icon={item.iconUrl}
102
+ iconSize="sm"
103
+ className="text-muted-foreground"
104
+ >
105
+ {item.description}
106
+ </LabelWithIcon>
107
+ {showBoostedRewardsDescription && item.description && (
108
+ <span className="text-muted-foreground text-xs">
109
+ {item.description}
110
+ </span>
111
+ )}
112
+ </div>
113
+ ))}
114
+ </span>
115
+ </div>
116
+ </>
117
+ )}
118
+ {/* <p className="text-sm text-muted-foreground text-center">
36
119
  All reward amounts displayed in this app are the amounts after fees, please note that
37
120
  the reward rate is not guaranteed and may change over time. The APR is the annualized
38
121
  return on investment for the opportunity.
39
- </p>
122
+ </p> */}
40
123
  </div>
41
124
  </HoverCardContent>
42
125
  </HoverCard>
@@ -0,0 +1,2 @@
1
+ export * from "./use-opportunity-filtering";
2
+ export * from "./use-opportunity-grouping";
@@ -0,0 +1,45 @@
1
+ import { useMemo } from "react";
2
+ import { OpportunityFilter } from "../opportunity-list";
3
+ import { OpportunityItemValue as Opportunity } from "../../../widget/opportunity-item";
4
+
5
+ interface UseOpportunityFilteringProps {
6
+ opportunities: Opportunity[];
7
+ searchQuery: string;
8
+ activeFilterIds: string[];
9
+ filters: OpportunityFilter[];
10
+ }
11
+
12
+ export function useOpportunityFiltering({
13
+ opportunities,
14
+ searchQuery,
15
+ activeFilterIds,
16
+ filters,
17
+ }: UseOpportunityFilteringProps): Opportunity[] {
18
+ return useMemo(() => {
19
+ let result = opportunities;
20
+
21
+ // Apply search filter
22
+ if (searchQuery) {
23
+ const query = searchQuery.toLowerCase();
24
+ result = result.filter(
25
+ (opportunity) =>
26
+ opportunity.name.toLowerCase().includes(query) ||
27
+ opportunity.partner?.name.toLowerCase().includes(query) ||
28
+ opportunity.chain.name.toLowerCase().includes(query)
29
+ );
30
+ }
31
+
32
+ // Apply active filters
33
+ if (activeFilterIds.length > 0) {
34
+ const activeFilterFns = filters
35
+ .filter((f) => activeFilterIds.includes(f.id))
36
+ .map((f) => f.filterFn);
37
+
38
+ result = result.filter((opportunity) =>
39
+ activeFilterFns.every((filterFn) => filterFn(opportunity))
40
+ );
41
+ }
42
+
43
+ return result;
44
+ }, [opportunities, searchQuery, activeFilterIds, filters]);
45
+ }
@@ -0,0 +1,81 @@
1
+ import { useMemo } from "react";
2
+ import { OpportunityItemValue } from "../../../widget/opportunity-item";
3
+ import { WidgetListGroup } from "../../../widget/widget-list-items";
4
+
5
+ interface UseOpportunityGroupingProps {
6
+ opportunities: OpportunityItemValue[];
7
+ groupBy: "none" | "partner" | "chain";
8
+ }
9
+
10
+ export function useOpportunityGrouping({
11
+ opportunities,
12
+ groupBy,
13
+ }: UseOpportunityGroupingProps): WidgetListGroup<OpportunityItemValue>[] {
14
+ return useMemo(() => {
15
+ // First, sort all opportunities by yield (APY) in descending order
16
+ const sortedOpportunities = [...opportunities].sort((a, b) => {
17
+ const aprA = parseFloat(a.apr?.replace("%", "") || "0");
18
+ const aprB = parseFloat(b.apr?.replace("%", "") || "0");
19
+ return aprB - aprA;
20
+ });
21
+
22
+ if (groupBy === "none") {
23
+ return [
24
+ {
25
+ id: "all-opportunities",
26
+ items: sortedOpportunities,
27
+ },
28
+ ];
29
+ }
30
+
31
+ // Group by the selected field
32
+ const groups = sortedOpportunities.reduce(
33
+ (acc, opportunity) => {
34
+ let groupKey: string;
35
+ let groupTitle: string;
36
+ let groupIcon: string | undefined;
37
+
38
+ switch (groupBy) {
39
+ case "partner":
40
+ groupKey = opportunity.partner?.name || "other";
41
+ groupTitle = opportunity.partner?.name || "Other";
42
+ groupIcon = opportunity.partner?.icon;
43
+ break;
44
+ case "chain":
45
+ groupKey = opportunity.chain.name || "other";
46
+ groupTitle = opportunity.chain.name || "Other";
47
+ groupIcon = opportunity.chain.icon;
48
+ break;
49
+ default:
50
+ groupKey = "all";
51
+ groupTitle = "All";
52
+ }
53
+
54
+ if (!acc[groupKey]) {
55
+ acc[groupKey] = {
56
+ id: groupKey,
57
+ title: groupTitle,
58
+ icon: groupIcon,
59
+ items: [],
60
+ };
61
+ }
62
+ acc[groupKey].items.push(opportunity);
63
+ return acc;
64
+ },
65
+ {} as Record<string, WidgetListGroup<OpportunityItemValue>>
66
+ );
67
+
68
+ // Sort groups by the highest APY in each group
69
+ const groupsArray = Object.values(groups);
70
+ groupsArray.sort((a, b) => {
71
+ // Get the highest APY in each group (items are already sorted)
72
+ const maxYieldA =
73
+ a.items.length > 0 ? parseFloat(a.items[0].apr?.replace("%", "") || "0") : 0;
74
+ const maxYieldB =
75
+ b.items.length > 0 ? parseFloat(b.items[0].apr?.replace("%", "") || "0") : 0;
76
+ return maxYieldB - maxYieldA;
77
+ });
78
+
79
+ return groupsArray;
80
+ }, [opportunities, groupBy]);
81
+ }
@@ -0,0 +1 @@
1
+ export * from "./opportunity-list";