Skip to content

Commit

Permalink
fix(home): design, copy tweaks + subscribe section (#20)
Browse files Browse the repository at this point in the history
* fix(ticker): simplify + correct values

* fixup

* fix(home): design, copy tweaks + subscribe section

* fixup

* review requests
  • Loading branch information
dohaki authored Feb 20, 2024
1 parent 9343469 commit ca6ec4f
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 31 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"numeral": "^2.0.6",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.2.1"
"tailwind-merge": "^2.2.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
27 changes: 21 additions & 6 deletions src/app/(routes)/_components/hero-section.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Image from "next/image";

import { PartnersTicker } from "@/app/_components/partners-ticker";
import { Hero } from "../../_components/hero";
import { Text } from "../../_components/text";
import { ArrowRightIcon } from "../../_components/icons/arrow-right";
import landingHeroSrc from "../../_assets/landing-1.png";
import { INFORMATION_LINKS } from "../../_constants";
import { Hero } from "@/app/_components/hero";
import { Text } from "@/app/_components/text";
import { ArrowRightIcon } from "@/app/_components/icons/arrow-right";
import landingHeroSrc from "@/app/_assets/landing-hero.png";
import { INFORMATION_LINKS } from "@/app/_constants";
import { Button } from "@/app/_components/button";
import { BridgeNowLink } from "@/app/_components/bridge-now-link";
import { twMerge } from "@/app/_lib/tw-merge";

export function HeroSection() {
return (
Expand All @@ -15,7 +18,10 @@ export function HeroSection() {
<Image src={landingHeroSrc} alt="Across protocol diagram" priority={true} />
</div>
<div className="flex flex-1 flex-col gap-6">
<Text variant="heading-1" className="text-center md:text-left">
<Text
variant="heading-1"
className="text-center sm:tracking-tight-1 md:text-left"
>
<span className="text-aqua-100">Interoperability</span>
<br />
<span className="text-light-100">Powered By</span>{" "}
Expand All @@ -26,6 +32,15 @@ export function HeroSection() {
A new paradigm in cross-chain experiences, seamlessly connecting users with
applications.
</Text>
<BridgeNowLink>
<Button
className={twMerge(
"hidden border-aqua-100 bg-aqua-100/[.05] text-aqua-100 transition md:block",
)}
>
<Text variant="cap-case-sm">Bridge now</Text>
</Button>
</BridgeNowLink>
<a
className="flex cursor-pointer flex-row items-center justify-center gap-2 text-aqua-100 md:justify-start"
href={INFORMATION_LINKS.docs.href}
Expand Down
20 changes: 10 additions & 10 deletions src/app/(routes)/_components/products-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const products = [
iconContainerClassName: "bg-aqua-100/[.05]",
arrowIconClassName: "stroke-aqua-100",
containerClassName: [
"bg-gradient-to-r from-aqua-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-r md:group-hover:from-aqua-100/[.05] md:group-hover:to-transparent",
"bg-gradient-to-b from-aqua-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-b md:group-hover:from-aqua-100/[.05] md:group-hover:to-transparent",
],
},
{
Expand All @@ -29,8 +29,8 @@ const products = [
iconContainerClassName: "bg-teal-100/[.05]",
arrowIconClassName: "stroke-teal-100",
containerClassName: [
"bg-gradient-to-r from-teal-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-r md:group-hover:from-teal-100/[.05] md:group-hover:to-transparent",
"bg-gradient-to-b from-teal-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-b md:group-hover:from-teal-100/[.05] md:group-hover:to-transparent",
],
},
{
Expand All @@ -40,23 +40,23 @@ const products = [
iconContainerClassName: "bg-purple-100/[.05]",
arrowIconClassName: "stroke-purple-100",
containerClassName: [
"bg-gradient-to-r from-purple-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-r md:group-hover:from-purple-100/[.05] md:group-hover:to-transparent",
"bg-gradient-to-b from-purple-100/[.05] to-transparent",
"md:group-hover:bg-gradient-to-b md:group-hover:from-purple-100/[.05] md:group-hover:to-transparent",
],
},
];

export function ProductsSection() {
return (
<section className="container mx-auto mb-12 flex flex-col gap-16 px-4 sm:gap-24 md:mb-24">
<div className="flex flex-col gap-3 sm:gap-4">
<Text variant="cap-case" className="text-teal-100">
<section className="container mx-auto flex flex-col gap-16 px-4 md:gap-24">
<div className="flex flex-col gap-3 sm:gap-4 md:items-center">
<Text variant="cap-case" className="text-aqua-100">
Solutions
</Text>
<Text variant="heading-2" className="capitalize text-light-200">
Across Products
</Text>
<Text variant="body-nums">
<Text variant="body-nums" className="md:text-center">
Fastest and lowest-cost bridging for end-users.
<br />
Streamlined interoperability for developers.
Expand Down
5 changes: 4 additions & 1 deletion src/app/(routes)/_components/stats-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export function StatsSection() {
<Text variant="cap-case" className="text-aqua-100 md:text-center">
power in originality
</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"
>
Production ready <br />
Empirically Proven
</Text>
Expand Down
12 changes: 6 additions & 6 deletions src/app/(routes)/_components/technology-section.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { ChatIcon, FeatherIcon, BlocksDiagonalIcon } from "../../_components/icons";
import { Text } from "../../_components/text";
import landingTechnologySrc from "../../_assets/landing-2.png";
import landingTechnologyMobileSrc from "../../_assets/landing-2-mobile.png";
import landingTechnologySrc from "../../_assets/landing-tech.png";
import landingTechnologyMobileSrc from "../../_assets/landing-tech-mobile.png";

const sections = [
{
Icon: ChatIcon,
title: "User-Centric",
body: "Intents replace explicit execution steps with implicit user outcomes, relying on a competitive network of market makers to fulfill outcomes. Cross-chain intents are a cross-chain limit order plus an action to execute.",
body: "Intents replace explicit execution steps with user outcomes, allowing relayers to compete to provide the optimal execution path for the user. Cross-chain intents are a cross-chain limit order plus an action to execute.",
},
{
Icon: FeatherIcon,
title: "Elegant Abstraction",
body: "Across connects users and applications via intents, not blockchains to other blockchains via complex or trusted message passing. Developers only need to attach a standard order to protocol actions to create seamless cross-chain experiences.",
body: "Unlike complex, trusted message passing solutions, Across connects users to dapps via intents, not just blockchains to other blockchains. Developers only need to embed a standard order in protocol actions to create seamless cross-chain experiences.",
},
{
Icon: BlocksDiagonalIcon,
Expand All @@ -22,7 +22,7 @@ const sections = [
Cross-chain intents are powered by a modular system of 3 layers:
<ol className="list-decimal pl-6">
<li>Request for quote mechanism</li>
<li>Network of competitive market makers</li>
<li>Network of competitive relayers</li>
<li>Settlement layer to escrow user input funds, verify, and repay relayers</li>
</ol>
</>
Expand Down Expand Up @@ -53,7 +53,7 @@ export function TechnologySection() {
))}
</div>
<div className="flex flex-col items-center">
<div className="flex max-w-100 flex-1 sm:max-w-lg md:max-w-full">
<div className="flex max-w-100 flex-1 sm:max-w-lg md:max-w-[638px]">
<picture>
<source srcSet={landingTechnologySrc.src} media="(min-width: 760px)" />
<img src={landingTechnologyMobileSrc.src} alt="MDN" />
Expand Down
3 changes: 3 additions & 0 deletions src/app/(routes)/across-newsletter/_constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY;
export const MAILCHIMP_API_SERVER = process.env.MAILCHIMP_API_SERVER;
export const MAILCHIMP_AUDIENCE_ID = process.env.MAILCHIMP_AUDIENCE_ID;
45 changes: 45 additions & 0 deletions src/app/(routes)/across-newsletter/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { z } from "zod";

import {
MAILCHIMP_API_KEY,
MAILCHIMP_API_SERVER,
MAILCHIMP_AUDIENCE_ID,
} from "./_constants";

export async function POST(request: Request) {
const body = await request.json();
const email = body.email;

const parsedEmail = z.string().email().safeParse(email);

if (!parsedEmail.success) {
return new Response("Invalid email address", {
status: 400,
});
}

const response = await fetch(
`https://${MAILCHIMP_API_SERVER}.api.mailchimp.com/3.0/lists/${MAILCHIMP_AUDIENCE_ID}/members`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `api_key ${MAILCHIMP_API_KEY}`,
},
body: JSON.stringify({
email_address: parsedEmail.data,
status: "subscribed",
}),
},
);

if (response.status == 200) {
return new Response("Successfully subscribed", {
status: 201,
});
}

return new Response("Something went wrong", {
status: 500,
});
}
4 changes: 3 additions & 1 deletion src/app/(routes)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { HeroSection } from "./_components/hero-section";
import { TechnologySection } from "./_components/technology-section";
import { StatsSection } from "./_components/stats-section";
import { ProductsSection } from "./_components/products-section";
import { SubscribeSection } from "@/app/_components/subscribe-section";

export const metadata: Metadata = {
title: "Home | Across Protocol",
Expand All @@ -14,9 +15,10 @@ export default function Home() {
return (
<main className="z-0 flex min-h-screen flex-col gap-24 overflow-hidden px-4 sm:gap-32 md:gap-48">
<HeroSection />
<ProductsSection />
<TechnologySection />
<StatsSection />
<ProductsSection />
<SubscribeSection />
</main>
);
}
Binary file removed src/app/_assets/landing-1.png
Binary file not shown.
Binary file removed src/app/_assets/landing-2.png
Binary file not shown.
Binary file added src/app/_assets/landing-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/app/_assets/landing-tech-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/app/_assets/landing-tech.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/app/_components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
UmaIcon,
QuestionMarkIcon,
DocumentIcon,
DiscourseIcon,
} from "./icons";
import { IconBox } from "./icon-box";
import { PRODUCT_LINKS, SOCIAL_LINKS, INFORMATION_LINKS } from "@/app/_constants";
Expand Down Expand Up @@ -57,6 +58,12 @@ const socials = [
iconClassName: "h-3 w-5",
iconContainerClassName: "bg-light-100/[.05]",
},
{
...SOCIAL_LINKS.discourse,
Icon: DiscourseIcon,
iconClassName: "h-4 w-4",
iconContainerClassName: "bg-light-100/[.05]",
},
];

const information = [
Expand Down
7 changes: 4 additions & 3 deletions src/app/_components/get-started-section.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArrowRightIcon } from "@/app/_components/icons";
import { Text } from "@/app/_components/text";
import { INFORMATION_LINKS } from "@/app/_constants";
import { INFORMATION_LINKS, SOCIAL_LINKS } from "@/app/_constants";
import { ReactNode } from "react";
import { twJoin } from "tailwind-merge";

Expand Down Expand Up @@ -44,9 +44,10 @@ export function GetStartedSection(props: {
go to docs
</Text>
</a>
{/* TODO: Use correct link */}
<a
href="#"
href={SOCIAL_LINKS.discord.href}
target="_blank"
rel="noopener noreferrer"
className="flex h-10 flex-row items-center justify-center gap-2 px-6 py-2"
>
<Text
Expand Down
8 changes: 8 additions & 0 deletions src/app/_components/header-nav/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
DiscordIcon,
TwitterIcon,
MediumIcon,
DiscourseIcon,
} from "../icons";
import { Button } from "../button";
import { Text } from "../text";
Expand Down Expand Up @@ -72,6 +73,13 @@ const communityNavigationItems = [
iconContainerClassName: "bg-light-100/[.05]",
containerClassName: "group-hover:bg-light-100/[.05]",
},
{
...SOCIAL_LINKS.discourse,
Icon: DiscourseIcon,
iconClassName: "h-4 w-4",
iconContainerClassName: "bg-light-100/[.05]",
containerClassName: "group-hover:bg-light-100/[.05]",
},
];

export function HeaderNav() {
Expand Down
19 changes: 19 additions & 0 deletions src/app/_components/icons/discourse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { SVGProps } from "react";

export function DiscourseIcon(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="M8.23157 0C6.88664 0.000794599 5.56497 0.351143 4.39592 1.01675C3.22687 1.68236 2.25051 2.64041 1.56241 3.79714C0.874316 4.95386 0.498064 6.26961 0.470487 7.61559C0.44291 8.96157 0.764952 10.2917 1.40509 11.4756L0 16L5.04555 14.8591C6.10135 15.3352 7.25017 15.569 8.40789 15.5432C9.56561 15.5174 10.7029 15.2327 11.7365 14.71C12.7701 14.1874 13.6738 13.4399 14.3815 12.5223C15.0891 11.6048 15.5828 10.5405 15.8263 9.40722C16.0699 8.274 16.0571 7.10059 15.789 5.97293C15.5209 4.84528 15.0042 3.79193 14.2768 2.89002C13.5493 1.98812 12.6296 1.2605 11.5849 0.760442C10.5402 0.260388 9.39694 0.000565225 8.23894 0H8.23157Z"
fill="white"
/>
</svg>
);
}
1 change: 1 addition & 0 deletions src/app/_components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export { ArrowRightIcon } from "./arrow-right";
export { ArrowUpRightIcon } from "./arrow-up-right";
export { ArrowUpRightThickIcon } from "./arrow-up-right-thick";
export { VerifiedCheckmarkIcon } from "./verified-checkmark";
export { DiscourseIcon } from "./discourse";

// Gradient icons
export { ArrowUpIcon } from "./gradient/arrow-up";
Expand Down
66 changes: 66 additions & 0 deletions src/app/_components/subscribe-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"use client";

import { useState } from "react";

import { Text } from "./text";

export function SubscribeSection() {
const [email, setEmail] = useState("");
const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
const [responseMsg, setResponseMsg] = useState("");

async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
setStatus("loading");

try {
const response = await fetch("/across-newsletter", {
method: "POST",
body: JSON.stringify({ email }),
headers: {
"Content-Type": "application/json",
},
});
setResponseMsg(await response.text());

if (response.ok) {
setStatus("success");
} else {
setStatus("error");
}
} catch {
setStatus("error");
}
}

return (
<section className="mb-24 flex flex-col items-center gap-6">
<Text variant="heading-2" className="capitalize text-light-100">
Stay up to date
</Text>
<Text variant="body-nums" className="text-light-300">
Sign up for our Newsletter
</Text>
<form className="flex flex-row gap-3" onSubmit={handleSubmit}>
<input
type="email"
placeholder="your email"
className="text-medium h-10 rounded-full border border-grey-500 bg-transparent px-6 text-xs uppercase lining-nums tabular-nums tracking-wide-4 focus:outline-none focus:ring-light-100 sm:w-[280px] sm:text-sm"
onChange={(event) => setEmail(event.target.value)}
value={email}
/>
<button
type="submit"
className="h-10 w-[112px] rounded-full bg-aqua-100/[.05] px-6 text-aqua-100 shadow hover:opacity-75"
disabled={status === "loading"}
>
<Text variant="cap-case-sm">Sign up</Text>
</button>
</form>
<div>
{status === "success" ? <p className="text-aqua-100">{responseMsg}</p> : null}
{status === "error" ? <p className="text-orange-100">{responseMsg}</p> : null}
</div>
</section>
);
}
Loading

0 comments on commit ca6ec4f

Please sign in to comment.