Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 4 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ jobs:
uses: pnpm/action-setup@v2
with:
version: 8
run_install: false

- name: Install dependencies
run: pnpm install --frozen-lockfile --prod false
run: |
pnpm add -D next@15.2.4 react@^18.3.1 react-dom@^18.3.1
pnpm add -D eslint
pnpm install --frozen-lockfile=false

- name: Run ESLint
run: pnpm run lint
1 change: 0 additions & 1 deletion app/dashboard/creators/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ export default function CreatorsPage() {

} catch (error) {
console.error("❌ Error in fetchData:", error)
setError('There was an error loading your YouTube data. Showing sample data instead.')
setStats(mockCreatorStats as { primaryYear: DashboardStats; comparisonYear?: DashboardStats })
} finally {
setIsLoading(false)
Expand Down
6 changes: 3 additions & 3 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const mockStats = {
title: "These new computers are getting creepy… Copilot+ PC first look",
channel: "Fireship",
count: 12,
videoId: ""
videoId: "hlwcZpEx2IY"
},
{
title: "iPhone 16/16 Pro Review: Times Have Changed!",
Expand Down Expand Up @@ -437,8 +437,8 @@ export default function DashboardPage() {
<div className="py-1"></div>
</CardHeader>
<CardContent>
<div className="flex gap-4 overflow-x-auto pb-4 px-4">
{stats?.primaryYear.mostWatchedVideos?.map((video) => (
<div className="flex gap-4 overflow-x-auto pb-4 px-4 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent scroll-smooth">
{stats?.primaryYear.mostWatchedVideos?.map((video) => (
<a
key={video.videoId}
href={`https://www.youtube.com/watch?v=${video.videoId}`}
Expand Down
27 changes: 16 additions & 11 deletions app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ export default function LoginPage() {
checkUsers();
}, []);

// Redirect if already logged in
useEffect(() => {
if (isLoggedIn) {
router.push("/dashboard");
}
}, [isLoggedIn, router]);

return (
<div className="flex min-h-screen flex-col items-center justify-center bg-muted/40 p-4">
<Link
Expand All @@ -49,8 +42,10 @@ export default function LoginPage() {
</Link>

<div className="mb-8 flex items-center gap-2">
<Film className="h-8 w-8 text-primary" />
<span className="text-2xl font-bold">YouTube Wrapped</span>
<Link href="/" className="flex items-center gap-2">
<Film className="h-8 w-8 text-primary" />
<span className="text-2xl font-bold">YouTube Wrapped</span>
</Link>
</div>

<Card className="w-full max-w-md">
Expand All @@ -62,8 +57,18 @@ export default function LoginPage() {
</CardDescription>
</CardHeader>
<CardContent>
<div className="mb-4 rounded-md bg-muted/60 p-3 text-sm text-muted-foreground text-center">
Make sure you have already completed the <a href="/takeout-instructions" className="text-primary hover:underline">takeout instructions</a> before signing in.
<div className="mb-4 rounded-md bg-yellow-50 dark:bg-yellow-950/50 border border-yellow-200 dark:border-yellow-800 p-4 text-sm text-yellow-800 dark:text-yellow-200">
<div className="flex items-start gap-2">
<div className="mt-0.5">
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
</div>
<div>
<p className="font-medium">Psst! Before you dive in... 🎬</p>
<p className="mt-1">You'll need your YouTube watch history to get your Wrapped! Don't worry, it's super easy - just follow our <a href="/takeout-instructions" className="text-yellow-700 dark:text-yellow-300 underline hover:text-yellow-800 dark:hover:text-yellow-200">quick guide</a> to get your data.</p>
</div>
</div>
</div>
<Tabs defaultValue="login" className="w-full">
<TabsList className="grid w-full grid-cols-2">
Expand Down
60 changes: 41 additions & 19 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export default function HomePage() {
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
<div className="container flex h-16 items-center justify-between">
<div className="flex items-center gap-2">
<Play className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
<Link href="/" className="flex items-center gap-2">
<Play className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
</Link>
</div>
<nav className="hidden md:flex gap-6">
<Link href="#features" className="text-sm font-medium hover:underline">
Expand All @@ -38,10 +40,9 @@ export default function HomePage() {
<ThemeToggle />
<UserProfile />
{!isLoggedIn ? (
<Button onClick={(e) => {
e.preventDefault();
login();
}}>Get Started</Button>
<Link href="#how-it-works">
<Button>Get Started</Button>
</Link>
) : (
<Link href="/dashboard">
<Button>Dashboard</Button>
Expand All @@ -60,7 +61,7 @@ export default function HomePage() {
Discover your YouTube addiction in a fun and (soon) shareable format. <span className="inline-block">(<a href="/terms-and-privacy" className="text-primary hover:underline">Privacy Policy</a> ensures we won't judge... much 😜)</span>
</p>
<div className="flex flex-col sm:flex-row gap-4">
<Link href="#how-it-works">
<Link href={isLoggedIn ? "/dashboard" : "/login"}>
<Button size="lg" className="gap-2">
See Your Wrapped <ArrowRight className="h-4 w-4" />
</Button>
Expand All @@ -71,6 +72,9 @@ export default function HomePage() {
</Button>
</Link>
</div>
<div className="mt-4 text-sm text-muted-foreground">
<p>New here? Check out our <a href="#how-it-works" className="text-primary hover:underline">quick guide</a> to get started! 🚀</p>
</div>
</div>
<div className="mx-auto mt-16 grid max-w-5xl grid-cols-1 gap-8 md:grid-cols-2">
<div className="relative overflow-hidden rounded-xl border bg-background p-2">
Expand Down Expand Up @@ -100,14 +104,17 @@ export default function HomePage() {
</div>
</div>
<div className="relative overflow-hidden rounded-xl border bg-background p-2">
<div className="bg-gradient-to-br from-purple-500/20 to-purple-500/5 rounded-lg p-6">
<div className="flex flex-col gap-2">
<div className="bg-gradient-to-br from-purple-500/20 to-purple-500/5 rounded-lg p-6 h-full">
<div className="flex flex-col gap-2 h-full justify-center">
<h3 className="text-xl font-bold">Top Categories</h3>
<div className="mt-4 space-y-3">
<div className="mt-4 space-y-4">
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span>Gaming</span>
<span className="font-medium">32%</span>
<div className="flex items-center gap-1">
<span className="font-medium">32%</span>
<span className="text-purple-400 text-xs">(+8%)</span>
</div>
</div>
<div className="h-2 w-full rounded-full bg-muted">
<div className="h-full w-[32%] rounded-full bg-purple-500"></div>
Expand All @@ -116,7 +123,10 @@ export default function HomePage() {
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span>Tech</span>
<span className="font-medium">28%</span>
<div className="flex items-center gap-1">
<span className="font-medium">28%</span>
<span className="text-purple-400 text-xs">(+3%)</span>
</div>
</div>
<div className="h-2 w-full rounded-full bg-muted">
<div className="h-full w-[28%] rounded-full bg-purple-500"></div>
Expand All @@ -125,7 +135,10 @@ export default function HomePage() {
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span>Music</span>
<span className="font-medium">18%</span>
<div className="flex items-center gap-1">
<span className="font-medium">18%</span>
<span className="text-purple-300 text-xs">(-2%)</span>
</div>
</div>
<div className="h-2 w-full rounded-full bg-muted">
<div className="h-full w-[18%] rounded-full bg-purple-500"></div>
Expand All @@ -134,7 +147,10 @@ export default function HomePage() {
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span>Education</span>
<span className="font-medium">12%</span>
<div className="flex items-center gap-1">
<span className="font-medium">12%</span>
<span className="text-purple-400 text-xs">(+4%)</span>
</div>
</div>
<div className="h-2 w-full rounded-full bg-muted">
<div className="h-full w-[12%] rounded-full bg-purple-500"></div>
Expand All @@ -143,7 +159,10 @@ export default function HomePage() {
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span>Entertainment</span>
<span className="font-medium">10%</span>
<div className="flex items-center gap-1">
<span className="font-medium">10%</span>
<span className="text-purple-300 text-xs">(-13%)</span>
</div>
</div>
<div className="h-2 w-full rounded-full bg-muted">
<div className="h-full w-[10%] rounded-full bg-purple-500"></div>
Expand Down Expand Up @@ -198,19 +217,22 @@ export default function HomePage() {
<div className="mx-auto flex max-w-[58rem] flex-col items-center justify-center gap-4 text-center">
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl">How It Works</h2>
<p className="max-w-[42rem] leading-normal text-muted-foreground sm:text-xl sm:leading-8">
Some steps to get us going...
Get your personalized YouTube Wrapped in just 3 simple steps
</p>
</div>
<div className="mx-auto mt-16 grid max-w-5xl grid-cols-1 gap-8 md:grid-cols-3">
<div className="flex flex-col items-center gap-4 rounded-lg border bg-background p-6 text-center">
<div className="flex flex-col items-center gap-4 rounded-lg border bg-background p-6 text-center relative">
<div className="absolute -top-3 -right-3 bg-red-500 text-white px-2 py-1 rounded-full text-xs font-bold">
Required
</div>
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-muted text-2xl font-bold">
1
</div>
<h3 className="text-xl font-bold">Export Your Data</h3>
<p className="text-muted-foreground">Get your YouTube watch history from Google Takeout. <span className="inline-block">(It's sooo easy, kinda!)</span></p>
<Link href="/takeout-instructions">
<Button variant="outline" className="mt-2">
Learn How
<Button className="mt-2">
Get Takeout Instructions
</Button>
</Link>
</div>
Expand Down
8 changes: 5 additions & 3 deletions app/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default function ProfilePage() {
}

// Use the helper function to handle the rest
await fetchAndProcessWatchHistory(accessToken, user?.uid || "", true);
await fetchAndProcessWatchHistory(accessToken, user?.uid || "");

toast({
title: "Data refreshed",
Expand Down Expand Up @@ -94,8 +94,10 @@ export default function ProfilePage() {
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
<div className="container flex h-16 items-center justify-between">
<div className="flex items-center gap-2">
<Film className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
<Link href="/" className="flex items-center gap-2">
<Film className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
</Link>
</div>
<div className="flex items-center gap-2">
<ThemeToggle />
Expand Down
8 changes: 5 additions & 3 deletions app/takeout-instructions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export default function TakeoutInstructionsPage() {
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
<div className="container flex h-16 items-center justify-between">
<div className="flex items-center gap-2">
<Play className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
<Link href="/" className="flex items-center gap-2">
<Play className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
</Link>
</div>
<Link href="/">
<Button variant="ghost" className="gap-2">
Expand Down Expand Up @@ -121,7 +123,7 @@ export default function TakeoutInstructionsPage() {
</CardHeader>
<CardContent>
<div className="space-y-4">
<p>1. Wait for Google to prepare your data (this may take a few minutes to several hours - i worry for you if it takes hours 😭)</p>
<p>1. Wait for Google to prepare your data (this may take a few minutes to several hours - we really worry for you if it takes hours 😭)</p>
<p>2. You'll receive an email when your data is ready and you should be good to go!!</p>
</div>
</CardContent>
Expand Down
7 changes: 5 additions & 2 deletions components/dashboard-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ThemeToggle } from "@/components/theme-toggle"
import { ShareStats } from "@/components/share-stats"
import { UserProfile } from "@/components/user-profile"
import { useState, useEffect } from "react"
import Link from "next/link"

export function DashboardHeader() {
const [stats, setStats] = useState<{
Expand Down Expand Up @@ -34,8 +35,10 @@ export function DashboardHeader() {
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur">
<div className="container flex h-16 items-center justify-between">
<div className="flex items-center gap-2">
<Film className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
<Link href="/" className="flex items-center gap-2">
<Film className="h-6 w-6 text-primary" />
<span className="text-xl font-bold">YouTube Wrapped</span>
</Link>
</div>
<div className="flex items-center gap-2">
<ThemeToggle />
Expand Down
Loading
Loading