From 07c77eecca29901a5eae85685b4fe07d5f2b3e80 Mon Sep 17 00:00:00 2001 From: tGiech22 Date: Fri, 5 Dec 2025 10:54:05 -0500 Subject: [PATCH 1/4] feat: adding carousel and swiping of carousel to top of home page --- frontend/components/Carousel.tsx | 10 +++- frontend/screen/HomeScreen.tsx | 83 ++++++++++++++++++++++++++------ 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/frontend/components/Carousel.tsx b/frontend/components/Carousel.tsx index b19e19f..0735b2f 100644 --- a/frontend/components/Carousel.tsx +++ b/frontend/components/Carousel.tsx @@ -20,10 +20,13 @@ export default function MyCarousel({ components, width, height }: CarouselProps) const carouselHeight = (height / 100) * screenHeight; return ( - + { const newIndex = Math.round( @@ -31,10 +34,12 @@ export default function MyCarousel({ components, width, height }: CarouselProps) ); setCurrentIndex(newIndex); }} + scrollEventThrottle={16} + contentContainerStyle={{ height: carouselHeight }} style={{ width: carouselWidth, height: carouselHeight }} > {components.map((component, index) => ( - + {component} ))} @@ -67,6 +72,7 @@ const styles = StyleSheet.create({ carouselItem: { justifyContent: "center", alignItems: "center", + height: "100%", }, pagination: { flexDirection: "row", diff --git a/frontend/screen/HomeScreen.tsx b/frontend/screen/HomeScreen.tsx index ace2194..a4764db 100644 --- a/frontend/screen/HomeScreen.tsx +++ b/frontend/screen/HomeScreen.tsx @@ -11,9 +11,11 @@ import { import { Feather } from '@expo/vector-icons'; import { router } from 'expo-router'; import tw from 'twrnc'; +import { LinearGradient } from 'expo-linear-gradient'; import SearchBar from '../components/SearchBar'; import TabToggle from '../components/TabToggle'; import SectionHeader from '../components/SectionHeader'; +import Carousel from '../components/Carousel'; export type HomeScreenProps = { user?: any; @@ -21,12 +23,71 @@ export type HomeScreenProps = { }; export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { - const screenWidth = Dimensions.get('window').width; + const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); const heroHeight = Math.min(screenWidth * 0.6, 320); + const heroHeightPercent = (heroHeight / screenHeight) * 100; const primaryNavColor = '#D62E05'; const inactiveNavColor = '#979797'; const navOptions = ['For You', 'Friends', 'Trending', 'Country']; const navTabs = navOptions.map(label => ({ key: label, label })); + const heroSlides = [ + { + uri: 'https://image.tmdb.org/t/p/original/8Vt6mWEReuy4Of61Lnj5Xj704m8.jpg', + title: 'Across the Spider-Verse', + subtitle: 'Miles and Gwen swing across the multiverse.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/AtFG8L1Jf3GOMcxNnTvMXLfxJ9v.jpg', + title: 'Dune: Part Two', + subtitle: 'Paul and Chani stride through Arrakis dunes.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/kyeqWdyUXW608qlYkRqosgbbJyK.jpg', + title: 'Oppenheimer', + subtitle: 'The Trinity test ignites the desert horizon.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/rqbCbjB19amtOtFQbb3K2lgm2zv.jpg', + title: 'The Batman', + subtitle: 'Batman surveys Gotham from the skyline.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/euYcyqv5J19t1SYwQ8d3tNbBlPR.jpg', + title: 'Mad Max: Fury Road', + subtitle: 'Furiosa leads the rig through the sandstorm.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/wC4H1Z0YvSuFAvauGmDx5hOaP6F.jpg', + title: 'La La Land', + subtitle: 'Seb and Mia dance above the city lights.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/s9Mqz1TQO2wy7h0T4z9NJ1ONwW3.jpg', + title: 'Everything Everywhere All at Once', + subtitle: 'Evelyn spirals through the multiverse.', + }, + { + uri: 'https://image.tmdb.org/t/p/original/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg', + title: 'Wonder Woman', + subtitle: 'Diana crosses No Man’s Land.', + }, + ]; + const heroComponents = heroSlides.map(slide => ( + + + {slide.title} + {slide.subtitle} + + + )); const quickActionButtons = [ { label: 'Browse Movies', @@ -62,21 +123,13 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { contentContainerStyle={[tw`pb-28`]} showsVerticalScrollIndicator={false} > - {/* Hero image */} + {/* Hero carousel */} - - - - - + {/* Category nav */} From 737946faf6d15627ec668485a68c644b3e2b72a7 Mon Sep 17 00:00:00 2001 From: tGiech22 Date: Fri, 5 Dec 2025 17:59:23 -0500 Subject: [PATCH 2/4] feat: adding posts to each tab on the home page --- frontend/components/TabToggle.tsx | 2 +- frontend/screen/HomeScreen.tsx | 221 +++++++++++++++++++++++++++--- 2 files changed, 203 insertions(+), 20 deletions(-) diff --git a/frontend/components/TabToggle.tsx b/frontend/components/TabToggle.tsx index 56153e8..238aa95 100644 --- a/frontend/components/TabToggle.tsx +++ b/frontend/components/TabToggle.tsx @@ -77,7 +77,7 @@ const styles = StyleSheet.create({ borderBottomColor: 'transparent', }, tabText: { - fontSize: width * 0.04, + fontSize: width * 0.036, fontWeight: '500', color: '#666', }, diff --git a/frontend/screen/HomeScreen.tsx b/frontend/screen/HomeScreen.tsx index a4764db..a2e5760 100644 --- a/frontend/screen/HomeScreen.tsx +++ b/frontend/screen/HomeScreen.tsx @@ -7,6 +7,8 @@ import { ImageBackground, Dimensions, SafeAreaView, + Image, + StyleSheet, } from 'react-native'; import { Feather } from '@expo/vector-icons'; import { router } from 'expo-router'; @@ -28,60 +30,175 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { const heroHeightPercent = (heroHeight / screenHeight) * 100; const primaryNavColor = '#D62E05'; const inactiveNavColor = '#979797'; - const navOptions = ['For You', 'Friends', 'Trending', 'Country']; + const navOptions = ['For You', 'Friends', 'Trending']; const navTabs = navOptions.map(label => ({ key: label, label })); + const postsByTab: Record< + string, + { + id: string; + userName: string; + username: string; + date: string; + content: string; + imageUri?: string; + }[] + > = { + 'For You': [ + { + id: 'fy-1', + userName: 'Lena Morales', + username: 'lenam', + date: '2h ago', + content: + 'Caught a surprise Q&A with the director last night—this shot of the neon skyline was unreal.', + imageUri: + 'https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=1600&q=80', + }, + { + id: 'fy-2', + userName: 'Khalid Noor', + username: 'knoor', + date: '3h ago', + content: + 'If you loved slow-burn thrillers, add “North Passage” to your list. No jumpscares—just dread.', + }, + { + id: 'fy-3', + userName: 'Ava Chen', + username: 'ava.chen', + date: '5h ago', + content: + 'Festival reminder: short docs block starts at 7pm. Best seat is back row, right of center.', + imageUri: + 'https://images.unsplash.com/photo-1464375117522-1311d6a5b81f?auto=format&fit=crop&w=1600&q=80', + }, + ], + Friends: [ + { + id: 'fr-1', + userName: 'Miguel Soto', + username: 'migs', + date: '1h ago', + content: + 'Double-feature night: classic noir then animated short. Snacks ready, lights off.', + imageUri: + 'https://images.unsplash.com/photo-1497032205916-ac775f0649ae?auto=format&fit=crop&w=1600&q=80', + }, + { + id: 'fr-2', + userName: 'Priya Patel', + username: 'priyap', + date: '4h ago', + content: + 'Posted my review of “Riverlights.” Score’s great but the third act needed another pass.', + }, + { + id: 'fr-3', + userName: 'Jonas Meyer', + username: 'jonas.m', + date: '6h ago', + content: + 'Anyone heading to the rooftop screening tomorrow? I’ve got two extra tickets.', + }, + ], + Trending: [ + { + id: 'tr-1', + userName: 'Spotlight Daily', + username: 'spotlight', + date: 'Just now', + content: + 'Box office watch: “Starfall” just crossed the $150M mark domestically.', + }, + { + id: 'tr-2', + userName: 'Festival Lens', + username: 'festivalens', + date: '50m ago', + content: + 'This candid from the Venice premiere is everywhere for a reason.', + imageUri: + 'https://images.unsplash.com/photo-1520699514109-9012a284e1d9?auto=format&fit=crop&w=1600&q=80', + }, + { + id: 'tr-3', + userName: 'Cinema Beat', + username: 'cinemabeat', + date: '2h ago', + content: + 'Editor’s pick: five micro-budget films that punch way above their weight.', + }, + ], + }; const heroSlides = [ { + id: 'spider-verse', uri: 'https://image.tmdb.org/t/p/original/8Vt6mWEReuy4Of61Lnj5Xj704m8.jpg', title: 'Across the Spider-Verse', subtitle: 'Miles and Gwen swing across the multiverse.', }, { + id: 'dune-part-two', uri: 'https://image.tmdb.org/t/p/original/AtFG8L1Jf3GOMcxNnTvMXLfxJ9v.jpg', title: 'Dune: Part Two', subtitle: 'Paul and Chani stride through Arrakis dunes.', }, { + id: 'oppenheimer', uri: 'https://image.tmdb.org/t/p/original/kyeqWdyUXW608qlYkRqosgbbJyK.jpg', title: 'Oppenheimer', subtitle: 'The Trinity test ignites the desert horizon.', }, { + id: 'the-batman', uri: 'https://image.tmdb.org/t/p/original/rqbCbjB19amtOtFQbb3K2lgm2zv.jpg', title: 'The Batman', subtitle: 'Batman surveys Gotham from the skyline.', }, { + id: 'mad-max-fury-road', uri: 'https://image.tmdb.org/t/p/original/euYcyqv5J19t1SYwQ8d3tNbBlPR.jpg', title: 'Mad Max: Fury Road', subtitle: 'Furiosa leads the rig through the sandstorm.', }, { + id: 'la-la-land', uri: 'https://image.tmdb.org/t/p/original/wC4H1Z0YvSuFAvauGmDx5hOaP6F.jpg', title: 'La La Land', subtitle: 'Seb and Mia dance above the city lights.', }, { + id: 'everything-everywhere', uri: 'https://image.tmdb.org/t/p/original/s9Mqz1TQO2wy7h0T4z9NJ1ONwW3.jpg', title: 'Everything Everywhere All at Once', subtitle: 'Evelyn spirals through the multiverse.', }, { + id: 'wonder-woman', uri: 'https://image.tmdb.org/t/p/original/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg', title: 'Wonder Woman', subtitle: 'Diana crosses No Man’s Land.', }, ]; - const heroComponents = heroSlides.map(slide => ( + const [hiddenHeroIds, setHiddenHeroIds] = React.useState>(new Set()); + const visibleHeroSlides = heroSlides.filter(slide => !hiddenHeroIds.has(slide.id)); + const hideSlideOnError = (id: string) => { + setHiddenHeroIds(prev => { + const next = new Set(prev); + next.add(id); + return next; + }); + }; + const heroComponents = visibleHeroSlides.map(slide => ( hideSlideOnError(slide.id)} > {slide.title} {slide.subtitle} @@ -145,21 +262,37 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { {/* Feed area under nav */} - {activeNav === 'For You' ? ( - - - - Your personalized feed will appear here soon. - - - ) : ( - - - - Content for {activeNav} will appear here. - - - )} + + {postsByTab[activeNav].map(post => ( + + + + + + {post.userName + .split(' ') + .map(part => part[0]) + .join('') + .slice(0, 2)} + + + + {post.userName} + @{post.username} · {post.date} + + + + {post.content} + {post.imageUri && ( + + )} + + ))} + {/* Optional: show who's signed in */} @@ -182,3 +315,53 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { ); } + +const styles = StyleSheet.create({ + postCard: { + backgroundColor: '#FFF', + borderRadius: 14, + padding: 14, + marginBottom: 12, + borderWidth: 1, + borderColor: '#EFEFEF', + }, + postHeader: { + flexDirection: 'row', + alignItems: 'center', + }, + avatarPlaceholder: { + width: 36, + height: 36, + borderRadius: 18, + backgroundColor: '#F4F4F5', + alignItems: 'center', + justifyContent: 'center', + }, + avatarInitials: { + fontWeight: '700', + color: '#D62E05', + }, + author: { + fontSize: 15, + fontWeight: '700', + color: '#111827', + }, + metaText: { + fontSize: 12, + color: '#6B7280', + marginTop: 2, + }, + postText: { + fontSize: 14, + color: '#111827', + lineHeight: 20, + marginTop: 10, + marginBottom: 10, + }, + postImage: { + width: '100%', + height: 180, + borderRadius: 12, + backgroundColor: '#E5E7EB', + }, +}); From 1a1dcc4a4048d566b69886baf6c347e03d3b7749 Mon Sep 17 00:00:00 2001 From: Dylan Anctil <134968796+danctila@users.noreply.github.com> Date: Fri, 5 Dec 2025 18:21:53 -0500 Subject: [PATCH 3/4] Nav bar colors - hard coded home page data --- frontend/screen/HomeScreen.tsx | 443 +++++++++++++++++-------- frontend/styles/BottomNavBar.styles.ts | 8 +- 2 files changed, 303 insertions(+), 148 deletions(-) diff --git a/frontend/screen/HomeScreen.tsx b/frontend/screen/HomeScreen.tsx index a2e5760..a00c757 100644 --- a/frontend/screen/HomeScreen.tsx +++ b/frontend/screen/HomeScreen.tsx @@ -7,7 +7,6 @@ import { ImageBackground, Dimensions, SafeAreaView, - Image, StyleSheet, } from 'react-native'; import { Feather } from '@expo/vector-icons'; @@ -16,14 +15,40 @@ import tw from 'twrnc'; import { LinearGradient } from 'expo-linear-gradient'; import SearchBar from '../components/SearchBar'; import TabToggle from '../components/TabToggle'; -import SectionHeader from '../components/SectionHeader'; import Carousel from '../components/Carousel'; +import TextPost from '../components/TextPost'; +import PicturePost from '../components/PicturePost'; +import ReviewPost from '../components/ReviewPost'; +import InteractionBar from '../components/InteractionBar'; +import UserBar from '../components/UserBar'; export type HomeScreenProps = { user?: any; onSignOut?: () => Promise; }; +type Post = { + id: string; + type: 'text' | 'picture' | 'review'; + userName: string; + username: string; + date: string; + content: string; + imageUrls?: string[]; + movieTitle?: string; + rating?: number; + movieImageUrl?: string; + userId?: string; + reviewerName?: string; + reviewerUserId?: string; + commentCount?: number; + reactions?: Array<{ + emoji: string; + count: number; + selected: boolean; + }>; +}; + export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); const heroHeight = Math.min(screenWidth * 0.6, 320); @@ -32,104 +57,216 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { const inactiveNavColor = '#979797'; const navOptions = ['For You', 'Friends', 'Trending']; const navTabs = navOptions.map(label => ({ key: label, label })); - const postsByTab: Record< - string, - { - id: string; - userName: string; - username: string; - date: string; - content: string; - imageUri?: string; - }[] - > = { + + const postsByTab: Record = { 'For You': [ { id: 'fy-1', - userName: 'Lena Morales', - username: 'lenam', + type: 'review', + userName: 'Arjun Kapoor', + username: 'arjunk', date: '2h ago', - content: - 'Caught a surprise Q&A with the director last night—this shot of the neon skyline was unreal.', - imageUri: - 'https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=1600&q=80', + content: 'Check out this new review that I just dropped!', + reviewerName: 'Arjun Kapoor', + reviewerUserId: 'user-1', + movieTitle: 'RRR', + rating: 5, + movieImageUrl: + 'https://image.tmdb.org/t/p/original/wE0I6efAW4cDDmZQWtwZMOW44EJ.jpg', + userId: 'user-1', + commentCount: 24, + reactions: [ + { emoji: '🌶️', count: 12, selected: false }, + { emoji: '✨', count: 18, selected: false }, + { emoji: '🧠', count: 8, selected: false }, + { emoji: '🧨', count: 45, selected: true }, + ], }, { id: 'fy-2', - userName: 'Khalid Noor', - username: 'knoor', + type: 'text', + userName: 'Priya Sharma', + username: 'priyasharma', date: '3h ago', content: - 'If you loved slow-burn thrillers, add “North Passage” to your list. No jumpscares—just dread.', + 'Just watched 3 Idiots for the 10th time and it still makes me cry. Aamir Khan\'s performance is timeless. "All is well" will forever be iconic! 🎓', + userId: 'user-2', + commentCount: 15, + reactions: [ + { emoji: '🌶️', count: 5, selected: false }, + { emoji: '✨', count: 23, selected: true }, + { emoji: '🧠', count: 17, selected: false }, + { emoji: '🧨', count: 9, selected: false }, + ], }, { id: 'fy-3', - userName: 'Ava Chen', - username: 'ava.chen', + type: 'picture', + userName: 'Raj Malhotra', + username: 'rajm', date: '5h ago', content: - 'Festival reminder: short docs block starts at 7pm. Best seat is back row, right of center.', - imageUri: - 'https://images.unsplash.com/photo-1464375117522-1311d6a5b81f?auto=format&fit=crop&w=1600&q=80', + 'Found this hidden gem of a theater in Mumbai that still shows classic Bollywood films. Caught a screening of Sholay last night - the experience was magical! 🎬', + imageUrls: [ + 'https://images.unsplash.com/photo-1598899134739-24c46f58b8c0?auto=format&fit=crop&w=1600&q=80', + 'https://images.unsplash.com/photo-1489599849927-2ee91cede3ba?auto=format&fit=crop&w=1600&q=80', + ], + userId: 'user-3', + commentCount: 8, + reactions: [ + { emoji: '🌶️', count: 3, selected: false }, + { emoji: '✨', count: 12, selected: false }, + { emoji: '🧠', count: 4, selected: false }, + { emoji: '🧨', count: 6, selected: false }, + ], + }, + { + id: 'fy-4', + type: 'review', + userName: 'Kavya Reddy', + username: 'kavyar', + date: '6h ago', + content: 'Check out this new review that I just dropped!', + reviewerName: 'Kavya Reddy', + reviewerUserId: 'user-4', + movieTitle: 'Baahubali 2: The Conclusion', + rating: 4.5, + movieImageUrl: + 'https://image.tmdb.org/t/p/original/9oKwLM9XlhVGGNnKkOJ8ovjQ3cG.jpg', + userId: 'user-4', + commentCount: 32, + reactions: [ + { emoji: '🌶️', count: 8, selected: false }, + { emoji: '✨', count: 28, selected: false }, + { emoji: '🧠', count: 12, selected: false }, + { emoji: '🧨', count: 56, selected: false }, + ], }, ], Friends: [ { id: 'fr-1', - userName: 'Miguel Soto', - username: 'migs', + type: 'picture', + userName: 'Aisha Khan', + username: 'aishak', date: '1h ago', content: - 'Double-feature night: classic noir then animated short. Snacks ready, lights off.', - imageUri: - 'https://images.unsplash.com/photo-1497032205916-ac775f0649ae?auto=format&fit=crop&w=1600&q=80', + "Movie night with the squad! We're doing a Shahrukh Khan marathon - starting with Dilwale Dulhania Le Jayenge. Who else is a SRK fan? 👑", + imageUrls: [ + 'https://images.unsplash.com/photo-1505686994434-e3cc5abf1330?auto=format&fit=crop&w=1600&q=80', + ], + userId: 'user-5', + commentCount: 11, + reactions: [ + { emoji: '🌶️', count: 4, selected: false }, + { emoji: '✨', count: 19, selected: true }, + { emoji: '🧠', count: 2, selected: false }, + { emoji: '🧨', count: 7, selected: false }, + ], }, { id: 'fr-2', - userName: 'Priya Patel', - username: 'priyap', + type: 'text', + userName: 'Vikram Singh', + username: 'vikrams', date: '4h ago', content: - 'Posted my review of “Riverlights.” Score’s great but the third act needed another pass.', + "Andhadhun is a masterpiece! The way Sriram Raghavan keeps you guessing till the very end is brilliant. If you haven't seen it yet, what are you waiting for? 🎹", + userId: 'user-6', + commentCount: 21, + reactions: [ + { emoji: '🌶️', count: 14, selected: false }, + { emoji: '✨', count: 8, selected: false }, + { emoji: '🧠', count: 31, selected: true }, + { emoji: '🧨', count: 5, selected: false }, + ], }, { id: 'fr-3', - userName: 'Jonas Meyer', - username: 'jonas.m', + type: 'review', + userName: 'Meera Patel', + username: 'meerap', date: '6h ago', - content: - 'Anyone heading to the rooftop screening tomorrow? I’ve got two extra tickets.', + content: 'Check out this new review that I just dropped!', + reviewerName: 'Meera Patel', + reviewerUserId: 'user-7', + movieTitle: 'Dangal', + rating: 5, + movieImageUrl: + 'https://image.tmdb.org/t/p/original/9bCNo1FXwW9r1v9w5mYYxY8b5sO.jpg', + userId: 'user-7', + commentCount: 18, + reactions: [ + { emoji: '🌶️', count: 6, selected: false }, + { emoji: '✨', count: 15, selected: false }, + { emoji: '🧠', count: 22, selected: false }, + { emoji: '🧨', count: 11, selected: false }, + ], }, ], Trending: [ { id: 'tr-1', - userName: 'Spotlight Daily', - username: 'spotlight', + type: 'text', + userName: 'Bollywood Insider', + username: 'bollyinsider', date: 'Just now', content: - 'Box office watch: “Starfall” just crossed the $150M mark domestically.', + "Box office update: Jawan crosses ₹1000 crore worldwide! Shah Rukh Khan proves he's still the king! 👑💰", + userId: 'user-8', + commentCount: 67, + reactions: [ + { emoji: '🌶️', count: 23, selected: false }, + { emoji: '✨', count: 45, selected: false }, + { emoji: '🧠', count: 12, selected: false }, + { emoji: '🧨', count: 89, selected: true }, + ], }, { id: 'tr-2', - userName: 'Festival Lens', - username: 'festivalens', + type: 'picture', + userName: 'Cinema Chronicles', + username: 'cinemachronicles', date: '50m ago', content: - 'This candid from the Venice premiere is everywhere for a reason.', - imageUri: - 'https://images.unsplash.com/photo-1520699514109-9012a284e1d9?auto=format&fit=crop&w=1600&q=80', + 'Behind the scenes from the Pathaan shoot! The action sequences were filmed across 8 countries. Indian cinema is truly going global! 🌍', + imageUrls: [ + 'https://images.unsplash.com/photo-1485846234645-a62644f84728?auto=format&fit=crop&w=1600&q=80', + ], + userId: 'user-9', + commentCount: 43, + reactions: [ + { emoji: '🌶️', count: 18, selected: false }, + { emoji: '✨', count: 52, selected: false }, + { emoji: '🧠', count: 9, selected: false }, + { emoji: '🧨', count: 71, selected: false }, + ], }, { id: 'tr-3', - userName: 'Cinema Beat', - username: 'cinemabeat', + type: 'review', + userName: 'Rohan Verma', + username: 'rohanv', date: '2h ago', - content: - 'Editor’s pick: five micro-budget films that punch way above their weight.', + content: 'Check out this new review that I just dropped!', + reviewerName: 'Rohan Verma', + reviewerUserId: 'user-10', + movieTitle: 'Tumbbad', + rating: 4.5, + movieImageUrl: + 'https://image.tmdb.org/t/p/original/wDlMQdNQJqFn1pekaXGqxqC9pBg.jpg', + userId: 'user-10', + commentCount: 29, + reactions: [ + { emoji: '🌶️', count: 31, selected: true }, + { emoji: '✨', count: 19, selected: false }, + { emoji: '🧠', count: 42, selected: false }, + { emoji: '🧨', count: 14, selected: false }, + ], }, ], }; + const heroSlides = [ { id: 'spider-verse', @@ -177,11 +314,16 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { id: 'wonder-woman', uri: 'https://image.tmdb.org/t/p/original/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg', title: 'Wonder Woman', - subtitle: 'Diana crosses No Man’s Land.', + subtitle: "Diana crosses No Man's Land.", }, ]; - const [hiddenHeroIds, setHiddenHeroIds] = React.useState>(new Set()); - const visibleHeroSlides = heroSlides.filter(slide => !hiddenHeroIds.has(slide.id)); + + const [hiddenHeroIds, setHiddenHeroIds] = React.useState>( + new Set() + ); + const visibleHeroSlides = heroSlides.filter( + slide => !hiddenHeroIds.has(slide.id) + ); const hideSlideOnError = (id: string) => { setHiddenHeroIds(prev => { const next = new Set(prev); @@ -200,30 +342,89 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { colors={['rgba(0,0,0,0.55)', 'rgba(0,0,0,0.15)']} style={{ flex: 1, padding: 16, justifyContent: 'flex-end' }} > - {slide.title} + + {slide.title} + {slide.subtitle} )); - const quickActionButtons = [ - { - label: 'Browse Movies', - icon: , - onPress: () => router.push('movies'), - }, - { - label: 'Find Events', - icon: , - onPress: () => router.push('events'), - }, - { - label: 'Profile', - icon: , - onPress: () => router.push('profile'), - }, - ]; + const [activeNav, setActiveNav] = React.useState(navOptions[0]); + const renderPost = (post: Post, index: number, totalPosts: number) => { + if (post.type === 'review') { + return ( + + + + {post.content} + + + {index < totalPosts - 1 && } + + ); + } else if (post.type === 'picture') { + return ( + + + + + + + + {index < totalPosts - 1 && } + + ); + } else { + // text post + return ( + + + + + + + + {index < totalPosts - 1 && } + + ); + } + }; + return ( {/* Feed area under nav */} - - - {postsByTab[activeNav].map(post => ( - - - - - - {post.userName - .split(' ') - .map(part => part[0]) - .join('') - .slice(0, 2)} - - - - {post.userName} - @{post.username} · {post.date} - - - - {post.content} - {post.imageUri && ( - - )} - - ))} + + + {postsByTab[activeNav].map((post, index) => + renderPost(post, index, postsByTab[activeNav].length) + )} @@ -316,52 +491,32 @@ export default function HomeScreen({ user, onSignOut }: HomeScreenProps) { ); } +const { width } = Dimensions.get('window'); + const styles = StyleSheet.create({ - postCard: { + reviewItemContainer: { backgroundColor: '#FFF', - borderRadius: 14, - padding: 14, - marginBottom: 12, - borderWidth: 1, - borderColor: '#EFEFEF', + paddingHorizontal: width * 0.04, + paddingTop: width * 0.04, + paddingBottom: width * 0.04, }, - postHeader: { - flexDirection: 'row', - alignItems: 'center', - }, - avatarPlaceholder: { - width: 36, - height: 36, - borderRadius: 18, - backgroundColor: '#F4F4F5', - alignItems: 'center', - justifyContent: 'center', - }, - avatarInitials: { - fontWeight: '700', - color: '#D62E05', - }, - author: { - fontSize: 15, - fontWeight: '700', - color: '#111827', + postContainer: { + backgroundColor: '#FFF', + paddingTop: width * 0.04, }, - metaText: { - fontSize: 12, - color: '#6B7280', - marginTop: 2, + interactionWrapper: { + paddingHorizontal: width * 0.04, + paddingBottom: width * 0.04, }, - postText: { - fontSize: 14, - color: '#111827', - lineHeight: 20, - marginTop: 10, - marginBottom: 10, + reviewShareText: { + fontSize: width * 0.04, + color: '#000', + marginTop: width * 0.03, + marginBottom: width * 0.04, }, - postImage: { - width: '100%', - height: 180, - borderRadius: 12, - backgroundColor: '#E5E7EB', + divider: { + height: 1, + backgroundColor: '#E0E0E0', + marginVertical: 0, }, }); diff --git a/frontend/styles/BottomNavBar.styles.ts b/frontend/styles/BottomNavBar.styles.ts index 9afa76b..fa62ec1 100644 --- a/frontend/styles/BottomNavBar.styles.ts +++ b/frontend/styles/BottomNavBar.styles.ts @@ -14,16 +14,16 @@ export const styles = StyleSheet.create({ paddingHorizontal: width * 0.015, }, item: { alignItems: "center", justifyContent: "center" }, - postButton: { color: "#000", fontSize: width * 0.105}, + postButton: { color: "#561202", fontSize: width * 0.105}, activeIcon: { - color: "#9A0169", + color: "#D62E05", fontWeight: "600", fontSize: width * 0.07 }, icon: { - color: "#9A0169", + color: "#F7D5CD", fontWeight: "100", - opacity: 0.6, + opacity: 1, fontSize: width * 0.07 }, }); \ No newline at end of file From ad049ddd1ff9505d56a209c4b51663ed59bfb0eb Mon Sep 17 00:00:00 2001 From: Dylan Anctil <134968796+danctila@users.noreply.github.com> Date: Fri, 5 Dec 2025 18:28:05 -0500 Subject: [PATCH 4/4] Fix type issue --- frontend/components/Carousel.tsx | 1 - frontend/types/api-generated.ts | 109 +++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/frontend/components/Carousel.tsx b/frontend/components/Carousel.tsx index 823c82f..0735b2f 100644 --- a/frontend/components/Carousel.tsx +++ b/frontend/components/Carousel.tsx @@ -28,7 +28,6 @@ export default function MyCarousel({ components, width, height }: CarouselProps) directionalLockEnabled decelerationRate="fast" showsHorizontalScrollIndicator={false} - nestedScrollEnabled={true} onMomentumScrollEnd={(event) => { const newIndex = Math.round( event.nativeEvent.contentOffset.x / carouselWidth diff --git a/frontend/types/api-generated.ts b/frontend/types/api-generated.ts index f7b74cf..9bababd 100644 --- a/frontend/types/api-generated.ts +++ b/frontend/types/api-generated.ts @@ -177,6 +177,115 @@ export interface paths { patch?: never; trace?: never; }; + "/api/translate": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: { + text?: string; + dl?: string; + sl?: string; + }; + header?: { + authorization?: string; + }; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/languages": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: never; + header?: { + authorization?: string; + }; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/swagger-output.json": { parameters: { query?: never;