Skip to content

Commit

Permalink
[home] Implement backend queries & restyle StoryPreview component (#34)
Browse files Browse the repository at this point in the history
* done restyling home screen

* cleanup, add author profile pics

* updated queries for schema change to jsonb type

* pr review changes

* fix user not being set from saved session, add onPress functions
  • Loading branch information
akshaynthakur authored Nov 14, 2023
1 parent 65602ee commit 63a41f6
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 190 deletions.
2 changes: 2 additions & 0 deletions assets/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export type IconType =
| 'home_outline'
| 'document_outline'
| 'search_outline'
| 'settings_gear'
| 'close_modal_button';

const IconSvgs: Record<IconType, React.ReactElement> = {
home_outline: <Ionicons name="home-outline" size={23} />,
search_outline: <Ionicons name="search-outline" size={23} />,
document_outline: <Ionicons name="document-outline" size={23} />,
settings_gear: <Ionicons name="settings-outline" size={32} />,
close_modal_button: (
<SvgXml
xml={`<svg
Expand Down
231 changes: 147 additions & 84 deletions src/app/(tabs)/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,102 +1,165 @@
import { Link } from 'expo-router';
import { Button, ScrollView, Text, View } from 'react-native';
import { router } from 'expo-router';
import { useEffect, useState } from 'react';
import { Pressable, ScrollView, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
import Icon from '../../../../assets/icons';
import ContentCard from '../../../components/ContentCard/ContentCard';
import SearchCard from '../../../components/SearchCard/SearchCard';
import PreviewCard from '../../../components/PreviewCard/PreviewCard';
import { fetchUsername } from '../../../queries/profiles';
import {
fetchFeaturedStoriesDescription,
fetchFeaturedStoryPreviews,
fetchNewStories,
fetchRecommendedStories,
} from '../../../queries/stories';
import { StoryCard, StoryPreview } from '../../../queries/types';
import globalStyles from '../../../styles/globalStyles';

const dummyStories = [
{
title: 'The Witch and Her Wings',
author: 'Victoria V.',
image: '',
author_image: '',
tags: ['Non-fiction', 'Mysterious', 'Goofy', 'Silly', 'Adventurous'],
},
{
title: "It's Carnival",
author: 'Victoria V.',
image: '',
author_image: '',
tags: ['Non-fiction', 'Mysterious'],
},
{
title: "Akshay's Adventures",
author: 'Victoria V.',
image: '',
author_image: '',
tags: ['Non-fiction', 'Mysterious'],
},
];
import { useSession } from '../../../utils/AuthContext';

function HomeScreen() {
const { user } = useSession();
const [username, setUsername] = useState('');
const [loading, setLoading] = useState(true);
const [featuredStories, setFeaturedStories] = useState<StoryPreview[]>([]);
const [featuredStoriesDescription, setFeaturedStoriesDescription] =
useState<string>('');
const [recommendedStories, setRecommendedStories] = useState<StoryCard[]>([]);
const [newStories, setNewStories] = useState<StoryCard[]>([]);

useEffect(() => {
(async () => {
const [
usernameResponse,
featuredStoryResponse,
featuredStoryDescriptionResponse,
recommendedStoriesResponse,
newStoriesResponse,
] = await Promise.all([
fetchUsername(user?.id).catch(() => ''),
fetchFeaturedStoryPreviews().catch(() => []),
fetchFeaturedStoriesDescription().catch(() => ''),
fetchRecommendedStories().catch(() => []),
fetchNewStories().catch(() => []),
]);
setUsername(usernameResponse);
setFeaturedStories(featuredStoryResponse);
setFeaturedStoriesDescription(featuredStoryDescriptionResponse);
setRecommendedStories(recommendedStoriesResponse);
setNewStories(newStoriesResponse);
})().finally(() => {
setLoading(false);
});
}, [user]);
return (
<SafeAreaView style={globalStyles.container}>
<SafeAreaView style={[globalStyles.container, { marginHorizontal: -8 }]}>
{loading && (
<View style={styles.loading}>
<Text>Loading</Text>
</View>
)}
<ScrollView
horizontal={false}
showsVerticalScrollIndicator={false}
bounces={false}
contentContainerStyle={{ paddingHorizontal: 8 }}
>
<View style={styles.headerContainer}>
<Text style={globalStyles.h4}>Welcome, Brenda</Text>
<Link href="/settings" asChild>
<Button title="Settings" />
</Link>
</View>
<Text style={styles.featuredSubheading}>Featured Stories</Text>
<Text style={[globalStyles.body2, styles.featuredDescription]}>
Celebrate lorem ipsum by diving into related stories from our talented
authors.
</Text>
<View style={styles.featuredContainer}>
{dummyStories.map(story => (
<SearchCard
key={story.title}
title={story.title}
author={story.author}
image={story.image}
authorImage={story.author_image}
tags={story.tags}
pressFunction={() => null}
/>
))}
<Text style={globalStyles.h2}>
{username ? `Welcome, ${username}` : 'Welcome!'}
</Text>
<Pressable onPress={() => router.push('/settings')}>
<View>
<Icon type="settings_gear" />
</View>
</Pressable>
</View>
<Text style={styles.subheading}>Recommended For You</Text>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
bounces={false}
style={styles.scrollView}
>
{dummyStories.map(story => (
<ContentCard
key={story.title}
title={story.title}
author={story.author}
pressFunction={() => null}
image={story.image}
/>
))}
</ScrollView>
<Text style={styles.subheading}>New Stories</Text>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
bounces={false}
style={styles.scrollView}
>
{dummyStories.map(story => (
<ContentCard
key={story.title}
title={story.title}
author={story.author}
pressFunction={() => null}
image={story.image}
/>
))}
</ScrollView>
{featuredStories.length > 0 && (
<View>
<Text style={globalStyles.h3}>Featured Stories</Text>
<Text style={[globalStyles.body1, styles.featuredDescription]}>
{featuredStoriesDescription}
</Text>
<View>
{featuredStories.map(story => (
<PreviewCard
key={story.title}
title={story.title}
image={story.featured_media}
author={story.author_name}
authorImage={story.author_image}
excerpt={story.excerpt}
tags={story.genre_medium
.concat(story.tone)
.concat(story.topic)}
pressFunction={() =>
router.push({
pathname: '/story',
params: { storyId: story.id.toString() },
})
}
/>
))}
</View>
</View>
)}
{recommendedStories.length > 0 && (
<View>
<Text style={[globalStyles.h3, styles.subheading]}>
Recommended For You
</Text>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
bounces={false}
style={styles.scrollView}
>
{recommendedStories.map(story => (
<ContentCard
key={story.title}
title={story.title}
author={story.author_name}
pressFunction={() =>
router.push({
pathname: '/story',
params: { storyId: story.id.toString() },
})
}
image={story.featured_media}
/>
))}
</ScrollView>
</View>
)}
{newStories.length > 0 && (
<View>
<Text style={[globalStyles.h3, styles.subheading]}>
New Stories
</Text>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
bounces={false}
style={styles.scrollView}
>
{newStories.map(story => (
<ContentCard
key={story.title}
title={story.title}
author={story.author_name}
pressFunction={() =>
router.push({
pathname: '/story',
params: { storyId: story.id.toString() },
})
}
image={story.featured_media}
/>
))}
</ScrollView>
</View>
)}
</ScrollView>
</SafeAreaView>
);
Expand Down
34 changes: 18 additions & 16 deletions src/app/(tabs)/home/styles.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { StyleSheet } from 'react-native';
import { Dimensions, StyleSheet } from 'react-native';

import colors from '../../../styles/colors';
const { width, height } = Dimensions.get('window');

const styles = StyleSheet.create({
subheading: {
fontSize: 16,
fontWeight: '800',
textAlign: 'left',
lineHeight: 24,
color: 'black',
marginBottom: 12,
loading: {
backgroundColor: colors.white,
flex: 1,
position: 'absolute',
left: 0,
top: 0,
width,
height,
zIndex: 1,
padding: 50,
},
featuredSubheading: {
fontSize: 16,
fontWeight: '800',
textAlign: 'left',
lineHeight: 24,
color: 'black',
marginBottom: 8,
subheading: {
marginTop: 12,
marginBottom: 16,
},
scrollView: {
marginBottom: 20,
Expand All @@ -30,8 +32,8 @@ const styles = StyleSheet.create({
},
featuredDescription: {
marginBottom: 16,
marginTop: 8,
},
featuredContainer: {},
});

export default styles;
6 changes: 4 additions & 2 deletions src/app/(tabs)/search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
import FilterModal from '../../../components/FilterModal/FilterModal';
import SearchCard from '../../../components/SearchCard/SearchCard';
import SearchCard from '../../../components/PreviewCard/PreviewCard';
import { fetchAllStoryPreviews } from '../../../queries/stories';
import { StoryPreview } from '../../../queries/types';
import globalStyles from '../../../styles/globalStyles';
Expand Down Expand Up @@ -66,13 +66,15 @@ function SearchScreen() {
<FlatList
showsVerticalScrollIndicator={false}
data={searchResults}
contentContainerStyle={{}}
renderItem={({ item }) => (
<SearchCard
key={item.title}
title={item.title}
author={item.author_name}
image={item.featured_media}
author={item.author_name}
authorImage={item.author_image}
excerpt={item.excerpt}
tags={item.genre_medium}
pressFunction={() =>
router.push({
Expand Down
2 changes: 1 addition & 1 deletion src/app/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function SettingsScreen() {

return (
<SafeAreaView style={globalStyles.container}>
<Text style={globalStyles.h1}>Settings</Text>
<Text style={globalStyles.h2}>Settings</Text>
<View style={[globalStyles.verticallySpaced, globalStyles.mt20]}>
<Input label="Email" value={session?.user?.email} disabled />
</View>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ContentCard/ContentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function ContentCard({
<View style={styles.contentCard}>
<Image style={styles.image} source={{ uri: image }} />
<View style={styles.textContainer}>
<Text style={[globalStyles.body1, styles.title]} numberOfLines={1}>
<Text style={[globalStyles.h4, styles.title]} numberOfLines={1}>
{title}
</Text>
<Text style={globalStyles.body1} numberOfLines={1}>
Expand Down
4 changes: 3 additions & 1 deletion src/components/ContentCard/styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { StyleSheet } from 'react-native';

import colors from '../../styles/colors';

const styles = StyleSheet.create({
contentCard: {
marginRight: 20,
Expand All @@ -9,7 +11,7 @@ const styles = StyleSheet.create({
image: {
height: 140,
width: 148,
backgroundColor: '#D9D9D9',
backgroundColor: colors.lime,
borderRadius: 4,
marginBottom: 8,
},
Expand Down
Loading

0 comments on commit 63a41f6

Please sign in to comment.