From 4ea4e6a33b2d80be88fa80970c0b1191cf68b364 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Mon, 3 Aug 2026 17:37:35 +0200 Subject: [PATCH] feat: protocol above rankings + badges + compare on /perp/[slug] --- src/app/perp/[slug]/page.tsx | 235 +++++++++++++++++++++++++++-------- 1 file changed, 182 insertions(+), 53 deletions(-) diff --git a/src/app/perp/[slug]/page.tsx b/src/app/perp/[slug]/page.tsx index 102abfe0..df39417c 100644 --- a/src/app/perp/[slug]/page.tsx +++ b/src/app/perp/[slug]/page.tsx @@ -352,6 +352,60 @@ export default async function PerpVenuePage({ )} + {/* Vault / Protocol */} + {hasVault && ( +
+

+ Protocol +

+
+ {ext.vaultTvlUsd != null && ( + + )} + {ext.stakingAprPct != null && ( + + )} +
+ + {/* Collateral breakdown table */} + {(ext.collateralBreakdown?.length ?? 0) > 0 && ( +
+ + + + + + + + + + {ext.collateralBreakdown!.map((cr) => ( + + + + + + ))} + +
+ Collateral + + TVL + + APR +
{cr.symbol} + {fmtUSD(cr.tvlUsd)} + + {fmtPct(cr.aprPct)} +
+
+ )} +
+ )} + {/* Live benchmark results */} {rankings.length > 0 && (
@@ -429,59 +483,134 @@ export default async function PerpVenuePage({
)} - {/* Vault / Protocol */} - {hasVault && ( -
-

- Protocol -

-
- {ext.vaultTvlUsd != null && ( - - )} - {ext.stakingAprPct != null && ( - - )} -
- - {/* Collateral breakdown table */} - {(ext.collateralBreakdown?.length ?? 0) > 0 && ( -
- - - - - - - - - - {ext.collateralBreakdown!.map((cr) => ( - - - - - - ))} - -
- Collateral - - TVL - - APR -
{cr.symbol} - {fmtUSD(cr.tvlUsd)} - - {fmtPct(cr.aprPct)} -
-
- )} -
- )} + {/* Embeddable badges — only for rank #1 appearances */} + {(() => { + const winnerRankings = rankings.filter((a) => a.rank === 1 && a.hasData); + if (winnerRankings.length === 0) return null; + return ( +
+

+ Embeddable badges +

+

+ Drop these on your site to show your ranking. The SVG fetches the + latest figures on every request so the badge stays accurate without + redeploying. +

+ +
+ ); + })()} + + {/* Compare to other perp venues */} + {(() => { + const otherVenues = PERP_VENUES + .filter((v) => v.slug !== cohortSlug) + .map((v) => { + const sharedCount = (benchBlobs as (Benchmark | null)[]).filter( + (b) => b && b.results.some((r) => r.slug === v.slug), + ).length; + return { ...v, sharedCount }; + }) + .filter((v) => v.sharedCount > 0) + .sort((a, b) => b.sharedCount - a.sharedCount); + if (otherVenues.length === 0) return null; + return ( +
+

+ Compare {seed.name} to alternatives +

+

+ Other perp venues benchmarked on the same metrics. +

+ +
+ ); + })()} {/* Footer links */}