Skip to content

Commit fde57dd

Browse files
committed
Add side panel with testimonial and customer logos to auth layout
Introduced a new SidePanel component featuring a testimonial section and customer logos, visible on desktop layouts. Updated the auth layout to use a two-column grid, displaying the side panel on the right for larger screens.
1 parent c7ed7f5 commit fde57dd

File tree

3 files changed

+132
-38
lines changed

3 files changed

+132
-38
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const CUSTOMER_LOGOS = [
2+
{ name: "Framer", src: "https://assets.dub.co/clients/framer.svg" },
3+
{ name: "Granola", src: "https://assets.dub.co/clients/granola.svg" },
4+
{ name: "Buffer", src: "https://assets.dub.co/clients/buffer.svg" },
5+
{ name: "Copper", src: "https://assets.dub.co/clients/copper.svg" },
6+
{ name: "Perplexity", src: "https://assets.dub.co/clients/perplexity.svg" },
7+
{ name: "Wisprflow", src: "https://assets.dub.co/clients/wisprflow.svg" },
8+
];
9+
10+
export function CustomerLogos() {
11+
return (
12+
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-4 px-8 pb-10 pt-6 opacity-80 grayscale lg:px-10">
13+
{CUSTOMER_LOGOS.map((logo) => (
14+
<img
15+
key={logo.name}
16+
src={logo.src}
17+
alt={logo.name}
18+
className="h-5 w-auto"
19+
/>
20+
))}
21+
</div>
22+
);
23+
}

apps/web/app/app.dub.co/(auth)/layout.tsx

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,67 @@ import Toolbar from "@/ui/layout/toolbar/toolbar";
22
import { Grid, Wordmark } from "@dub/ui";
33
import { cn } from "@dub/utils";
44
import { ReactNode } from "react";
5+
import { SidePanel } from "./side-panel";
56

67
export default function AuthLayout({ children }: { children: ReactNode }) {
78
return (
89
<>
910
<Toolbar />
1011

11-
<div className="absolute inset-0 isolate overflow-hidden bg-white">
12-
{/* Grid */}
13-
<div
14-
className={cn(
15-
"absolute inset-y-0 left-1/2 w-[1200px] -translate-x-1/2",
16-
"[mask-composite:intersect] [mask-image:linear-gradient(black,transparent_320px),linear-gradient(90deg,transparent,black_5%,black_95%,transparent)]",
17-
)}
18-
>
19-
<Grid
20-
cellSize={60}
21-
patternOffset={[0.75, 0]}
22-
className="text-neutral-200"
23-
/>
24-
</div>
12+
<div className="relative grid h-screen grid-cols-1 min-[900px]:grid-cols-[minmax(0,1fr)_440px] lg:grid-cols-[minmax(0,1fr)_595px]">
13+
{/* Left: Main auth content */}
14+
<div className="relative">
15+
<div className="absolute inset-0 isolate overflow-hidden bg-white">
16+
{/* Grid */}
17+
<div
18+
className={cn(
19+
"absolute inset-y-0 left-1/2 w-[1200px] -translate-x-1/2",
20+
"[mask-composite:intersect] [mask-image:linear-gradient(black,transparent_320px),linear-gradient(90deg,transparent,black_5%,black_95%,transparent)]",
21+
)}
22+
>
23+
<Grid
24+
cellSize={60}
25+
patternOffset={[0.75, 0]}
26+
className="text-neutral-200"
27+
/>
28+
</div>
2529

26-
{/* Gradient */}
27-
{[...Array(2)].map((_, idx) => (
28-
<div
29-
key={idx}
30-
className={cn(
31-
"absolute left-1/2 top-6 size-[80px] -translate-x-1/2 -translate-y-1/2 scale-x-[1.6]",
32-
idx === 0 ? "mix-blend-overlay" : "opacity-10",
33-
)}
34-
>
35-
{[...Array(idx === 0 ? 2 : 1)].map((_, idx) => (
30+
{/* Gradient */}
31+
{[...Array(2)].map((_, idx) => (
3632
<div
3733
key={idx}
3834
className={cn(
39-
"absolute -inset-16 mix-blend-overlay blur-[50px] saturate-[2]",
40-
"bg-[conic-gradient(from_90deg,#F00_5deg,#EAB308_63deg,#5CFF80_115deg,#1E00FF_170deg,#855AFC_220deg,#3A8BFD_286deg,#F00_360deg)]",
35+
"absolute left-1/2 top-6 size-[80px] -translate-x-1/2 -translate-y-1/2 scale-x-[1.6]",
36+
idx === 0 ? "mix-blend-overlay" : "opacity-10",
4137
)}
42-
/>
38+
>
39+
{[...Array(idx === 0 ? 2 : 1)].map((_, idx) => (
40+
<div
41+
key={idx}
42+
className={cn(
43+
"absolute -inset-16 mix-blend-overlay blur-[50px] saturate-[2]",
44+
"bg-[conic-gradient(from_90deg,#F00_5deg,#EAB308_63deg,#5CFF80_115deg,#1E00FF_170deg,#855AFC_220deg,#3A8BFD_286deg,#F00_360deg)]",
45+
)}
46+
/>
47+
))}
48+
</div>
4349
))}
4450
</div>
45-
))}
46-
</div>
4751

48-
<div className="relative flex min-h-screen w-full justify-center">
49-
<a
50-
href="https://dub.co"
51-
target="_blank"
52-
className="absolute left-1/2 top-4 z-10 -translate-x-1/2"
53-
>
54-
<Wordmark className="h-8" />
55-
</a>
56-
{children}
52+
<div className="relative flex min-h-screen w-full justify-center">
53+
<a
54+
href="https://dub.co"
55+
target="_blank"
56+
className="absolute left-1/2 top-4 z-10 -translate-x-1/2"
57+
>
58+
<Wordmark className="h-8" />
59+
</a>
60+
{children}
61+
</div>
62+
</div>
63+
64+
{/* Right: Side panel - hidden on mobile */}
65+
<SidePanel />
5766
</div>
5867
</>
5968
);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { cn } from "@dub/utils";
2+
import Link from "next/link";
3+
import { CustomerLogos } from "./customer-logos";
4+
5+
export function SidePanel() {
6+
return (
7+
<div className="relative hidden h-full flex-col justify-between overflow-hidden border-l border-black/5 bg-neutral-50 min-[900px]:flex">
8+
{/* Gradient at bottom */}
9+
{[...Array(2)].map((_, idx) => (
10+
<div
11+
key={idx}
12+
className={cn(
13+
"absolute bottom-0 left-1/2 size-[80px] -translate-x-1/2 translate-y-1/2 scale-x-[1.6]",
14+
idx === 0 ? "mix-blend-overlay" : "opacity-15",
15+
)}
16+
>
17+
{[...Array(idx === 0 ? 2 : 1)].map((_, innerIdx) => (
18+
<div
19+
key={innerIdx}
20+
className={cn(
21+
"absolute -inset-16 mix-blend-overlay blur-[50px] saturate-[2]",
22+
"bg-[conic-gradient(from_90deg,#F00_5deg,#EAB308_63deg,#5CFF80_115deg,#1E00FF_170deg,#855AFC_220deg,#3A8BFD_286deg,#F00_360deg)]",
23+
)}
24+
/>
25+
))}
26+
</div>
27+
))}
28+
29+
{/* Testimonial section - vertically centered */}
30+
<div className="relative flex grow items-center justify-center p-6 lg:p-10">
31+
<div className="flex flex-col gap-6">
32+
{/* Testimonial image */}
33+
<div className="overflow-hidden rounded-xl">
34+
<img
35+
src="https://assets.dub.co/cms/framer-thumbnail.png"
36+
alt="Framer team"
37+
className="aspect-[16/10] w-full object-cover"
38+
/>
39+
</div>
40+
41+
{/* Testimonial text */}
42+
<p className="text-content-default max-w-[370px] text-pretty text-xl font-medium">
43+
Learn how Framer manages $500K+ in monthly affiliate payouts with
44+
Dub
45+
</p>
46+
47+
{/* Read more button */}
48+
<Link
49+
href="https://dub.co/customers/framer"
50+
target="_blank"
51+
className="text-content-emphasis flex h-8 w-fit items-center rounded-lg bg-black/5 px-3 text-sm font-medium transition-[transform,background-color] duration-75 hover:bg-black/10 active:scale-[0.98]"
52+
>
53+
Read more
54+
</Link>
55+
</div>
56+
</div>
57+
58+
{/* Bottom: Customer logos */}
59+
<CustomerLogos />
60+
</div>
61+
);
62+
}

0 commit comments

Comments
 (0)