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

Placeholder page updates #1960

Merged
merged 8 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from 7 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
31 changes: 31 additions & 0 deletions apps/web/app/[domain]/browser-graphic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { cn } from "@dub/utils";

export function BrowserGraphic({ domain }: { domain: string }) {
return (
<div className="w-full p-1 [mask-image:linear-gradient(black_50%,transparent_90%)]">
<div className="w-full rounded-t-lg border border-neutral-300 ring ring-black/5">
<div className="flex items-center justify-between gap-4 rounded-t-[inherit] bg-white px-5 py-3">
<div className="hidden grow basis-0 items-center gap-2 sm:flex">
{["bg-red-400", "bg-yellow-400", "bg-green-400"].map((c) => (
<div
key={c}
className={cn(
"size-[11px] rounded-full border border-black/10",
c,
)}
/>
))}
</div>
<div className="relative min-w-0 grow truncate rounded-lg bg-[radial-gradient(60%_80%_at_50%_0%,#ddd,#f5f5f5)] px-4 py-2 text-sm font-medium leading-none">
<div className="absolute inset-x-0 top-0 h-px bg-[linear-gradient(90deg,transparent,#0001,transparent)]" />
{domain}
</div>
<div className="hidden grow basis-0 sm:block" />
</div>
<div className="h-12 border-t border-neutral-200 bg-neutral-100/50" />
</div>
</div>
);
}
6 changes: 2 additions & 4 deletions apps/web/app/[domain]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { NewBackground } from "@/ui/shared/new-background";
import { Footer, Nav, NavMobile } from "@dub/ui";

export default function CustomDomainLayout({
Expand All @@ -9,10 +8,9 @@ export default function CustomDomainLayout({
return (
<div className="flex min-h-screen flex-col justify-between bg-gray-50/80">
<NavMobile />
<Nav />
<Nav maxWidthWrapperClassName="max-w-screen-lg lg:px-4 xl:px-0" />
{children}
<Footer />
<NewBackground />
<Footer className="max-w-screen-lg border-0 bg-transparent lg:px-4 xl:px-0" />
</div>
);
}
141 changes: 65 additions & 76 deletions apps/web/app/[domain]/placeholder.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,79 @@
"use client";

import { InlineSnippet } from "@dub/ui";
import { createHref, STAGGER_CHILD_VARIANTS } from "@dub/utils";
import Spline from "@splinetool/react-spline";
import { motion } from "framer-motion";
import { ButtonLink } from "@/ui/placeholders/button-link";
import { CTA } from "@/ui/placeholders/cta";
import { FeaturesSection } from "@/ui/placeholders/features-section";
import { Hero } from "@/ui/placeholders/hero";
import { Logo } from "@dub/ui";
import { cn, createHref } from "@dub/utils";
import { useParams } from "next/navigation";
import { useState } from "react";
import { useDebounce } from "use-debounce";
import { BubbleIcon } from "../../ui/placeholders/bubble-icon";
import { BrowserGraphic } from "./browser-graphic";

const UTM_PARAMS = {
utm_source: "Custom Domain",
utm_medium: "Welcome Page",
};

export default function PlaceholderContent() {
const { domain } = useParams() as { domain: string };
const [loading, setLoading] = useState(true);
const onLoad = () => {
setLoading(false);
};
// workaround to avoid the blinking effect when Spline loads
const [opacity] = useDebounce(loading ? 0 : 1, 200);

const [showText] = useDebounce(loading ? false : true, 800);

return (
<motion.div
className="z-10 mb-20"
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.5, type: "spring" }}
>
<div
className={`${
loading ? "scale-[25%] blur-md" : "scale-100 blur-0"
} mt-[7vh] h-[50vh] w-screen object-cover transition-all duration-1000`}
>
<Spline
onLoad={onLoad}
style={{ opacity: opacity }}
scene="https://assets.dub.co/misc/scene.splinecode"
/>
</div>
<motion.div
variants={{
show: {
transition: {
staggerChildren: 0.3,
},
},
}}
initial="hidden"
animate={showText ? "show" : "hidden"}
className="mx-5 flex flex-col items-center space-y-10 text-center sm:mx-auto"
>
<motion.h1
className="font-display text-4xl font-bold text-gray-800 transition-colors sm:text-5xl"
variants={STAGGER_CHILD_VARIANTS}
>
Welcome to {process.env.NEXT_PUBLIC_APP_NAME}
</motion.h1>
<motion.p
className="max-w-xl text-gray-600 transition-colors sm:text-lg"
variants={STAGGER_CHILD_VARIANTS}
<div>
<Hero>
<div className="relative mx-auto flex w-full max-w-xl flex-col items-center">
<BubbleIcon>
<Logo className="size-10" />
</BubbleIcon>
<div className="mt-16 w-full">
<BrowserGraphic domain={domain} />
</div>
<h1
className={cn(
"font-display mt-2 text-center text-4xl font-medium text-neutral-900 sm:text-5xl sm:leading-[1.15]",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:20px] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
Welcome to Dub
</h1>
<p
className={cn(
"mt-5 text-balance text-base text-neutral-700 sm:text-xl",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:10px] [animation-delay:200ms] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
This custom domain is powered by Dub.co &ndash; the link management
platform designed for modern marketing teams.
</p>
</div>

<div
className={cn(
"xs:flex-row relative mx-auto mt-8 flex max-w-fit flex-col items-center gap-4",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:5px] [animation-delay:300ms] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
<InlineSnippet>{domain}</InlineSnippet> is a custom domain on{" "}
<a
className="bg-gradient-to-r from-purple-400 to-pink-600 bg-clip-text font-semibold text-transparent decoration-rose-600 hover:underline"
href={createHref("/", domain, {
utm_source: "Custom Domain",
utm_medium: "Welcome Page",
<ButtonLink variant="primary" href="https://d.to/register">
Try Dub today
</ButtonLink>
<ButtonLink
variant="secondary"
href={createHref("/home", domain, {
...UTM_PARAMS,
utm_campaign: domain,
utm_content: "Dub.co",
utm_content: "Learn more",
})}
>
{process.env.NEXT_PUBLIC_APP_NAME}
</a>{" "}
- the link management platform for modern marketing teams.
</motion.p>
<motion.a
variants={STAGGER_CHILD_VARIANTS}
href={createHref("/home", domain, {
utm_source: "Custom Domain",
utm_medium: "Welcome Page",
utm_campaign: domain,
utm_content: "Create Your Free Branded Link",
})}
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
</motion.a>
</motion.div>
</motion.div>
Learn more
</ButtonLink>
</div>
</Hero>
<div className="mt-20">
<FeaturesSection domain={domain} utmParams={UTM_PARAMS} />
</div>
<div className="mt-32">
<CTA domain={domain} utmParams={UTM_PARAMS} />
</div>
</div>
);
}
91 changes: 70 additions & 21 deletions apps/web/app/banned/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Background, Footer, Nav, NavMobile } from "@dub/ui";
import { constructMetadata } from "@dub/utils";
import { ShieldBan } from "lucide-react";
import { BubbleIcon } from "@/ui/placeholders/bubble-icon";
import { ButtonLink } from "@/ui/placeholders/button-link";
import { CTA } from "@/ui/placeholders/cta";
import { FeaturesSection } from "@/ui/placeholders/features-section";
import { Hero } from "@/ui/placeholders/hero";
import { Footer, Nav, NavMobile, ShieldSlash } from "@dub/ui";
import { cn, constructMetadata, createHref } from "@dub/utils";

export const runtime = "edge";

Expand All @@ -10,28 +14,73 @@ export const metadata = constructMetadata({
noIndex: true,
});

export default async function BannedPage() {
const UTM_PARAMS = {
utm_source: "Expired Link",
utm_medium: "Expired Link Page",
};

export default async function BannedPage({
params,
}: {
params: { domain: string };
}) {
return (
<main className="flex min-h-screen flex-col justify-between">
<NavMobile staticDomain="dub.sh" />
<Nav staticDomain="dub.sh" />
<div className="z-10 mx-2 my-10 flex max-w-md flex-col items-center space-y-5 px-2.5 text-center sm:mx-auto sm:max-w-lg sm:px-0 lg:mb-16">
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-full border border-gray-300 bg-white/30">
<ShieldBan className="size-6 text-gray-500" />
<NavMobile />
<Nav maxWidthWrapperClassName="max-w-screen-lg lg:px-4 xl:px-0" />
<div>
<Hero>
<div className="relative mx-auto flex w-full max-w-sm flex-col items-center">
<BubbleIcon>
<ShieldSlash className="size-12" />
</BubbleIcon>
<h1
className={cn(
"font-display mt-10 text-center text-4xl font-medium text-neutral-900 sm:text-5xl sm:leading-[1.15]",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:20px] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
Banned link
</h1>
<p
className={cn(
"mt-5 text-pretty text-base text-neutral-700 sm:text-xl",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:10px] [animation-delay:200ms] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
This link has been banned for violating our terms of service.
</p>
</div>

<div
className={cn(
"xs:flex-row relative mx-auto mt-8 flex max-w-fit flex-col items-center gap-4",
"animate-slide-up-fade motion-reduce:animate-fade-in [--offset:5px] [animation-delay:300ms] [animation-duration:1s] [animation-fill-mode:both]",
)}
>
<ButtonLink variant="primary" href="https://d.to/register">
Try Dub today
</ButtonLink>
<ButtonLink
variant="secondary"
href={createHref("/home", params.domain, {
...UTM_PARAMS,
utm_campaign: params.domain,
utm_content: "Learn more",
})}
>
Learn more
</ButtonLink>
</div>
</Hero>
<div className="mt-20">
<FeaturesSection domain={params.domain} utmParams={UTM_PARAMS} />
</div>
<div className="mt-32">
<CTA domain={params.domain} utmParams={UTM_PARAMS} />
</div>
<h1 className="font-display text-5xl font-bold">Banned Link</h1>
<p className="text-lg text-gray-600">
This link has been banned for violating our terms of service.
</p>
<a
href="https://dub.co/home"
className="rounded-full bg-gray-800 px-10 py-2 font-medium text-white transition-colors hover:bg-black"
>
Create Your Free Branded Link
</a>
</div>
<Footer staticDomain="dub.sh" />
<Background />
<Footer className="max-w-screen-lg border-0 bg-transparent lg:px-4 xl:px-0" />
</main>
);
}
Loading
Loading