From e63a378679831b0c2e57883a2205c5bcd3ee94c5 Mon Sep 17 00:00:00 2001 From: Aditya-Shetty-08 Date: Mon, 17 Nov 2025 22:07:44 -0500 Subject: [PATCH 1/3] Final --- app/home/page.tsx | 8 ++++---- app/page.tsx | 10 +++++----- components/flago-navbar.tsx | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/home/page.tsx b/app/home/page.tsx index d0eedc5..6422e29 100644 --- a/app/home/page.tsx +++ b/app/home/page.tsx @@ -25,13 +25,13 @@ export default function HomePage() {
{/* Left Section - Text and CTA */} -
+
{/* Two-line Headline */}

Flago your
- Movies + movies

@@ -39,9 +39,9 @@ export default function HomePage() {

Pick the perfect movie in seconds.
- 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.
- With friends? Use Create a Party.Watching alone? Tap Get Started. (top-right). + Use Create a Party to get started.

{/* Call-to-Action Button */} diff --git a/app/page.tsx b/app/page.tsx index 9bbae24..b49401e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -21,17 +21,17 @@ export default function HomePage() { return (
{/* Main Content Area */} -
+
{/* Left Section - Text and CTA */} -
+
{/* Two-line Headline */}

Flago your
- Movies + movies

@@ -39,9 +39,9 @@ export default function HomePage() {

Pick the perfect movie in seconds.
- 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.
- With friends? Use Create a Party.Watching alone? Tap Get Started. (top-right). + Use Create a Party to get started.

{/* Call-to-Action Button */} diff --git a/components/flago-navbar.tsx b/components/flago-navbar.tsx index e3e6fdd..51515af 100644 --- a/components/flago-navbar.tsx +++ b/components/flago-navbar.tsx @@ -131,7 +131,7 @@ export default function FlagoNavbar() { {/* Right Section - Get Started Button */}
{/* Text and icon */} - Get Started + Create a Party Date: Wed, 19 Nov 2025 14:06:53 -0500 Subject: [PATCH 2/3] Made changes --- app/party/[slug]/page.tsx | 25 ++++- components/party/host-controls.tsx | 59 ++++++++--- components/party/party-results.tsx | 45 +++++--- components/party/party-tinder-cards.tsx | 134 ++++++++++++++++++++---- 4 files changed, 208 insertions(+), 55 deletions(-) diff --git a/app/party/[slug]/page.tsx b/app/party/[slug]/page.tsx index 1acd25a..ae8a267 100644 --- a/app/party/[slug]/page.tsx +++ b/app/party/[slug]/page.tsx @@ -96,10 +96,16 @@ export default function PartyPage() { const [error, setError] = useState(null); const [channel, setChannel] = useState(null); const [totalMovies, setTotalMovies] = useState(10); + const [confettiData, setConfettiData] = useState(null); // Fetch initial data useEffect(() => { fetchPartyData(); + // Load confetti animation + fetch('/confetti.json') + .then((res) => res.json()) + .then((data) => setConfettiData(data)) + .catch((err) => console.error('Error loading confetti animation:', err)); }, [slug]); @@ -260,9 +266,21 @@ export default function PartyPage() { const isMember = myMembership !== null; return ( -
- - +
+ {/* Confetti Animation - Full Screen Overlay when results are shown */} + {party?.status === 'completed' && confettiData && ( +
+ +
+ )} +
+ + {!isMember && (
@@ -379,6 +397,7 @@ export default function PartyPage() { )} )} +
); } diff --git a/components/party/host-controls.tsx b/components/party/host-controls.tsx index c17df33..b070dce 100644 --- a/components/party/host-controls.tsx +++ b/components/party/host-controls.tsx @@ -1,8 +1,9 @@ "use client"; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import Lottie from 'lottie-react'; interface HostControlsProps { partySlug: string; @@ -15,6 +16,15 @@ interface HostControlsProps { export function HostControls({ partySlug, members, onStatusChange }: HostControlsProps) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); + const [animationData, setAnimationData] = useState(null); + + useEffect(() => { + // Load movie animation + fetch('/movie-animation.json') + .then((res) => res.json()) + .then((data) => setAnimationData(data)) + .catch((err) => console.error('Error loading animation:', err)); + }, []); const allMembersSubmitted = members.length > 0 && members.every(m => m.has_submitted_preferences); const submittedCount = members.filter(m => m.has_submitted_preferences).length; @@ -67,38 +77,53 @@ export function HostControls({ partySlug, members, onStatusChange }: HostControl }; return ( - + - Host Controls + Host Controls
-

+

Preferences submitted: {submittedCount} / {members.length}

{!allMembersSubmitted && ( -

+

Waiting for all members to submit preferences...

)}
{error && ( -
{error}
+
{error}
+ )} + + {loading && animationData && ( +
+
+ +
+

Generating Movies...

+

This may take a moment

+
)} - + {!loading && ( + + )}
diff --git a/components/party/party-results.tsx b/components/party/party-results.tsx index 3f7620f..f9ada55 100644 --- a/components/party/party-results.tsx +++ b/components/party/party-results.tsx @@ -100,9 +100,16 @@ export function PartyResults({ partySlug }: PartyResultsProps) { if (loading) { return ( - + -

Loading results...

+
+
+
+
+
+
+

Loading results...

+
); @@ -110,8 +117,8 @@ export function PartyResults({ partySlug }: PartyResultsProps) { if (error) { return ( - - + +

{error}

@@ -119,11 +126,20 @@ export function PartyResults({ partySlug }: PartyResultsProps) { } return ( - - - We think you should watch... - - +
+ {/* All Done Message */} + + +

🎉 All Done! 🎉

+

Here are your personalized movie recommendations

+
+
+ + + + We think you should watch... + +
{rankings.map((movie, index) => { // First movie: vertical on mobile, horizontal on larger screens @@ -183,19 +199,19 @@ export function PartyResults({ partySlug }: PartyResultsProps) { return (
#{index + 1}
-

+

{movie.title}

{movie.genres.map((genre: string) => ( - + {genre} ))} @@ -203,10 +219,10 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
-
+
{Math.round(movie.elo_rating)}
-
ELO Rating
+
ELO Rating
{movie.right_swipes} likes, {movie.left_swipes} passes
@@ -217,6 +233,7 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
+
); } diff --git a/components/party/party-tinder-cards.tsx b/components/party/party-tinder-cards.tsx index ac9ebbc..8f716a4 100644 --- a/components/party/party-tinder-cards.tsx +++ b/components/party/party-tinder-cards.tsx @@ -6,6 +6,7 @@ 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'; +import Lottie from 'lottie-react'; interface PartyTinderCardsProps { partySlug: string; @@ -26,10 +27,16 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp const [titleToDirectors, setTitleToDirectors] = useState>({}); const [titleToDescription, setTitleToDescription] = useState>({}); const [titleToRating, setTitleToRating] = useState>({}); + const [animationData, setAnimationData] = useState(null); // Fetch movies useEffect(() => { fetchMovies(); + // Load movie animation + fetch('/movie-animation.json') + .then((res) => res.json()) + .then((data) => setAnimationData(data)) + .catch((err) => console.error('Error loading animation:', err)); }, [partySlug]); // Set up realtime for movie updates @@ -241,9 +248,27 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp if (loading) { return ( - + -

Loading movies...

+ {animationData ? ( +
+
+ +
+

Loading movies...

+
+ ) : ( +
+
+
+
+
+ )}
); @@ -251,8 +276,8 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp if (error) { return ( - - + +

{error}

@@ -261,8 +286,8 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp if (movies.length === 0) { return ( - - + +

No movies available. The host needs to generate movies first.

@@ -270,27 +295,94 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp } const remainingCount = movies.length - swipedMovies.size; + const completedCount = swipedMovies.size; + const progressPercentage = movies.length > 0 ? (completedCount / movies.length) * 100 : 0; return ( -
- - - - Swipe through movies ({remainingCount} remaining) - - - +
+ {/* Movie Animation Background - More Visible */} + {animationData && remainingCount > 0 && ( +
+
+ +
+
+ )} + + {/* Dark gradient background */} + {remainingCount > 0 && ( +
+ )} + + {/* Progress Bar */} + {remainingCount > 0 && ( + + +
+ + 🎬 + Swipe through movies + +
+
+ {completedCount} completed + {remainingCount} remaining +
+
+
+
+
+
+
+
+ )} {remainingCount > 0 ? ( - +
+
+ + {/* Swipe instructions */} +
+

💡 Swipe right to like, left to pass

+
+ + Pass + + + Like + +
+
+
+
) : ( - + -

All done! 🎉

-

+

+ {animationData && ( +
+ +
+ )} +
+

All done! 🎉

+

Waiting for other members to finish swiping...

From 939a81f9b3c7a52360f2497dc3567dd7e522078e Mon Sep 17 00:00:00 2001 From: Aditya-Shetty-08 Date: Wed, 19 Nov 2025 14:41:35 -0500 Subject: [PATCH 3/3] final --- app/final/page.tsx | 16 +- app/layout.tsx | 8 +- app/party/[slug]/page.tsx | 25 +-- components/conditional-navbar.tsx | 2 +- components/party/host-controls.tsx | 59 ++----- components/party/party-results.tsx | 97 ++++++++---- components/party/party-tinder-cards.tsx | 197 +++++++++--------------- 7 files changed, 174 insertions(+), 230 deletions(-) diff --git a/app/final/page.tsx b/app/final/page.tsx index 82fa9a4..9b207bb 100644 --- a/app/final/page.tsx +++ b/app/final/page.tsx @@ -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'; @@ -14,7 +14,7 @@ interface MovieWithPoster { rank: number; } -function FinalPageContent() { +export default function FinalPage() { const [topMovies, setTopMovies] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -311,15 +311,3 @@ function FinalPageContent() { ); } -export default function FinalPage() { - return ( - -
Loading results...
-
- }> - - - ); -} - diff --git a/app/layout.tsx b/app/layout.tsx index 236f446..06256de 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -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}` @@ -115,9 +116,12 @@ export default function RootLayout({ enableSystem disableTransitionOnChange > -
+
- {children} +
+ {children} +
+
diff --git a/app/party/[slug]/page.tsx b/app/party/[slug]/page.tsx index ae8a267..1acd25a 100644 --- a/app/party/[slug]/page.tsx +++ b/app/party/[slug]/page.tsx @@ -96,16 +96,10 @@ export default function PartyPage() { const [error, setError] = useState(null); const [channel, setChannel] = useState(null); const [totalMovies, setTotalMovies] = useState(10); - const [confettiData, setConfettiData] = useState(null); // Fetch initial data useEffect(() => { fetchPartyData(); - // Load confetti animation - fetch('/confetti.json') - .then((res) => res.json()) - .then((data) => setConfettiData(data)) - .catch((err) => console.error('Error loading confetti animation:', err)); }, [slug]); @@ -266,21 +260,9 @@ export default function PartyPage() { const isMember = myMembership !== null; return ( -
- {/* Confetti Animation - Full Screen Overlay when results are shown */} - {party?.status === 'completed' && confettiData && ( -
- -
- )} -
- - +
+ + {!isMember && (
@@ -397,7 +379,6 @@ export default function PartyPage() { )} )} -
); } diff --git a/components/conditional-navbar.tsx b/components/conditional-navbar.tsx index 29511d0..22a21d9 100644 --- a/components/conditional-navbar.tsx +++ b/components/conditional-navbar.tsx @@ -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 ; } diff --git a/components/party/host-controls.tsx b/components/party/host-controls.tsx index b070dce..c17df33 100644 --- a/components/party/host-controls.tsx +++ b/components/party/host-controls.tsx @@ -1,9 +1,8 @@ "use client"; -import { useState, useEffect } from 'react'; +import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import Lottie from 'lottie-react'; interface HostControlsProps { partySlug: string; @@ -16,15 +15,6 @@ interface HostControlsProps { export function HostControls({ partySlug, members, onStatusChange }: HostControlsProps) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); - const [animationData, setAnimationData] = useState(null); - - useEffect(() => { - // Load movie animation - fetch('/movie-animation.json') - .then((res) => res.json()) - .then((data) => setAnimationData(data)) - .catch((err) => console.error('Error loading animation:', err)); - }, []); const allMembersSubmitted = members.length > 0 && members.every(m => m.has_submitted_preferences); const submittedCount = members.filter(m => m.has_submitted_preferences).length; @@ -77,53 +67,38 @@ export function HostControls({ partySlug, members, onStatusChange }: HostControl }; return ( - + - Host Controls + Host Controls
-

+

Preferences submitted: {submittedCount} / {members.length}

{!allMembersSubmitted && ( -

+

Waiting for all members to submit preferences...

)}
{error && ( -
{error}
- )} - - {loading && animationData && ( -
-
- -
-

Generating Movies...

-

This may take a moment

-
+
{error}
)} - {!loading && ( - - )} +
diff --git a/components/party/party-results.tsx b/components/party/party-results.tsx index f9ada55..f93f57d 100644 --- a/components/party/party-results.tsx +++ b/components/party/party-results.tsx @@ -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'; @@ -22,11 +24,20 @@ export function PartyResults({ partySlug }: PartyResultsProps) { const [rankings, setRankings] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [confettiData, setConfettiData] = useState(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); @@ -100,16 +111,9 @@ export function PartyResults({ partySlug }: PartyResultsProps) { if (loading) { return ( - + -
-
-
-
-
-
-

Loading results...

-
+

Loading results...

); @@ -117,8 +121,8 @@ export function PartyResults({ partySlug }: PartyResultsProps) { if (error) { return ( - - + +

{error}

@@ -126,20 +130,24 @@ export function PartyResults({ partySlug }: PartyResultsProps) { } return ( -
- {/* All Done Message */} - - -

🎉 All Done! 🎉

-

Here are your personalized movie recommendations

-
-
- - +
+ {/* Confetti Animation Overlay */} + {confettiData && !loading && !error && rankings.length > 0 && ( +
+ +
+ )} + + - We think you should watch... + We think you should watch... - +
{rankings.map((movie, index) => { // First movie: vertical on mobile, horizontal on larger screens @@ -199,19 +207,19 @@ export function PartyResults({ partySlug }: PartyResultsProps) { return (
#{index + 1}
-

+

{movie.title}

{movie.genres.map((genre: string) => ( - + {genre} ))} @@ -219,10 +227,10 @@ export function PartyResults({ partySlug }: PartyResultsProps) {
-
+
{Math.round(movie.elo_rating)}
-
ELO Rating
+
ELO Rating
{movie.right_swipes} likes, {movie.left_swipes} passes
@@ -231,6 +239,39 @@ export function PartyResults({ partySlug }: PartyResultsProps) { ); })}
+ + {/* Back to Home Button */} +
+ + Back to Home + + + + +
diff --git a/components/party/party-tinder-cards.tsx b/components/party/party-tinder-cards.tsx index 8f716a4..27097ff 100644 --- a/components/party/party-tinder-cards.tsx +++ b/components/party/party-tinder-cards.tsx @@ -5,8 +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'; -import Lottie from 'lottie-react'; interface PartyTinderCardsProps { partySlug: string; @@ -27,16 +25,10 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp const [titleToDirectors, setTitleToDirectors] = useState>({}); const [titleToDescription, setTitleToDescription] = useState>({}); const [titleToRating, setTitleToRating] = useState>({}); - const [animationData, setAnimationData] = useState(null); // Fetch movies useEffect(() => { fetchMovies(); - // Load movie animation - fetch('/movie-animation.json') - .then((res) => res.json()) - .then((data) => setAnimationData(data)) - .catch((err) => console.error('Error loading animation:', err)); }, [partySlug]); // Set up realtime for movie updates @@ -248,145 +240,108 @@ export function PartyTinderCards({ partySlug, onComplete }: PartyTinderCardsProp if (loading) { return ( - - - {animationData ? ( -
-
- -
-

Loading movies...

-
- ) : ( -
-
-
-
-
- )} -
-
+
+
+
+

Loading movies...

+
+
); } if (error) { return ( - - -

{error}

-
-
+
+
+
⚠️
+

{error}

+
+
); } if (movies.length === 0) { return ( - - -

No movies available. The host needs to generate movies first.

-
-
+
+
+
🎬
+

+ No movies available. The host needs to generate movies first. +

+
+
); } const remainingCount = movies.length - swipedMovies.size; - const completedCount = swipedMovies.size; - const progressPercentage = movies.length > 0 ? (completedCount / movies.length) * 100 : 0; + const progressPercentage = ((movies.length - remainingCount) / movies.length) * 100; return ( -
- {/* Movie Animation Background - More Visible */} - {animationData && remainingCount > 0 && ( -
-
- +
+ {/* Enhanced Header Card */} +
+
+
+

+ Swipe through movies +

+
+
+
+
+
+ {remainingCount} left +
+
+
+
+
+ + {Math.round(progressPercentage)}% complete +
- )} - - {/* Dark gradient background */} - {remainingCount > 0 && ( -
- )} - - {/* Progress Bar */} - {remainingCount > 0 && ( - - -
- - 🎬 - Swipe through movies - -
-
- {completedCount} completed - {remainingCount} remaining -
-
-
-
-
+
+ + {/* Swipe Instructions */} + {remainingCount > 0 && remainingCount === movies.length && ( +
+
+
👆
+
+

Swipe right to like, left to pass

+

Or use the buttons below

- - +
+
)} + {/* Tinder Cards */} {remainingCount > 0 ? ( -
-
- - {/* Swipe instructions */} -
-

💡 Swipe right to like, left to pass

-
- - Pass - - - Like - -
-
-
+
+
) : ( - - -
- {animationData && ( -
- -
- )} -
-

All done! 🎉

-

+

+
+
🎉
+

All done!

+

Waiting for other members to finish swiping...

- - +
+
+
+
+
+
+
)}
);