Skip to content
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): hero + features sections #15

Merged
merged 24 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/(routes)/_components/hero-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function HeroSection() {
target="_blank"
rel="noopener noreferrer"
>
<Text variant="cap-case">start building</Text>
<Text variant="cap-case-sm">start building</Text>
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-aqua-100">
<ArrowRightIcon />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(routes)/_components/products-section.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { twMerge } from "tailwind-merge";
import { twMerge } from "@/app/_lib/tw-merge";
import Link from "next/link";

import {
Expand Down
57 changes: 4 additions & 53 deletions src/app/(routes)/_components/stats-section.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
import { Text } from "../../_components/text";
import { StatBox } from "../../_components/stat-box";
import { Text } from "@/app/_components/text";
import { StatsRow } from "@/app/_components/stats-row";

import { getProtocolStats } from "../../_lib/scraper";
import { humanReadableNumber } from "../../_lib/format";

async function getFormattedStatsData() {
const protocolStats = await getProtocolStats({
revalidate: 24 * 60 * 60, // Update once a day
});

return {
totalVolumeUsd: `$${humanReadableNumber(protocolStats.totalVolumeUsd)}`,
totalDeposits: `${humanReadableNumber(protocolStats.totalDeposits)}`,
avgFillTimeInMinutes: `${protocolStats.avgFillTimeInMinutes < 1 ? "<" : ""} ${Math.max(
protocolStats.avgFillTimeInMinutes,
1,
)}m`,
bridgeFee: "<$1",
};
}

export async function StatsSection() {
const formattedStatsData = await getFormattedStatsData();
export function StatsSection() {
return (
<section className="container mx-auto flex flex-col gap-10 px-4 sm:gap-16">
<div className="flex flex-col items-center gap-4">
Expand All @@ -38,36 +18,7 @@ export async function StatsSection() {
tradeoffs.
</Text>
</div>
<div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
<StatBox
title="volume"
value={formattedStatsData.totalVolumeUsd}
titleClassName="text-teal-100"
className="group-hover:border-teal-100"
dividerClassName="group-hover:bg-teal-100/[.5]"
/>
<StatBox
title="transaction"
value={formattedStatsData.totalDeposits}
titleClassName="text-orange-100"
className="group-hover:border-orange-100"
dividerClassName="group-hover:bg-orange-100/[.5]"
/>
<StatBox
title="avg. fill time"
value={formattedStatsData.avgFillTimeInMinutes}
titleClassName="text-purple-100"
className="group-hover:border-purple-100"
dividerClassName="group-hover:bg-purple-100/[.5]"
/>
<StatBox
title="bridge 1 eth"
value={formattedStatsData.bridgeFee}
titleClassName="text-aqua-100"
className="group-hover:border-aqua-100"
dividerClassName="group-hover:bg-aqua-100/[.5]"
/>
</div>
<StatsRow />
</section>
);
}
55 changes: 55 additions & 0 deletions src/app/(routes)/across-bridge/_components/features-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Image from "next/image";

import {
CodeIcon,
ShieldLargeIcon,
DoubleChevronRightIcon,
DollarIcon,
} from "@/app/_components/icons";
import { Text } from "@/app/_components/text";
import { FeaturesGrid } from "@/app/_components/features-grid";
import bridge2Image from "@/app/_assets/bridge-2.png";

const features = [
{
Icon: <CodeIcon className="h-14 w-14" />,
title: "efficient",
body: "With Across, bridging your tokens at the fastest speed and lowest cost does not come with security tradeoffs. How? At Across, only bridge users or bridge LPs never shoulder the risks associated with cross-chain transfers.",
},
{
Icon: <ShieldLargeIcon className="h-14 w-14" />,
title: "Secure",
body: "Using canonical assets is the only trustless way to transfer value, which is why Across only circulates genuine tokens, never representative or synthetic assets. In every transfer facilitated by Across, user assets are never put at risk.",
},
{
Icon: <DoubleChevronRightIcon className="h-14 w-14" />,
title: "Fast",
body: "Intents architecture enables the fastest bridge experience. By using a network of third party relayers, incentivized to quickly fill transfers, fill times are usually completed in a few seconds.",
},
{
Icon: <DollarIcon className="h-14 w-14" />,
title: "Superior",
body: "Canonical assets are the only trustless way to transfer value, which is why Across only circulates canonical tokens, never representative or synthetic ones. In every transfer at Across, users always receive canonical assets.",
},
];

export function FeaturesSection() {
return (
<section className="container mx-auto -mt-32 flex flex-col gap-16 px-4 sm:gap-24 md:-mt-48">
<Image
src={bridge2Image}
alt="Across settlement layers graphic"
className="-mb-16 self-center sm:-mb-24 sm:max-w-[514px]"
/>
<div className="flex flex-col gap-4">
<Text variant="cap-case" className="text-center text-aqua-100">
built for safe travels
</Text>
<Text variant="heading-2" className="text-center capitalize text-light-200">
Engineered for best execution
</Text>
</div>
<FeaturesGrid features={features} />
</section>
);
}
42 changes: 42 additions & 0 deletions src/app/(routes)/across-bridge/_components/hero-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Image from "next/image";

import { Hero } from "@/app/_components/hero";
import { Text } from "@/app/_components/text";
import { BridgeNowLink } from "@/app/_components/bridge-now-link";
import { ArrowRightIcon } from "@/app/_components/icons/arrow-right";
import bridgeHeroImage from "@/app/_assets/bridge-hero.png";

export function HeroSection() {
return (
<Hero title="supported chains">
<div className="container mx-auto flex flex-col items-center gap-16 px-4 pb-16 pt-8 md:flex-row-reverse md:gap-8 md:pt-16">
<div className="flex max-w-80 flex-1 sm:max-w-100 md:max-w-full">
<Image src={bridgeHeroImage} alt="Across bridge ui" priority={true} />
</div>
<div className="flex flex-1 flex-col gap-6">
<Text
variant="heading-1"
className="text-center tracking-tight-5 sm:tracking-tight-2 md:text-left md:tracking-tight-1"
>
<span className="text-aqua-100">Bridge</span>{" "}
<span className="text-light-100">Without</span>{" "}
<br className="block sm:hidden md:block" />
<span className="text-aqua-100">Compromise</span>
</Text>
<div className="flex w-full flex-row justify-center md:justify-start">
<Text variant="body-nums" className="max-w-[430px] text-center md:text-left">
Experience extraordinarily fast and cost-effective cross-chain bridging,
secured by an intents-based architecture.
</Text>
</div>
<BridgeNowLink className="flex cursor-pointer flex-row items-center justify-center gap-2 text-aqua-100 md:justify-start">
<Text variant="cap-case">bridge now</Text>
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-aqua-100">
<ArrowRightIcon />
</div>
</BridgeNowLink>
</div>
</div>
</Hero>
);
}
8 changes: 6 additions & 2 deletions src/app/(routes)/across-bridge/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { Metadata } from "next";

import { HeroSection } from "./_components/hero-section";
import { FeaturesSection } from "./_components/features-section";

export const metadata: Metadata = {
title: "Across Bridge",
description: "Interoperability powered by Intents.",
};

export default function BridgeLanding() {
return (
<main className="z-0 min-h-screen overflow-hidden">
<div className="py-10 text-center">Across Bridge</div>
<main className="z-0 mb-24 flex min-h-screen flex-col gap-24 overflow-hidden px-4 sm:gap-32 md:gap-48">
<HeroSection />
<FeaturesSection />
</main>
);
}
26 changes: 12 additions & 14 deletions src/app/(routes)/across-plus/_components/features-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ArrowUpRightThickIcon,
} from "@/app/_components/icons";
import { Text } from "@/app/_components/text";
import { FeaturesGrid } from "@/app/_components/features-grid";
import { INFORMATION_LINKS } from "@/app/_constants";

const features = [
Expand All @@ -27,25 +28,22 @@ const features = [

export function FeaturesSection() {
return (
<section className="container mx-auto flex flex-col gap-16 px-4 sm:gap-24 ">
<section className="container mx-auto flex flex-col gap-16 px-4 sm:gap-24">
<div className="flex flex-col gap-4">
<Text variant="cap-case" className="text-center text-teal-100">
<Text
variant="cap-case"
className="text-center text-xs text-teal-100 sm:text-xs md:text-xs"
>
+users +TVL +chains
</Text>
<Text variant="heading-2" className="text-center capitalize text-light-200">
<Text
variant="heading-2"
className="text-center capitalize tracking-tight-2 text-light-200"
>
Seamless Cross-chain Onboarding
</Text>
</div>
<div className="grid grid-cols-1 gap-12 sm:gap-y-16 md:grid-cols-2">
{features.map((feature) => (
<div key={feature.title}>
{feature.Icon}
<Text variant="heading-4" className="mb-4 mt-8 capitalize text-light-200">
{feature.title}
</Text>
<Text className="text-light-300">{feature.body}</Text>
</div>
))}
<FeaturesGrid features={features}>
<div className="flex flex-col items-center gap-8 rounded-2xl bg-teal-100/[.02] p-6 shadow-md sm:items-start">
<div className="flex flex-col items-center justify-center self-center rounded-lg bg-teal-100/[.05] p-2">
<Text variant="cap-case" className="text-teal-100">
Expand All @@ -72,7 +70,7 @@ export function FeaturesSection() {
</a>
</div>
</div>
</div>
</FeaturesGrid>
</section>
);
}
13 changes: 13 additions & 0 deletions src/app/(routes)/across-plus/_components/get-started-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Image from "next/image";

import { GetStartedSection } from "@/app/_components/get-started-section";
import plusGetStartedImage from "@/app/_assets/plus-get-started.png";

export function PlusGetStartedSection() {
return (
<GetStartedSection
variant="teal"
Image={<Image src={plusGetStartedImage} alt="get started image" />}
/>
);
}
Loading
Loading