diff --git a/package-lock.json b/package-lock.json index 075d3fde..ca07deb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@mui/styled-engine-sc": "^6.0.0-alpha.1", "@mui/system": "^5.14.13", "@react-native-async-storage/async-storage": "^1.18.2", - "@react-native-community/datetimepicker": "7.2.0", + "@react-native-community/datetimepicker": "^7.2.0", "@react-navigation/bottom-tabs": "^6.5.9", "@react-navigation/material-bottom-tabs": "^6.2.17", "@react-navigation/native": "^6.1.8", diff --git a/package.json b/package.json index 5518a736..7ba5f154 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@mui/styled-engine-sc": "^6.0.0-alpha.1", "@mui/system": "^5.14.13", "@react-native-async-storage/async-storage": "^1.18.2", - "@react-native-community/datetimepicker": "7.2.0", + "@react-native-community/datetimepicker": "^7.2.0", "@react-navigation/bottom-tabs": "^6.5.9", "@react-navigation/material-bottom-tabs": "^6.2.17", "@react-navigation/native": "^6.1.8", diff --git a/src/app/(tabs)/_layout.tsx b/src/app/(tabs)/_layout.tsx index aca39b9d..9fd9baf6 100644 --- a/src/app/(tabs)/_layout.tsx +++ b/src/app/(tabs)/_layout.tsx @@ -1,5 +1,5 @@ import { Tabs } from 'expo-router'; -import { Platform } from 'react-native'; +import { Platform, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Icon from '../../../assets/icons'; @@ -89,6 +89,13 @@ function TabNav() { }} /> + {authorInfo.name} {authorInfo?.pronouns && ( - {authorInfo.pronouns} + + {authorInfo.pronouns} + )} )} @@ -83,17 +84,19 @@ function AuthorScreen() { {authorInfo?.bio && ( <> - {decode(authorInfo.bio)} + {decode(authorInfo.bio)} )} {authorInfo?.artist_statement && ( <> - + Artist's Statement - + {decode(authorInfo.artist_statement)} diff --git a/src/app/(tabs)/author/styles.tsx b/src/app/(tabs)/author/styles.tsx index d85a4dd7..213b9e7b 100644 --- a/src/app/(tabs)/author/styles.tsx +++ b/src/app/(tabs)/author/styles.tsx @@ -10,28 +10,12 @@ const styles = StyleSheet.create({ justifyContent: 'flex-start', alignItems: 'flex-end', }, - name: { - fontWeight: 'bold', - fontSize: 24, - fontFamily: 'Manrope-Regular', - }, image: { height: 68, width: 68, backgroundColor: colors.darkGrey, borderRadius: 4, }, - bioText: { - color: 'black', - fontFamily: 'Manrope-Regular', - fontSize: 14, - }, - authorStatement: { - fontSize: 14, - color: 'black', - fontWeight: '400', - fontFamily: 'Manrope-Regular', - }, authorTextContainer: { paddingLeft: 20, }, @@ -40,9 +24,6 @@ const styles = StyleSheet.create({ borderTopWidth: 20, }, authorStatementTitle: { - fontWeight: 'bold', - fontFamily: 'Manrope-Regular', - fontSize: 16, marginBottom: 8, }, storyCountText: { @@ -50,7 +31,7 @@ const styles = StyleSheet.create({ marginBottom: 8, }, pronouns: { - color: '#797979', + color: colors.textGrey, }, }); diff --git a/src/app/(tabs)/home/index.tsx b/src/app/(tabs)/home/index.tsx index 7c224297..871b0eed 100644 --- a/src/app/(tabs)/home/index.tsx +++ b/src/app/(tabs)/home/index.tsx @@ -43,6 +43,7 @@ function HomeScreen() { fetchRecommendedStories().catch(() => []), fetchNewStories().catch(() => []), ]); + setUsername(usernameResponse); setFeaturedStories(featuredStoryResponse); setFeaturedStoriesDescription(featuredStoryDescriptionResponse); @@ -68,7 +69,7 @@ function HomeScreen() { contentContainerStyle={{ paddingHorizontal: 8 }} > - + {username ? `Welcome, ${username}` : 'Welcome!'} router.push('/settings')}> @@ -77,6 +78,7 @@ function HomeScreen() { + {featuredStories.length > 0 && ( Featured Stories @@ -86,7 +88,7 @@ function HomeScreen() { {featuredStories.map(story => ( {recommendedStories.map(story => ( router.push({ pathname: '/story', @@ -143,13 +146,14 @@ function HomeScreen() { horizontal showsHorizontalScrollIndicator={false} bounces={false} - style={styles.scrollView} + style={styles.scrollView2} > {newStories.map(story => ( router.push({ pathname: '/story', diff --git a/src/app/(tabs)/home/styles.ts b/src/app/(tabs)/home/styles.ts index 231f5d9d..e24896bc 100644 --- a/src/app/(tabs)/home/styles.ts +++ b/src/app/(tabs)/home/styles.ts @@ -19,9 +19,15 @@ const styles = StyleSheet.create({ marginTop: 12, marginBottom: 16, }, - scrollView: { - marginBottom: 20, + scrollView1: { + paddingBottom: 16, flexGrow: 0, + padding: 8, + }, + scrollView2: { + paddingBottom: 80, + flexGrow: 0, + padding: 8, }, headerContainer: { flexDirection: 'row', diff --git a/src/app/(tabs)/search/index.tsx b/src/app/(tabs)/search/index.tsx index 91cef808..81ae0bd0 100644 --- a/src/app/(tabs)/search/index.tsx +++ b/src/app/(tabs)/search/index.tsx @@ -1,7 +1,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { SearchBar } from '@rneui/themed'; import { router } from 'expo-router'; -import { useEffect, useState } from 'react'; +import { Fragment, useEffect, useState } from 'react'; import { Button, FlatList, @@ -198,18 +198,21 @@ function SearchScreen() { setShowRecents(true); setShowGenreCarousals(false); }} - searchIcon={false} - clearIcon + searchIcon + clearIcon={false} + cancelButtonProps={{ + buttonTextStyle: [globalStyles.body1Bold, styles.cancelButton], + }} containerStyle={[ styles.searchContainer, showGenreCarousals && { marginRight: 24 }, ]} inputContainerStyle={styles.inputContainer} - inputStyle={{ color: 'black' }} + inputStyle={globalStyles.body1Bold} leftIconContainerStyle={{}} rightIconContainerStyle={{}} - placeholder="Search" - placeholderTextColor="black" + placeholder="What do you want to read?" + placeholderTextColor="grey" onChangeText={text => searchFunction(text)} value={search} onSubmitEditing={searchString => { @@ -230,19 +233,44 @@ function SearchScreen() { )} {showRecents && - (search ? ( + (search && searchResults.length > 0 ? ( - - {searchResults.length}{' '} - {searchResults.length === 1 ? 'Story' : 'Stories'} + + Showing results 1-{searchResults.length} - ) : ( + ) : search && searchResults.length === 0 ? ( + + + + There are no stories + + + for "{search}". + + + + Try searching by title or author, or + + + check if your spelling is correct. + + + ) : recentSearches.length > 0 || recentlyViewed.length > 0 ? ( - Recent Searches + + Recent Searches + - Clear All + + Clear All + @@ -260,9 +288,18 @@ function SearchScreen() { - Recently Viewed + + Recently Viewed + - Clear All + + Clear All + @@ -286,6 +323,17 @@ function SearchScreen() { ))} + ) : ( + + + + Find stories from young creators. + + + + Search for stories, authors, or collections. + + ))} {showGenreCarousals ? ( diff --git a/src/app/(tabs)/search/styles.ts b/src/app/(tabs)/search/styles.ts index 648752e0..c1d184be 100644 --- a/src/app/(tabs)/search/styles.ts +++ b/src/app/(tabs)/search/styles.ts @@ -16,12 +16,15 @@ const styles = StyleSheet.create({ searchContainer: { backgroundColor: 'transparent', borderRadius: 10, - borderColor: 'transparent', marginBottom: 8, + borderColor: colors.grey, }, inputContainer: { - backgroundColor: '#D9D9D9', + backgroundColor: 'transparent', borderRadius: 10, + borderColor: colors.grey2, + borderWidth: 1, + borderBottomWidth: 1, }, greyOverlay: { flex: 1, @@ -51,19 +54,10 @@ const styles = StyleSheet.create({ marginBottom: 8, marginHorizontal: 8, }, - searchText: { - fontWeight: '500', - fontSize: 14, - }, numDisplay: { marginTop: 24, marginBottom: 8, }, - clearAll: { - color: colors.gwnOrange, - fontSize: 12, - fontWeight: '400', - }, contentContainerRecents: { paddingHorizontal: 8, marginBottom: 8, @@ -86,6 +80,16 @@ const styles = StyleSheet.create({ fontSize: 12, textDecorationLine: 'underline', }, + emptySearch: { + display: 'flex', + flexDirection: 'column', + textAlign: 'center', + alignItems: 'center', + marginTop: '60%', + }, + cancelButton: { + color: colors.grey, + }, }); export default styles; diff --git a/src/app/settings/_layout.tsx b/src/app/(tabs)/settings/_layout.tsx similarity index 100% rename from src/app/settings/_layout.tsx rename to src/app/(tabs)/settings/_layout.tsx diff --git a/src/app/settings/index.tsx b/src/app/(tabs)/settings/index.tsx similarity index 83% rename from src/app/settings/index.tsx rename to src/app/(tabs)/settings/index.tsx index bd846b2b..10bf4af9 100644 --- a/src/app/settings/index.tsx +++ b/src/app/(tabs)/settings/index.tsx @@ -13,13 +13,13 @@ import { SafeAreaView } from 'react-native-safe-area-context'; import { Icon } from 'react-native-elements'; import styles from './styles'; -import colors from '../../styles/colors'; -import AccountDataDisplay from '../../components/AccountDataDisplay/AccountDataDisplay'; -import StyledButton from '../../components/StyledButton/StyledButton'; -import UserSelectorInput from '../../components/UserSelectorInput/UserSelectorInput'; -import globalStyles from '../../styles/globalStyles'; -import { useSession } from '../../utils/AuthContext'; -import supabase from '../../utils/supabase'; +import colors from '../../../styles/colors'; +import AccountDataDisplay from '../../../components/AccountDataDisplay/AccountDataDisplay'; +import StyledButton from '../../../components/StyledButton/StyledButton'; +import UserSelectorInput from '../../../components/UserSelectorInput/UserSelectorInput'; +import globalStyles from '../../../styles/globalStyles'; +import { useSession } from '../../../utils/AuthContext'; +import supabase from '../../../utils/supabase'; import DateTimePickerModal from 'react-native-modal-datetime-picker'; function SettingsScreen() { @@ -57,7 +57,7 @@ function SettingsScreen() { const { data, error, status } = await supabase .from('profiles') .select( - `first_name, last_name, username, birthday, gender, race_ethnicity`, + `first_name, last_name, username, birthday, gender, race_ethnicity, pronouns`, ) .eq('user_id', session?.user.id) .single(); @@ -81,7 +81,7 @@ function SettingsScreen() { } setGender(data.gender || gender); - // setPronouns(data.pronouns || pronouns); + setPronouns(data.pronouns || pronouns); setRaceEthnicity(data.race_ethnicity || raceEthnicity); } } catch (error) { @@ -115,8 +115,6 @@ function SettingsScreen() { // Only update values that are not blank const updates = { - ...(firstName && { first_name: firstName }), - ...(lastName && { last_name: lastName }), ...(gender && { gender }), ...(pronouns && { pronouns }), ...(raceEthnicity && { race_ethnicity: raceEthnicity }), @@ -177,7 +175,10 @@ function SettingsScreen() { } return ( - + - - - - + + + + + {birthdayChanged && ( diff --git a/src/app/settings/styles.tsx b/src/app/(tabs)/settings/styles.tsx similarity index 92% rename from src/app/settings/styles.tsx rename to src/app/(tabs)/settings/styles.tsx index 580f7838..a5eceadc 100644 --- a/src/app/settings/styles.tsx +++ b/src/app/(tabs)/settings/styles.tsx @@ -1,7 +1,11 @@ import { StyleSheet } from 'react-native'; -import colors from '../../styles/colors'; +import colors from '../../../styles/colors'; export default StyleSheet.create({ + selectors: { + flex: 1, + gap: 16, + }, container: { flex: 1, backgroundColor: 'white', diff --git a/src/app/(tabs)/story/index.tsx b/src/app/(tabs)/story/index.tsx index 646a1e4a..73cbdfef 100644 --- a/src/app/(tabs)/story/index.tsx +++ b/src/app/(tabs)/story/index.tsx @@ -18,6 +18,8 @@ import { SafeAreaView } from 'react-native-safe-area-context'; import styles from './styles'; import { fetchStory } from '../../../queries/stories'; import { Story } from '../../../queries/types'; +import colors from '../../../styles/colors'; +import globalStyles, { fonts } from '../../../styles/globalStyles'; function StoryScreen() { const [isLoading, setLoading] = useState(true); @@ -72,9 +74,8 @@ function StoryScreen() { ref={scrollRef} showsVerticalScrollIndicator={false} > - {/* */} + {story?.title} - {story?.title} { router.push({ @@ -88,7 +89,9 @@ function StoryScreen() { style={styles.authorImage} source={{ uri: story.author_image ? story.author_image : '' }} /> - By {story.author_name} + + By {story.author_name} + @@ -99,50 +102,63 @@ function StoryScreen() { data={story.genre_medium} renderItem={({ item }) => ( - {item} + + {item} + )} /> - Author's Process + + Author's Process + @@ -150,7 +166,9 @@ function StoryScreen() { style={styles.authorImage} source={{ uri: story.author_image }} /> - By {story.author_name} + + By {story.author_name} + )} diff --git a/src/app/(tabs)/story/styles.ts b/src/app/(tabs)/story/styles.ts index cbe432a8..7e6e2c8c 100644 --- a/src/app/(tabs)/story/styles.ts +++ b/src/app/(tabs)/story/styles.ts @@ -1,4 +1,5 @@ import { StyleSheet } from 'react-native'; +import colors from '../../../styles/colors'; const styles = StyleSheet.create({ container: { @@ -10,11 +11,6 @@ const styles = StyleSheet.create({ paddingRight: 24, paddingTop: 48, }, - image: { - width: '100%', - height: 153, - marginBottom: 16, - }, authorImage: { backgroundColor: '#D9D9D9', width: 21, @@ -22,11 +18,6 @@ const styles = StyleSheet.create({ borderRadius: 100 / 2, }, title: { - fontFamily: 'Manrope-Regular', - fontSize: 24, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, author: { @@ -35,13 +26,6 @@ const styles = StyleSheet.create({ gap: 10, marginBottom: 16, }, - authorText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', - }, genres: { display: 'flex', flexDirection: 'row', @@ -59,61 +43,24 @@ const styles = StyleSheet.create({ marginRight: 8, }, genresText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - color: 'black', backgroundColor: '#D9D9D9', }, shareButtonText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', - textDecorationLine: 'underline', - backgroundColor: '#D9D9D9', + color: colors.white, }, excerpt: { - fontFamily: 'Manrope-Regular', - fontSize: 16, - fontWeight: '400', textAlign: 'left', - color: 'black', - paddingTop: 16, - paddingBottom: 16, + paddingVertical: 16, }, story: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, authorProcess: { - fontFamily: 'Manrope-Regular', - fontSize: 16, - fontWeight: '600', - textAlign: 'left', - color: 'black', marginBottom: 16, }, process: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, - backToTopButtonText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '800', - textAlign: 'left', - color: 'black', - }, }); export default styles; diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index 7e805eaa..c15ba80c 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -12,7 +12,6 @@ function StackLayout() { - diff --git a/src/app/auth/onboarding/index.tsx b/src/app/auth/onboarding/index.tsx index 5595e6cb..936624fb 100644 --- a/src/app/auth/onboarding/index.tsx +++ b/src/app/auth/onboarding/index.tsx @@ -1,4 +1,4 @@ -import { Redirect, router } from 'expo-router'; +import { Link, Redirect, router } from 'expo-router'; import { useState, useEffect } from 'react'; import { Alert, @@ -9,16 +9,17 @@ import { Appearance, } from 'react-native'; import { Icon } from 'react-native-elements'; +import DateTimePickerModal from 'react-native-modal-datetime-picker'; import styles from './styles'; -import colors from '../../../styles/colors'; import StyledButton from '../../../components/StyledButton/StyledButton'; import UserSelectorInput from '../../../components/UserSelectorInput/UserSelectorInput'; +import UserStringInput from '../../../components/UserStringInput/UserStringInput'; +import colors from '../../../styles/colors'; import globalStyles from '../../../styles/globalStyles'; import { useSession } from '../../../utils/AuthContext'; import supabase from '../../../utils/supabase'; -import UserStringInput from '../../../components/UserStringInput/UserStringInput'; -import DateTimePickerModal from 'react-native-modal-datetime-picker'; +import { SafeAreaView } from 'react-native-safe-area-context'; function OnboardingScreen() { const { session, user } = useSession(); @@ -127,6 +128,9 @@ function OnboardingScreen() { } } + while (router.canGoBack()) { + router.back(); + } router.replace('/home'); } catch (error) { if (error instanceof Error) { @@ -149,95 +153,107 @@ function OnboardingScreen() { } return ( - - - setShowDatePicker(false)} - date={displayDate} - display="inline" - isDarkModeEnabled={isDark} - themeVariant={isDark ? 'dark' : 'light'} - /> - - Welcome, {user?.user_metadata.username} - - - Input your profile information below. - - - - - This information is only used for outreach efforts, and will not be - visible to other users on the app. + + + + setShowDatePicker(false)} + date={displayDate} + display="inline" + isDarkModeEnabled={isDark} + themeVariant={isDark ? 'dark' : 'light'} + /> + + Welcome, {user?.user_metadata.username} - - - - { - setShowDatePicker(!showDatePicker); - }} - > - - + Input your profile information below. + + + + + This information is only used for outreach efforts, and will not + be visible to other users on the app. + + + + + { + setShowDatePicker(!showDatePicker); + }} > - - + + + + + + - + + + + - - - - - - - router.replace('/home')} - disabled={false} - /> - - + + + + + + Skip For Now + + + + ); } diff --git a/src/app/auth/onboarding/styles.tsx b/src/app/auth/onboarding/styles.tsx index 688d843b..6555413a 100644 --- a/src/app/auth/onboarding/styles.tsx +++ b/src/app/auth/onboarding/styles.tsx @@ -4,35 +4,41 @@ import colors from '../../../styles/colors'; export default StyleSheet.create({ container: { - flex: 1, backgroundColor: 'white', + flex: 1, + }, + flex: { + flexGrow: 1, + justifyContent: 'space-between', paddingTop: 64, - paddingLeft: 44, + paddingBottom: 54, + paddingLeft: 43, paddingRight: 44, }, - verticallySpaced: { + inputContainer: { flex: 1, - justifyContent: 'space-between', - }, - datePickerButton: { - paddingBottom: 16, + gap: 16, }, subtext: { color: colors.darkGrey, marginLeft: 8, }, - h1: { - marginTop: 66, - }, body1: { marginTop: 26, }, info: { flexDirection: 'row', marginTop: 12, - marginBottom: 16, width: 250, }, + updateProfileButton: { + marginBottom: 24, + }, + skipButton: { + flex: 1, + alignSelf: 'center', + color: colors.darkGrey, + }, icon: { paddingLeft: 8, }, diff --git a/src/app/auth/signup/index.tsx b/src/app/auth/signup/index.tsx index f7c9506f..fbaeb5cd 100644 --- a/src/app/auth/signup/index.tsx +++ b/src/app/auth/signup/index.tsx @@ -130,7 +130,7 @@ function SignUpScreen() { if (error) Alert.alert(error.message); else - router.push({ + router.replace({ pathname: '/auth/verify', params: { finalRedirect: 'onboarding' }, }); @@ -262,12 +262,12 @@ function SignUpScreen() { onPress={signUpWithEmail} /> - - Already have an account?{' '} + + Already have an account? Log In - + diff --git a/src/app/auth/signup/styles.tsx b/src/app/auth/signup/styles.tsx index 600bcb26..51de2d40 100644 --- a/src/app/auth/signup/styles.tsx +++ b/src/app/auth/signup/styles.tsx @@ -14,9 +14,11 @@ export default StyleSheet.create({ textDecorationLine: 'underline', }, redirectText: { - textAlign: 'center', - marginBottom: 64, + gap: 8, + flexDirection: 'row', + justifyContent: 'center', marginTop: 16, + marginBottom: 64, }, title: { paddingTop: 64, diff --git a/src/components/AccountDataDisplay/AccountDataDisplay.tsx b/src/components/AccountDataDisplay/AccountDataDisplay.tsx index a2d464f3..4faccfff 100644 --- a/src/components/AccountDataDisplay/AccountDataDisplay.tsx +++ b/src/components/AccountDataDisplay/AccountDataDisplay.tsx @@ -1,6 +1,7 @@ import { View, Text } from 'react-native'; import styles from './styles'; +import globalStyles from '../../styles/globalStyles'; type AccountDataDisplayProps = { label: string; @@ -10,9 +11,9 @@ type AccountDataDisplayProps = { function AccountDataDisplay({ label, value }: AccountDataDisplayProps) { return ( - {label} + {label} {typeof value === 'string' ? ( - {value} + {value} ) : ( value )} diff --git a/src/components/AccountDataDisplay/styles.tsx b/src/components/AccountDataDisplay/styles.tsx index 5d769230..78da8ddb 100644 --- a/src/components/AccountDataDisplay/styles.tsx +++ b/src/components/AccountDataDisplay/styles.tsx @@ -8,18 +8,11 @@ export default StyleSheet.create({ marginBottom: 26, }, label: { - fontSize: 12, - fontFamily: 'Manrope-Regular', - fontStyle: 'normal', - fontWeight: '400', color: colors.textGrey, }, value: { paddingTop: 18, paddingRight: 20, fontSize: 14, - fontFamily: 'Manrope-Regular', - fontStyle: 'normal', - fontWeight: '400', }, }); diff --git a/src/components/ContentCard/ContentCard.tsx b/src/components/ContentCard/ContentCard.tsx index 99486907..4301cb9f 100644 --- a/src/components/ContentCard/ContentCard.tsx +++ b/src/components/ContentCard/ContentCard.tsx @@ -4,6 +4,7 @@ import { Pressable, Text, View, + TouchableOpacity, } from 'react-native'; import styles from './styles'; @@ -13,6 +14,7 @@ type ContentCardProps = { title: string; author: string; image: string; + authorImage: string; pressFunction: (event: GestureResponderEvent) => void; }; @@ -20,19 +22,73 @@ function ContentCard({ title, author, image, + authorImage, pressFunction, }: ContentCardProps) { + const saveStory = () => { + console.log("testing '+' icon does something for story " + title); + }; + return ( - + + + + + - + {title} - - {author} - + + + By + + + {author} + + + + + null} + style={{ flexDirection: 'row' }} + > + + + + + + 14{/*change number to work*/} + + + + + saveStory()}> + + + diff --git a/src/components/ContentCard/savedStoriesIcon.png b/src/components/ContentCard/savedStoriesIcon.png new file mode 100644 index 00000000..65b2ea6e Binary files /dev/null and b/src/components/ContentCard/savedStoriesIcon.png differ diff --git a/src/components/ContentCard/styles.ts b/src/components/ContentCard/styles.ts index 1ea6f118..d4458704 100644 --- a/src/components/ContentCard/styles.ts +++ b/src/components/ContentCard/styles.ts @@ -7,19 +7,77 @@ const styles = StyleSheet.create({ marginRight: 20, flexDirection: 'column', justifyContent: 'space-between', + backgroundColor: '#FFF', + borderRadius: 6, + shadowColor: colors.black, + shadowOpacity: 0.5, + shadowOffset: { width: 0, height: 4 }, + shadowRadius: 5, + elevation: 4, }, image: { + margin: 10, + justifyContent: 'center', + alignItems: 'center', height: 140, width: 148, backgroundColor: colors.lime, borderRadius: 4, marginBottom: 8, }, + authors: { + width: 30, + height: 30, + borderRadius: 30, + borderWidth: 1, + backgroundColor: '#89CFF0', + borderColor: 'white', + marginTop: 15, + marginLeft: -45, + flexDirection: 'row', + }, textContainer: { - width: 148, + width: 166, + paddingLeft: 10, + paddingRight: 10, + paddingBottom: 10, }, title: { - marginBottom: 4, + marginBottom: 8, + padding: 0, + }, + reactionText: { + color: colors.grey, + }, + reactionNumber: { + marginLeft: 15, + marginTop: 10, + }, + reactions: { + width: 20, + height: 20, + borderRadius: 20 / 2, + borderWidth: 1, + backgroundColor: '#89CFF0', //different per emoji reaction + borderColor: 'white', + marginTop: 10, + marginRight: -10, + }, + buttons: { + flexDirection: 'row', + justifyContent: 'space-between', + marginTop: 5, + }, + by: { + fontFamily: 'Manrope-Regular', + fontSize: 10, + color: colors.grey, + }, + authorSpacing: { + flexDirection: 'row', + alignItems: 'center', + gap: 4, + overflow: 'hidden', }, }); diff --git a/src/components/PreviewCard/PreviewCard.tsx b/src/components/PreviewCard/PreviewCard.tsx index 121c4952..84910f88 100644 --- a/src/components/PreviewCard/PreviewCard.tsx +++ b/src/components/PreviewCard/PreviewCard.tsx @@ -1,3 +1,4 @@ +import * as cheerio from 'cheerio'; import { GestureResponderEvent, Image, @@ -5,7 +6,6 @@ import { Text, View, } from 'react-native'; -import * as cheerio from 'cheerio'; import styles from './styles'; import globalStyles from '../../styles/globalStyles'; diff --git a/src/components/PreviewCard/styles.ts b/src/components/PreviewCard/styles.ts index d69aae26..e8af8f2c 100644 --- a/src/components/PreviewCard/styles.ts +++ b/src/components/PreviewCard/styles.ts @@ -11,8 +11,8 @@ const styles = StyleSheet.create({ marginTop: 8, marginBottom: 8, shadowColor: 'black', - shadowOffset: { width: 0, height: 4 }, - shadowOpacity: 0.5, + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.2, elevation: 4, }, image: { diff --git a/src/components/RecentSearchCard/RecentSearchCard.tsx b/src/components/RecentSearchCard/RecentSearchCard.tsx index eb77fcc6..e142baee 100644 --- a/src/components/RecentSearchCard/RecentSearchCard.tsx +++ b/src/components/RecentSearchCard/RecentSearchCard.tsx @@ -21,10 +21,14 @@ function RecentSearchCard({ - {value} + + {value} + - {numResults} Results + + {numResults} Results + diff --git a/src/components/RecentSearchCard/styles.ts b/src/components/RecentSearchCard/styles.ts index 676937de..b0cb9012 100644 --- a/src/components/RecentSearchCard/styles.ts +++ b/src/components/RecentSearchCard/styles.ts @@ -1,4 +1,5 @@ import { StyleSheet } from 'react-native'; +import colors from '../../styles/colors'; const styles = StyleSheet.create({ card: { @@ -13,10 +14,11 @@ const styles = StyleSheet.create({ paddingRight: 12, paddingBottom: 10, paddingTop: 10, + shadowColor: 'black', - shadowOffset: { width: 0, height: 4 }, - shadowOpacity: 0.5, - elevation: 4, + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.3, + elevation: 7, }, leftItems: { gap: 8, @@ -29,9 +31,6 @@ const styles = StyleSheet.create({ alignItems: 'center', }, searchValueText: { - color: 'black', - fontWeight: '400', - fontSize: 14, justifyContent: 'center', }, numResultsText: { diff --git a/src/components/StyledButton/styles.tsx b/src/components/StyledButton/styles.tsx index 4e664ced..b2c4dc94 100644 --- a/src/components/StyledButton/styles.tsx +++ b/src/components/StyledButton/styles.tsx @@ -13,7 +13,7 @@ export default StyleSheet.create({ }, titleStyle: { paddingHorizontal: 24, - paddingVertical: 10, + paddingVertical: 5, color: 'white', }, }); diff --git a/src/components/UserSelectorInput/UserSelectorInput.tsx b/src/components/UserSelectorInput/UserSelectorInput.tsx index dd5be4fc..a032b1ab 100644 --- a/src/components/UserSelectorInput/UserSelectorInput.tsx +++ b/src/components/UserSelectorInput/UserSelectorInput.tsx @@ -24,7 +24,7 @@ function UserSelectorInput({ value, }: UserSelectorInputProps) { return ( - + {label} ( diff --git a/src/components/UserSelectorInput/styles.tsx b/src/components/UserSelectorInput/styles.tsx index ad54c0ab..734f782b 100644 --- a/src/components/UserSelectorInput/styles.tsx +++ b/src/components/UserSelectorInput/styles.tsx @@ -10,17 +10,15 @@ export default StyleSheet.create({ position: 'relative', zIndex: 1, }, - container: { - marginBottom: 16, - }, label: { - marginBottom: 10, + marginBottom: 8, }, dropdown: { - height: 50, + height: 44, borderWidth: 1, borderRadius: 5, paddingHorizontal: 10, + paddingVertical: 10, }, dropdownContainer: { borderRadius: 5, diff --git a/src/components/UserStringInput/UserStringInput.tsx b/src/components/UserStringInput/UserStringInput.tsx index f7cd12d6..6d2d586b 100644 --- a/src/components/UserStringInput/UserStringInput.tsx +++ b/src/components/UserStringInput/UserStringInput.tsx @@ -2,8 +2,8 @@ import { ReactNode } from 'react'; import { View, Text, TextInput } from 'react-native'; import styles from './styles'; -import globalStyles from '../../styles/globalStyles'; import colors from '../../styles/colors'; +import globalStyles from '../../styles/globalStyles'; type UserStringInputProps = { placeholder: string; @@ -23,7 +23,7 @@ export default function UserStringInput({ label, children, labelColor = '#000', - placeholderTextColor = '#000', + placeholderTextColor = colors.darkGrey, onChange = _ => {}, }: UserStringInputProps) { return ( diff --git a/src/components/UserStringInput/styles.tsx b/src/components/UserStringInput/styles.tsx index a11509d5..5642a55e 100644 --- a/src/components/UserStringInput/styles.tsx +++ b/src/components/UserStringInput/styles.tsx @@ -14,7 +14,6 @@ export default StyleSheet.create({ borderWidth: 1, borderRadius: 5, borderColor: 'black', - fontFamily: 'Manrope-Regular', }, inputField: { flex: 1, diff --git a/src/queries/reactions.tsx b/src/queries/reactions.tsx new file mode 100644 index 00000000..8a9da888 --- /dev/null +++ b/src/queries/reactions.tsx @@ -0,0 +1,79 @@ +import { Reactions } from './types'; +import supabase from '../utils/supabase'; + +export async function addReactionToStory( + input_profile_id: number, + input_story_id: number, + input_reaction_id: number, +): Promise { + const { data, error } = await supabase.rpc('add_reaction_to_story', { + story_id: input_story_id, + profile_id: input_profile_id, + reaction_id: input_reaction_id, + }); + if (error) { + console.log(error); + throw new Error( + `An error occured when trying to insert author reaction to story: ${error}`, + ); + } else { + return data; + } +} + +export async function deleteReactionToStory( + input_profile_id: number, + input_story_id: number, + input_reaction_id: number, +): Promise { + const { data, error } = await supabase.rpc('remove_reaction_from_story', { + story_id: input_story_id, + profile_id: input_profile_id, + reaction_id: input_reaction_id, + }); + if (error) { + console.log(error); + throw new Error( + `An error occured when trying to delete reaction to story by a user: ${error}`, + ); + } else { + return data; + } +} + +export async function fetchAllReactionsToStory( + storyId: number, +): Promise { + const { data, error } = await supabase.rpc('curr_get_reactions_for_story', { + input_story_id: storyId, + }); + if (error) { + console.log(error); + throw new Error( + `An error occured when trying to fetch reactions to a story', ${error}`, + ); + } else { + return data; + } +} + +export async function fetchReactionsToStoryByUser( + story_id: number, + profile_id: number, +): Promise { + const { data, error } = await supabase.rpc( + 'get_reactions_for_user_and_story', + { + _story_id: story_id, + _profile_id: profile_id, + }, + ); + if (error) { + console.log(error); + throw new Error( + `An error occured when trying to fetch reactions for user and story ${error}`, + ); + } else { + return data; + } +} diff --git a/src/queries/types.tsx b/src/queries/types.tsx index eefba267..60748adc 100644 --- a/src/queries/types.tsx +++ b/src/queries/types.tsx @@ -47,6 +47,7 @@ export interface StoryCard { title: string; author_name: string; featured_media: string; + author_image: string; } export interface Subgenre { @@ -67,3 +68,10 @@ export interface GenreStories { subgenre_name: string; genre_story_previews: string[]; } + +export interface Reactions { + profile_id: number; + story_id: number; + emoji_id: number; + emoji: string; +} diff --git a/src/styles/colors.ts b/src/styles/colors.ts index 73d10142..af1f15f4 100644 --- a/src/styles/colors.ts +++ b/src/styles/colors.ts @@ -14,6 +14,7 @@ const colors = { fadedBlack: '#2D2D2D', white: '#FBFBFB', grey: '#A7A5A5', + grey2: '#D9D9D9', darkGrey: '#797979', textPrimary: '#000000', // black diff --git a/src/styles/globalStyles.ts b/src/styles/globalStyles.ts index ef9e2cb3..12e17283 100644 --- a/src/styles/globalStyles.ts +++ b/src/styles/globalStyles.ts @@ -79,6 +79,12 @@ export default StyleSheet.create({ textAlign: 'left', color: 'black', }, + body2Bold: { + fontFamily: 'Manrope-Bold', + fontSize: 16, + textAlign: 'left', + color: 'black', + }, body3: { fontFamily: 'Manrope-Regular', fontSize: 18, @@ -135,3 +141,5 @@ export default StyleSheet.create({ marginTop: 20, }, }); + +export const fonts = ['Manrope-Bold', 'Manrope-Regular', 'Manrope-Semibold'];