Skip to content
Open
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
16 changes: 2 additions & 14 deletions app/final/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useEffect, useState, Suspense } from 'react';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'next/navigation';
import Image from 'next/image';

Expand All @@ -14,7 +14,7 @@ interface MovieWithPoster {
rank: number;
}

function FinalPageContent() {
export default function FinalPage() {
const [topMovies, setTopMovies] = useState<MovieWithPoster[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
Expand Down Expand Up @@ -311,15 +311,3 @@ function FinalPageContent() {
);
}

export default function FinalPage() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center">
<div className="text-white text-xl">Loading results...</div>
</div>
}>
<FinalPageContent />
</Suspense>
);
}

8 changes: 4 additions & 4 deletions app/home/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ export default function HomePage() {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">

{/* Left Section - Text and CTA */}
<div className="flex flex-col space-y-6">
<div className="flex flex-col space-y-6 items-center text-center">
{/* Two-line Headline */}
<div className="space-y-2">
<h1 className="text-5xl lg:text-6xl font-bold">
<span className="text-white">Flago your</span>
<br />
<span className="text-white">Movies</span>
<span className="text-white">movies</span>
</h1>
</div>

{/* Description Paragraph */}
<p className="text-lg text-white/90 max-w-lg leading-relaxed">
Pick the perfect movie in seconds.
<br />
Set your preferences and let our AI handle the rest - solo or with friends.
Set your preferences with your friends and let our AI handle the rest.
<br />
With friends? Use Create a Party.Watching alone? Tap Get Started. (top-right).
Use Create a Party to get started.
</p>

{/* Call-to-Action Button */}
Expand Down
8 changes: 6 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ThemeProvider } from "next-themes";
import "./globals.css";
import FlagoNavbar from "@/components/flago-navbar";
import ConditionalNavbar from "@/components/conditional-navbar";
import Footer from "@/components/footer";

const defaultUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
Expand Down Expand Up @@ -115,9 +116,12 @@ export default function RootLayout({
enableSystem
disableTransitionOnChange
>
<div className="relative z-10">
<div className="relative z-10 flex flex-col min-h-screen">
<ConditionalNavbar />
{children}
<main className="flex-grow">
{children}
</main>
<Footer />
</div>
</ThemeProvider>
</body>
Expand Down
10 changes: 5 additions & 5 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,27 @@ export default function HomePage() {
return (
<div className="min-h-screen relative">
{/* Main Content Area */}
<div className="container mx-auto px-16 py-16">
<div className="container mx-auto px-6 py-16">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">

{/* Left Section - Text and CTA */}
<div className="flex flex-col space-y-6">
<div className="flex flex-col space-y-6 items-center lg:items-start text-center lg:text-left pl-8 lg:pl-12">
{/* Two-line Headline */}
<div className="space-y-2">
<h1 className="text-5xl lg:text-6xl font-bold">
<span className="text-white">Flago your</span>
<br />
<span className="text-white">Movies</span>
<span className="text-white">movies</span>
</h1>
</div>

{/* Description Paragraph */}
<p className="text-lg text-white/90 max-w-lg leading-relaxed">
Pick the perfect movie in seconds.
<br />
Set your preferences and let our AI handle the rest - solo or with friends.
Set your preferences with your friends and let our AI handle the rest.
<br />
With friends? Use Create a Party.Watching alone? Tap Get Started. (top-right).
Use Create a Party to get started.
</p>

{/* Call-to-Action Button */}
Expand Down
2 changes: 1 addition & 1 deletion components/conditional-navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function ConditionalNavbar() {

// Only show navbar on home page (exact match with "/")
// Hide it on all other pages including party routes
if (pathname === '/') {
if (pathname === '/home' || pathname === '/about' || pathname === '/contact_us' || pathname === '/') {
return <FlagoNavbar />;
}

Expand Down
4 changes: 2 additions & 2 deletions components/flago-navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export default function FlagoNavbar() {
{/* Right Section - Get Started Button */}
<div className="flex items-center">
<Link
href="/forms"
href="/party/create"
className="
group
relative
Expand Down Expand Up @@ -164,7 +164,7 @@ export default function FlagoNavbar() {
"></div>

{/* Text and icon */}
<span className="relative z-10">Get Started</span>
<span className="relative z-10">Create a Party</span>
<svg
className="w-4 h-4 relative z-10 transition-transform duration-300 group-hover:translate-x-1"
fill="none"
Expand Down
66 changes: 62 additions & 4 deletions components/party/party-results.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use client";

import { useEffect, useState } from 'react';
import Link from 'next/link';
import Lottie from 'lottie-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';

Expand All @@ -22,11 +24,20 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
const [rankings, setRankings] = useState<MovieWithPoster[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [confettiData, setConfettiData] = useState<any>(null);

useEffect(() => {
fetchResults();
}, [partySlug]);

// Load confetti animation
useEffect(() => {
fetch('/confetti.json')
.then((res) => res.json())
.then((data) => setConfettiData(data))
.catch((err) => console.error('Error loading confetti animation:', err));
}, []);

const fetchResults = async () => {
try {
setLoading(true);
Expand Down Expand Up @@ -119,10 +130,23 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
}

return (
<Card>
<CardHeader>
<CardTitle className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold">We think you should watch...</CardTitle>
</CardHeader>
<div className="relative">
{/* Confetti Animation Overlay */}
{confettiData && !loading && !error && rankings.length > 0 && (
<div className="fixed inset-0 pointer-events-none z-50">
<Lottie
animationData={confettiData}
loop={false}
autoplay={true}
className="w-full h-full"
/>
</div>
)}

<Card>
<CardHeader>
<CardTitle className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold">We think you should watch...</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{rankings.map((movie, index) => {
Expand Down Expand Up @@ -215,8 +239,42 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
);
})}
</div>

{/* Back to Home Button */}
<div className="mt-8 pt-6 border-t border-white/20">
<Link
href="/"
className="
inline-flex items-center justify-center gap-2
w-full sm:w-auto
px-8 py-4 text-lg font-semibold
bg-sky-400 hover:bg-sky-500
text-white rounded-lg
shadow-lg shadow-sky-400/30
transition-all transform hover:scale-105
focus:outline-none focus:ring-2 focus:ring-sky-400 focus:ring-offset-2
cursor-pointer
"
>
Back to Home
<svg
className="w-5 h-5"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
/>
</svg>
</Link>
</div>
</CardContent>
</Card>
</div>
);
}

115 changes: 81 additions & 34 deletions components/party/party-tinder-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { TinderCards } from '@/components/tinder-cards';
import { moviesToCardData } from '@/lib/elo_rating/movieToCardData';
import { subscribeToParty, unsubscribeFromParty } from '@/lib/party/realtime';
import type { RealtimeChannel } from '@supabase/supabase-js';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';

interface PartyTinderCardsProps {
partySlug: string;
Expand Down Expand Up @@ -241,60 +240,108 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp

if (loading) {
return (
<Card>
<CardContent className="p-8 text-center">
<p>Loading movies...</p>
</CardContent>
</Card>
<div className="flex items-center justify-center min-h-[400px]">
<div className="bg-white/10 backdrop-blur-md border border-white/20 rounded-2xl p-12 text-center">
<div className="inline-block w-12 h-12 border-4 border-white/30 border-t-sky-400 rounded-full animate-spin mb-4"></div>
<p className="text-white text-lg font-medium">Loading movies...</p>
</div>
</div>
);
}

if (error) {
return (
<Card>
<CardContent className="p-8 text-center text-red-600">
<p>{error}</p>
</CardContent>
</Card>
<div className="flex items-center justify-center min-h-[400px]">
<div className="bg-red-500/10 backdrop-blur-md border border-red-500/30 rounded-2xl p-12 text-center max-w-md">
<div className="text-red-400 text-4xl mb-4">⚠️</div>
<p className="text-red-300 text-lg font-medium">{error}</p>
</div>
</div>
);
}

if (movies.length === 0) {
return (
<Card>
<CardContent className="p-8 text-center">
<p>No movies available. The host needs to generate movies first.</p>
</CardContent>
</Card>
<div className="flex items-center justify-center min-h-[400px]">
<div className="bg-white/10 backdrop-blur-md border border-white/20 rounded-2xl p-12 text-center max-w-md">
<div className="text-white/70 text-4xl mb-4">🎬</div>
<p className="text-white text-lg font-medium">
No movies available. The host needs to generate movies first.
</p>
</div>
</div>
);
}

const remainingCount = movies.length - swipedMovies.size;
const progressPercentage = ((movies.length - remainingCount) / movies.length) * 100;

return (
<div>
<Card className="mb-4">
<CardHeader>
<CardTitle>
Swipe through movies ({remainingCount} remaining)
</CardTitle>
</CardHeader>
</Card>
<div className="space-y-6">
{/* Enhanced Header Card */}
<div className="bg-white/10 backdrop-blur-md border border-white/20 rounded-2xl p-6 shadow-xl">
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
<div className="flex-1">
<h2 className="text-2xl font-bold text-white mb-2">
Swipe through movies
</h2>
<div className="flex items-center gap-3">
<div className="flex-1 bg-white/10 rounded-full h-3 overflow-hidden">
<div
className="h-full bg-gradient-to-r from-sky-400 to-blue-500 transition-all duration-500 ease-out rounded-full"
style={{ width: `${progressPercentage}%` }}
></div>
</div>
<div className="text-white/90 font-semibold text-lg min-w-[80px] text-right">
{remainingCount} left
</div>
</div>
</div>
<div className="flex items-center gap-2 px-4 py-2 bg-sky-400/20 rounded-lg border border-sky-400/30">
<div className="w-2 h-2 bg-sky-400 rounded-full animate-pulse"></div>
<span className="text-sky-300 text-sm font-medium">
{Math.round(progressPercentage)}% complete
</span>
</div>
</div>
</div>

{/* Swipe Instructions */}
{remainingCount > 0 && remainingCount === movies.length && (
<div className="bg-gradient-to-r from-sky-500/20 to-blue-500/20 backdrop-blur-md border border-sky-400/30 rounded-xl p-4">
<div className="flex items-center gap-3 text-white/90">
<div className="text-2xl">👆</div>
<div className="flex-1">
<p className="font-medium">Swipe right to like, left to pass</p>
<p className="text-sm text-white/70 mt-1">Or use the buttons below</p>
</div>
</div>
</div>
)}

{/* Tinder Cards */}
{remainingCount > 0 ? (
<TinderCards
cardsData={cardsData}
onSwipe={handleSwipe}
/>
<div className="relative">
<TinderCards
cardsData={cardsData}
onSwipe={handleSwipe}
/>
</div>
) : (
<Card>
<CardContent className="p-8 text-center">
<p className="text-lg font-semibold mb-2">All done! 🎉</p>
<p className="text-gray-600">
<div className="flex items-center justify-center min-h-[400px]">
<div className="bg-gradient-to-br from-sky-500/20 to-purple-500/20 backdrop-blur-md border border-white/20 rounded-2xl p-12 text-center max-w-md shadow-xl">
<div className="text-6xl mb-4 animate-bounce">🎉</div>
<p className="text-white text-2xl font-bold mb-2">All done!</p>
<p className="text-white/80 text-lg">
Waiting for other members to finish swiping...
</p>
</CardContent>
</Card>
<div className="mt-6 flex items-center justify-center gap-2">
<div className="w-2 h-2 bg-sky-400 rounded-full animate-pulse"></div>
<div className="w-2 h-2 bg-sky-400 rounded-full animate-pulse [animation-delay:0.2s]"></div>
<div className="w-2 h-2 bg-sky-400 rounded-full animate-pulse [animation-delay:0.4s]"></div>
</div>
</div>
</div>
)}
</div>
);
Expand Down