Skip to content

Commit b5d25fc

Browse files
committed
Fix a bunch of stuff
1 parent 71452e1 commit b5d25fc

File tree

3 files changed

+125
-85
lines changed

3 files changed

+125
-85
lines changed

src/app/course/call-to-action.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useRef } from "react";
44
import { useState } from "react";
55
import { AnimatePresence, motion } from "motion/react";
6-
import { Dialog, DialogBackdrop, DialogPanel } from "@headlessui/react";
6+
import { Button, Dialog, DialogBackdrop, DialogPanel } from "@headlessui/react";
77

88
export function SignUpForm() {
99
return (
@@ -26,7 +26,13 @@ export function SignUpForm() {
2626
);
2727
}
2828

29-
export function HeroActions() {
29+
export function HeroActions({
30+
onWatchPreview = () => {},
31+
onClosePreview = () => {},
32+
}: {
33+
onWatchPreview?: () => void;
34+
onClosePreview?: () => void;
35+
}) {
3036
let [signUpState, setSignUpState] = useState<"closed" | "open">("closed");
3137
let input = useRef<HTMLInputElement>(null);
3238
let getCourseButton = useRef(null);
@@ -130,11 +136,16 @@ export function HeroActions() {
130136
</div>
131137
<AnimatePresence initial={false}>
132138
{signUpState === "closed" && (
133-
<motion.button
134-
onClick={() => setIsDialogOpen(true)}
139+
<Button
140+
as={motion.button}
141+
onClick={() => {
142+
console.log(onWatchPreview.toString());
143+
onWatchPreview();
144+
setIsDialogOpen(true);
145+
}}
135146
layout
136147
transition={{ duration: 0.3 }}
137-
className="inline-flex flex-nowrap items-baseline gap-1.5 self-center rounded-full bg-white/25 px-4 py-2 pl-3 text-sm/6 font-semibold whitespace-nowrap text-white hover:bg-white/30"
148+
className="inline-flex flex-nowrap items-baseline gap-1.5 self-center rounded-full bg-white/25 px-4 py-2 pl-3 text-sm/6 font-semibold whitespace-nowrap text-white hover:bg-white/30 focus:not-data-focus:outline-none"
138149
initial={{
139150
opacity: 0,
140151
}}
@@ -154,14 +165,20 @@ export function HeroActions() {
154165
/>
155166
</svg>
156167
Watch the first video
157-
</motion.button>
168+
</Button>
158169
)}
159170
</AnimatePresence>
160-
<Dialog open={isDialogOpen} onClose={() => setIsDialogOpen(false)}>
171+
<Dialog
172+
open={isDialogOpen}
173+
onClose={() => {
174+
setIsDialogOpen(false);
175+
onClosePreview();
176+
}}
177+
>
161178
<DialogBackdrop className="fixed inset-0 bg-black/85" />
162179
<div className="fixed inset-0 grid place-items-center">
163-
<DialogPanel className="max-w-7xl p-8">
164-
<video autoPlay controls className="aspect-video rounded-2xl">
180+
<DialogPanel className="w-full max-w-7xl p-8">
181+
<video autoPlay controls className="aspect-video w-full rounded-2xl">
165182
<source src="https://assets.tailwindcss.com/build-uis-that-dont-suck/intro.mp4" type="video/mp4" />
166183
</video>
167184
</DialogPanel>

src/app/course/hero-section.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"use client";
2+
3+
import { Logo } from "@/components/logo";
4+
import { GridContainer } from "./grid-container";
5+
import { HeroActions } from "./call-to-action";
6+
import { useRef } from "react";
7+
8+
export function HeroSection() {
9+
let videoRef = useRef<HTMLVideoElement>(null);
10+
11+
return (
12+
<>
13+
<div aria-hidden="true" className="absolute inset-x-0 top-0 left-1/5 -z-10 aspect-video opacity-50">
14+
<video ref={videoRef} autoPlay loop muted playsInline className="absolute size-full object-right">
15+
<source src="https://assets.tailwindcss.com/build-uis-that-dont-suck/hero-loop.mp4" type="video/mp4" />
16+
Your browser does not support the video tag.
17+
</video>
18+
<div className="absolute inset-0 size-full bg-linear-to-r from-gray-950 to-75%"></div>
19+
<div className="absolute inset-0 size-full bg-linear-to-t from-gray-950 to-50%"></div>
20+
</div>
21+
<GridContainer>
22+
<div className="p-2">
23+
<Logo className="h-7" />
24+
</div>
25+
</GridContainer>
26+
<div className="mt-20 flex flex-col gap-4 sm:mt-24">
27+
<GridContainer>
28+
<p className="font-mono text-sm/6 tracking-wider text-gray-400 uppercase">5-part mini-course</p>
29+
<h1 className="mt-2 text-5xl tracking-tighter text-balance text-white sm:text-8xl">
30+
Build UIs that don’t suck.
31+
</h1>
32+
</GridContainer>
33+
<GridContainer>
34+
<p className="max-w-2xl text-lg/7 font-medium text-gray-400">
35+
<strong className="font-medium text-white">Short, tactical video lessons</strong> from the creator of
36+
Tailwind CSS, delivered directly to your inbox{" "}
37+
<strong className="font-medium text-white">every day for a week</strong>.
38+
</p>
39+
</GridContainer>
40+
<GridContainer>
41+
<HeroActions
42+
onWatchPreview={() => {
43+
videoRef.current?.pause();
44+
}}
45+
onClosePreview={() => {
46+
videoRef.current?.play();
47+
}}
48+
/>
49+
</GridContainer>
50+
</div>
51+
</>
52+
);
53+
}

src/app/course/page.tsx

Lines changed: 46 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { HeroActions, SignUpForm } from "./call-to-action";
33
import { GridContainer } from "./grid-container";
44

55
import type { Metadata } from "next";
6+
import { HeroSection } from "./hero-section";
67

78
export const metadata: Metadata = {
89
title: "Build UIs that don't suck",
@@ -19,85 +20,54 @@ export const metadata: Metadata = {
1920
export default async function Course() {
2021
return (
2122
<div className="dark relative px-4 py-8 sm:px-0">
22-
<div>
23-
<div className="absolute inset-x-0 top-0 left-1/5 -z-10 aspect-video opacity-50">
24-
<video autoPlay loop muted playsInline className="absolute size-full object-right">
25-
<source
26-
src="https://assets.tailwindcss.com/build-uis-that-dont-suck/background-loop.mp4"
27-
type="video/mp4"
28-
/>
29-
Your browser does not support the video tag.
30-
</video>
31-
<div className="absolute inset-0 size-full bg-linear-to-r from-gray-950 to-75%"></div>
32-
<div className="absolute inset-0 size-full bg-linear-to-t from-gray-950 to-50%"></div>
33-
</div>
23+
<header>
24+
<HeroSection />
25+
</header>
26+
<main className="pt-14 pb-28">
3427
<GridContainer>
35-
<div className="p-2">
36-
<Logo className="h-7" />
37-
</div>
38-
</GridContainer>
39-
<div className="mt-20 flex flex-col gap-4 sm:mt-24">
40-
<GridContainer>
41-
<p className="font-mono text-sm/6 tracking-wider text-gray-400 uppercase">5-part mini-course</p>
42-
<h1 className="mt-2 text-5xl tracking-tighter text-balance text-white sm:text-8xl">
43-
Build UIs that don’t suck.
44-
</h1>
45-
</GridContainer>
46-
<GridContainer>
47-
<p className="max-w-2xl text-lg/7 font-medium text-gray-400">
48-
<strong className="font-medium text-white">Short, tactical video lessons</strong> from the creator of
49-
Tailwind CSS, delivered directly to your inbox{" "}
50-
<strong className="font-medium text-white">every day for a week</strong>.
28+
<div className="max-w-xl space-y-8 text-base/7 text-gray-400 marker:text-white/60 **:[li]:pl-2 **:[strong]:font-medium **:[strong]:text-white **:[ul]:list-[square] **:[ul]:space-y-4 **:[ul]:pl-8">
29+
<p>
30+
When you build UI components that are used by <strong>tens of thousands of developers</strong>, you learn
31+
to really care about the details, like:
32+
</p>
33+
<ul>
34+
<li>
35+
<strong>Building layouts that don't break</strong> when the content is longer than you planned for in
36+
Figma
37+
</li>
38+
<li>
39+
Making a table scrollable, <strong>without the content getting cropped</strong> by the page padding
40+
</li>
41+
<li>
42+
<strong>Automatically aligning icons</strong> in dropdown menus, even when some items are just text
43+
</li>
44+
<li>
45+
Making an entire card clickable, <strong>without destroying the experience</strong> for screen readers
46+
</li>
47+
<li>
48+
<strong>Fine-tuning click targets for mobile</strong>, without making everything else harder to maintain
49+
</li>
50+
<li>
51+
Getting the border radius <strong>mathematically perfect</strong> on nested elements, without
52+
hard-coding magic numbers
53+
</li>
54+
</ul>
55+
<p>
56+
<strong>“Build UIs that don’t suck”</strong> is a crash course in some of the coolest tricks I've picked
57+
up over the years building things that need to be both beautiful and bullet-proof.
5158
</p>
52-
</GridContainer>
53-
<GridContainer>
54-
<HeroActions />
55-
</GridContainer>
56-
</div>
57-
</div>
58-
<div className="px-2 pt-14 pb-28">
59-
<div className="max-w-xl space-y-8 text-base/7 text-gray-400 marker:text-white/60 **:[li]:pl-2 **:[strong]:font-medium **:[strong]:text-white **:[ul]:list-[square] **:[ul]:space-y-4 **:[ul]:pl-8">
60-
<p>
61-
When you build UI components that are used by <strong>tens of thousands of developers</strong>, you learn to
62-
really care about the details, like:
63-
</p>
64-
<ul>
65-
<li>
66-
<strong>Building layouts that don't break</strong> when the content is longer than you planned for in
67-
Figma
68-
</li>
69-
<li>
70-
Making a table scrollable, <strong>without the content getting cropped</strong> by the page padding
71-
</li>
72-
<li>
73-
<strong>Automatically aligning icons</strong> in dropdown menus, even when some items are just text
74-
</li>
75-
<li>
76-
Making an entire card clickable, <strong>without destroying the experience</strong> for screen readers
77-
</li>
78-
<li>
79-
<strong>Fine-tuning click targets for mobile</strong>, without making everything else harder to maintain
80-
</li>
81-
<li>
82-
Getting the border radius <strong>mathematically perfect</strong> on nested elements, without hard-coding
83-
magic numbers
84-
</li>
85-
</ul>
86-
<p>
87-
<strong>“Build UIs that don’t suck”</strong> is a crash course in some of the coolest tricks I've picked up
88-
over the years building things that need to be both beautiful and bullet-proof.
89-
</p>
9059

91-
<p>
92-
<strong>Every day for a week I'll send you a short video lesson</strong> walking you through an interesting
93-
UI problem, <strong>as well as the code</strong> so you can play with it yourself and adapt it for your own
94-
projects.
95-
</p>
96-
</div>
97-
<div className="mt-8">
98-
<SignUpForm />
99-
</div>
100-
</div>
60+
<p>
61+
<strong>Every day for a week I'll send you a short video lesson</strong> walking you through an
62+
interesting UI problem, <strong>as well as the code</strong> so you can play with it yourself and adapt it
63+
for your own projects.
64+
</p>
65+
</div>
66+
<div className="mt-8">
67+
<SignUpForm />
68+
</div>
69+
</GridContainer>
70+
</main>
10171
</div>
10272
);
10373
}

0 commit comments

Comments
 (0)