-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(bridge): testimonials + bridge now sections #17
Changes from all commits
9ac63e1
33a5c1a
9d9cd6e
27467b3
1fabc4a
22ac559
46ef893
4ad66d8
16e734a
47d60a2
fd892c8
8d9854a
b0b2b17
cf6aafa
82b7dc0
17cb58a
714922d
072bb82
75ef501
fc70a57
e97f8ce
0d0dfad
366def7
22cd842
ccb27f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,14 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = {}; | ||
const nextConfig = { | ||
images: { | ||
remotePatterns: [ | ||
{ | ||
protocol: "https", | ||
hostname: "pbs.twimg.com", | ||
pathname: "**", | ||
}, | ||
], | ||
}, | ||
}; | ||
|
||
export default nextConfig; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Image from "next/image"; | ||
|
||
import { Text } from "@/app/_components/text"; | ||
import { BridgeNowLink } from "@/app/_components/bridge-now-link"; | ||
import { Button } from "@/app/_components/button"; | ||
import bridgeHeroImage from "@/app/_assets/bridge-hero.png"; | ||
|
||
export function BridgeNowSection() { | ||
return ( | ||
<section className="container mx-auto flex flex-col items-center gap-16 sm:gap-24"> | ||
<Image | ||
src={bridgeHeroImage} | ||
alt="screenshot of bridge ui" | ||
className=" max-w-[357px]" | ||
/> | ||
<Text | ||
variant="heading-1" | ||
className="text-center capitalize text-light-100 md:tracking-tight-1" | ||
> | ||
experience the bridge | ||
</Text> | ||
<div className="flex flex-row items-center"> | ||
<BridgeNowLink> | ||
<Button className="border-aqua-100 bg-aqua-100/[.05] text-aqua-100"> | ||
<Text variant="cap-case-sm">Bridge now</Text> | ||
</Button> | ||
</BridgeNowLink> | ||
</div> | ||
</section> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
"use client"; | ||
|
||
import Image from "next/image"; | ||
import { useState } from "react"; | ||
|
||
import { TwitterIcon, VerifiedCheckmarkIcon } from "@/app/_components/icons"; | ||
import { Text } from "@/app/_components/text"; | ||
import { twMerge } from "@/app/_lib/tw-merge"; | ||
|
||
const mainTweet = { | ||
title: ( | ||
<> | ||
Lowest fees, Zero slippage, | ||
<br /> | ||
professional team. | ||
</> | ||
), | ||
body: ( | ||
<> | ||
'I've tried every L2 bridge out there. @AcrossProtocol is undoubtedly the | ||
best one. | ||
<br /> | ||
<br /> | ||
Lowest fees, 0 slippage, professional team. Very under-appreciated, use it.' | ||
</> | ||
), | ||
username: "@aradtski", | ||
}; | ||
|
||
const tweets = { | ||
firstColumn: [ | ||
{ | ||
isVerified: true, | ||
displayName: "pray.eth", | ||
username: "@pray_eth", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1692052698307153920/WiHp_6vw_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Yeah, I bridge a lot, noticed @BungeeExchange routes were giving me | ||
@AcrossProtocol most of the time, so just started to use it as my default bridge | ||
(minimizing risk is my primary concern when bridging). | ||
<br /> | ||
<br /> | ||
Transfers are incredibly fast and cheap. Great work! | ||
</> | ||
), | ||
Comment on lines
+39
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I'm not a huge fan of having markdown for each individual tweet. Not sure if there's a better solution, but it feels like it may be unwieldy if we increase the number of tweets. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, I am also not a big fan of this. But that's the best I could come up with. Especially with the Twitter API being highly limited (free version at least) |
||
tweetUrl: "https://x.com/pray_eth/status/1679328596261842944?s=20", | ||
}, | ||
{ | ||
isVerified: false, | ||
displayName: "David Goose", | ||
username: "@davidjgoosey", | ||
tweetUrl: "https://x.com/davidjgoosey/status/1649207665518690304?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1594113194397687816/l2RGYB8y_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Across has one of the best UX of the bridges I've tried to date, keep up | ||
the good work | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: true, | ||
displayName: "Scott BurkΞ", | ||
username: "@scottburke777", | ||
tweetUrl: "https://x.com/scottburke777/status/1656557680012476416?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1618111203586314240/obBfZyuv_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Tried a few Arbitrum bridges over the last few months, just tried | ||
@AcrossProtocol and it was the fastest yet, it was like 1 min Eth -> Arb | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: true, | ||
displayName: "kidponga.eth", | ||
username: "@kidponga", | ||
tweetUrl: "https://x.com/Infinity_1001/status/1749523278228521112?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1692052698307153920/WiHp_6vw_200x200.jpg", | ||
tweet: ( | ||
<> | ||
What's the best bridge in crypto? | ||
<br /> | ||
<br />A bridge that focuses on what users want the most: | ||
<br />- speed | ||
<br />- cost | ||
<br />- trust | ||
<br /> | ||
<br /> | ||
@AcrossProtocol $ACX | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: true, | ||
displayName: "Kisuke Urahara", | ||
username: "@Ivan90403291", | ||
tweetUrl: "https://x.com/Ivan90403291/status/1692120646602391671?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1255439408100265984/JjHosYHZ_200x200.jpg", | ||
tweet: <>@AcrossProtocol is 100% the best bridge</>, | ||
}, | ||
], | ||
secondColumn: [ | ||
{ | ||
isVerified: false, | ||
displayName: "maxlomu", | ||
username: "@maxlomu", | ||
tweetUrl: "https://x.com/maxlomu/status/1675975309835882502?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1620485487466094602/oAWikXJe_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Honestly well done guys. | ||
<br /> | ||
<br /> | ||
Not only Across liquidity model is very capital efficient (so you can be | ||
cheaper), but the architecture (contrary to L0) is actually trust-minimized. | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: true, | ||
displayName: "Andy", | ||
username: "@ayyyeandy", | ||
tweetUrl: "https://x.com/ayyyeandy/status/1726985723285553249?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1687521808331702272/Ky0QmeqD_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Lol. One second to bridge from @arbitrum to @zksync using @AcrossProtocol | ||
<br /> | ||
<br /> | ||
<Image | ||
height={242} | ||
width={302} | ||
alt="Across bridge ui" | ||
src="https://pbs.twimg.com/media/F_d8Rl1XoAA4N8S?format=jpg" | ||
/> | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: false, | ||
displayName: "Infinity", | ||
username: "@Infinity_1001", | ||
// TODO: update tweet url | ||
tweetUrl: "https://x.com/kidponga/status/1750013537379111135?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1687521808331702272/Ky0QmeqD_200x200.jpg", | ||
tweet: ( | ||
<> | ||
Across is without a doubt the best bridge you can use today. | ||
<br /> | ||
<br /> | ||
It is the fastest, most efficient and safest | ||
<br /> | ||
<br /> | ||
Not because I say so, the statistics support it | ||
</> | ||
), | ||
}, | ||
{ | ||
isVerified: false, | ||
displayName: "jaeger 狼", | ||
username: "@carlshuu", | ||
tweetUrl: "https://x.com/carlshuu/status/1742052941480255592?s=20", | ||
profileImageUrl: | ||
"https://pbs.twimg.com/profile_images/1737090443962413056/aHv5T66J_200x200.jpg", | ||
tweet: ( | ||
<> | ||
@AcrossProtocol is so freaking good. It's insane how fast their bridge is. | ||
</> | ||
), | ||
}, | ||
], | ||
}; | ||
|
||
export function TestimonialsSection() { | ||
const [isExpanded, setIsExpanded] = useState(false); | ||
return ( | ||
<section className="container mx-auto"> | ||
<div className="relative"> | ||
<div className="flex flex-col items-center gap-6"> | ||
<Text variant="cap-case" className="text-aqua-100"> | ||
across users say it all | ||
</Text> | ||
<Text variant="heading-2" className="text-center capitalize text-light-200"> | ||
"{mainTweet.title}" | ||
</Text> | ||
<Text | ||
variant="body" | ||
className="max-w-[336px] text-center text-md text-light-300 md:text-lg" | ||
> | ||
{mainTweet.body} | ||
</Text> | ||
<div className="flex h-10 w-40 flex-row items-center justify-between gap-2 rounded-full border border-aqua-100/[.05] bg-aqua-100/[.05] px-4 py-2"> | ||
<Text className="flex-1 text-center text-aqua-100">{mainTweet.username}</Text> | ||
<TwitterIcon className="h-3 w-3 fill-aqua-100" /> | ||
</div> | ||
<div | ||
className={twMerge( | ||
"flex flex-col gap-4 overflow-hidden sm:flex-row md:gap-8", | ||
isExpanded ? "" : "h-[480px]", | ||
)} | ||
> | ||
<div className="flex flex-1 flex-col gap-4"> | ||
{tweets.firstColumn.map((tweet, index) => ( | ||
<TweetCard key={index} tweet={tweet} /> | ||
))} | ||
</div> | ||
<div className="flex flex-1 flex-col gap-4"> | ||
{tweets.secondColumn.map((tweet, index) => ( | ||
<TweetCard key={index} tweet={tweet} /> | ||
))} | ||
</div> | ||
</div> | ||
</div> | ||
{!isExpanded && ( | ||
<div className="absolute bottom-0 h-24 w-full bg-gradient-to-t from-grey-dark to-transparent" /> | ||
)} | ||
</div> | ||
{!isExpanded && ( | ||
<div className="mt-4 flex flex-row justify-center"> | ||
<button | ||
className="flex rounded-full bg-light-100/[.05] px-4 py-2 hover:opacity-75" | ||
onClick={() => setIsExpanded(true)} | ||
> | ||
<Text variant="body-nums" className="text-grey-400"> | ||
View more Tweets | ||
</Text> | ||
</button> | ||
</div> | ||
)} | ||
</section> | ||
); | ||
} | ||
|
||
function TweetCard({ tweet }: { tweet: (typeof tweets.firstColumn)[0] }) { | ||
return ( | ||
<a className="group" href={tweet.tweetUrl} target="_blank" rel="noopener noreferrer"> | ||
<div className="flex cursor-pointer flex-col gap-4 rounded-3xl border border-black-700 p-5 transition group-hover:border-aqua-100/[.05] group-hover:bg-aqua-100/[.05] sm:p-6"> | ||
<div className="flex flex-row items-center gap-3"> | ||
<div className="h-10 w-10 overflow-hidden rounded-full"> | ||
<Image | ||
src={tweet.profileImageUrl} | ||
alt={`${tweet.displayName} profile picture`} | ||
width={40} | ||
height={40} | ||
/> | ||
</div> | ||
<div className="flex flex-col"> | ||
<div className="flex flex-row items-center gap-1"> | ||
<Text variant="body" className="text-aqua-100"> | ||
{tweet.displayName} | ||
</Text> | ||
{tweet.isVerified && <VerifiedCheckmarkIcon />} | ||
</div> | ||
<Text variant="body" className=" text-grey-400"> | ||
{tweet.username} | ||
</Text> | ||
</div> | ||
</div> | ||
<Text variant="body">{tweet.tweet}</Text> | ||
</div> | ||
</a> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { SVGProps } from "react"; | ||
|
||
export function VerifiedCheckmarkIcon(props: SVGProps<SVGSVGElement>) { | ||
return ( | ||
<svg | ||
width="16" | ||
height="16" | ||
viewBox="0 0 16 16" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
{...props} | ||
> | ||
<path | ||
d="M14.8346 8.00008C14.8346 7.04675 14.248 6.22008 13.3746 5.77341C13.6813 4.84675 13.508 3.84008 12.8346 3.16675C12.1613 2.49341 11.1546 2.32008 10.228 2.62675C9.78797 1.75341 8.95464 1.16675 8.0013 1.16675C7.04797 1.16675 6.2213 1.75341 5.7813 2.62675C4.84797 2.32008 3.8413 2.49341 3.16797 3.16675C2.49464 3.84008 2.32797 4.84675 2.63464 5.77341C1.7613 6.22008 1.16797 7.04675 1.16797 8.00008C1.16797 8.95341 1.7613 9.78008 2.63464 10.2267C2.32797 11.1534 2.49464 12.1601 3.16797 12.8334C3.8413 13.5067 4.84797 13.6734 5.77463 13.3734C6.2213 14.2467 7.04797 14.8334 8.0013 14.8334C8.95464 14.8334 9.78797 14.2467 10.228 13.3734C11.1546 13.6734 12.1613 13.5067 12.8346 12.8334C13.508 12.1601 13.6813 11.1534 13.3746 10.2267C14.248 9.78008 14.8346 8.95341 14.8346 8.00008ZM7.02797 10.8001L4.53464 8.30675L5.47464 7.36008L6.9813 8.86675L10.1813 5.38008L11.1613 6.28675L7.02797 10.8001Z" | ||
fill="#6CF9D8" | ||
/> | ||
</svg> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1