diff --git a/App.js b/App.js
index ac101a5..16c7469 100644
--- a/App.js
+++ b/App.js
@@ -1,18 +1,109 @@
import { StatusBar } from "expo-status-bar";
-import React from "react";
+import React, { useReducer } from "react";
import { StyleSheet, Text, View } from "react-native";
import { useFonts } from "expo-font";
import Colors from "./constants/Colors";
-import Navigator from "./navigation/stackNavigator";
import AppLoading from "expo-app-loading";
+import { enableScreens } from "react-native-screens";
+
+// Navigation Packages
+import { NavigationContainer } from "@react-navigation/native";
+import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+// Contexts
+import { reducerInitalState, ReducerContext } from "./contexts";
+import reducer from "./contexts/reducer";
+// Screens and Icons
+import { Ionicons } from "@expo/vector-icons";
+import Favorites from "./screens/Favorites";
+import HomeAndProfileStack from "./components/HomeAndProfileStack";
+import FavoritesAndProfileStack from "./components/FavoritesAndProfileStack";
+// Navigators
+const Tabs = createBottomTabNavigator();
+
+enableScreens();
+
export default function App() {
+ const [state, dispatch] = useReducer(reducer, reducerInitalState);
+
const [fontsLoaded] = useFonts({
Quicksand: require("./assets/fonts/Quicksand-Regular.ttf"),
"Quicksand-SB": require("./assets/fonts/Quicksand-SemiBold.ttf"),
"Quicksand-Bold": require("./assets/fonts/Quicksand-Bold.ttf"),
});
if (!fontsLoaded) return ;
- return ;
+
+ return (
+
+
+
+
+
+ {
+ const focusedTextStyles = {
+ color: props.color,
+ fontFamily: "Quicksand-Bold",
+ };
+ return (
+
+
+
+ Home
+
+
+ );
+ },
+ }}
+ />
+ (
+
+
+
+ Favorites
+
+
+ ),
+ }}
+ />
+
+
+
+ );
}
const styles = StyleSheet.create({
@@ -21,4 +112,12 @@ const styles = StyleSheet.create({
backgroundColor: Colors.primary,
justifyContent: "center",
},
+ iconContainer: {
+ justifyContent: "center",
+ alignItems: "center",
+ // width: 45,
+ },
+ tabText: {
+ fontFamily: "Quicksand-SB",
+ },
});
diff --git a/app.json b/app.json
index 86e62cc..5ed9c8b 100644
--- a/app.json
+++ b/app.json
@@ -2,13 +2,13 @@
"expo": {
"name": "Breaking Bad App",
"slug": "Breaking-Bad-App",
- "version": "1.0.0",
+ "version": "1.1.1",
"orientation": "portrait",
- "icon": "./assets/icon.png",
+ "icon": "./assets/icon1.png",
"splash": {
- "image": "./assets/splash.png",
- "resizeMode": "contain",
- "backgroundColor": "#ffffff"
+ "image": "./assets/Splash1.png",
+ "resizeMode": "cover",
+ "backgroundColor": "#282c34"
},
"updates": {
"fallbackToCacheTimeout": 0
@@ -21,8 +21,8 @@
},
"android": {
"adaptiveIcon": {
- "foregroundImage": "./assets/adaptive-icon.png",
- "backgroundColor": "#FFFFFF"
+ "foregroundImage": "./assets/icon1.png",
+ "backgroundColor": "#6a7ca3"
},
"package": "com.developedbynick.BreakingBadApp"
},
diff --git a/assets/Splash1.png b/assets/Splash1.png
new file mode 100644
index 0000000..638d588
Binary files /dev/null and b/assets/Splash1.png differ
diff --git a/assets/icon.png b/assets/icon.png
deleted file mode 100644
index a0b1526..0000000
Binary files a/assets/icon.png and /dev/null differ
diff --git a/assets/icon1.png b/assets/icon1.png
new file mode 100644
index 0000000..cd7b74a
Binary files /dev/null and b/assets/icon1.png differ
diff --git a/assets/splash.png b/assets/splash.png
deleted file mode 100644
index 6f47774..0000000
Binary files a/assets/splash.png and /dev/null differ
diff --git a/components/BoldText.js b/components/BoldText.js
new file mode 100644
index 0000000..071d599
--- /dev/null
+++ b/components/BoldText.js
@@ -0,0 +1,18 @@
+import React from "react";
+import { StyleSheet, Text } from "react-native";
+
+const BoldText = (props) => {
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default BoldText;
+
+const styles = StyleSheet.create({
+ boldText: {
+ fontFamily: "Quicksand-Bold",
+ },
+});
diff --git a/components/Character.js b/components/Character.js
index 6099b2a..8a24dd8 100644
--- a/components/Character.js
+++ b/components/Character.js
@@ -9,16 +9,16 @@ import {
const Character = ({ character, navigation }) => {
const navigateHandler = () =>
- navigation.navigate("CharacterProfile", character);
+ navigation.navigate("CharacterProfile", { character });
return (
{
+ return (
+
+
+ {
+ const { character } = route.params;
+
+ return {
+ headerTitle: character.name,
+ headerStyle: {
+ backgroundColor: Colors.primary,
+ elevation: 0,
+ shadowColor: "transparent",
+ },
+ headerTintColor: "white",
+ headerTitleStyle: {
+ fontFamily: "Quicksand-SB",
+ },
+ headerRight: () => ,
+
+ headerRightContainerStyle: {
+ width: 50,
+ justifyContent: "center",
+ alignItems: "center",
+ height: "100%",
+ },
+ headerLeftContainerStyle: {
+ width: 50,
+ justifyContent: "center",
+ alignItems: "center",
+ height: "100%",
+ },
+ };
+ }}
+ name="CharacterProfile"
+ component={CharacterProfile}
+ />
+
+ );
+};
+
+export default FavoritesAndProfileStack;
diff --git a/components/HomeAndProfileStack.js b/components/HomeAndProfileStack.js
new file mode 100644
index 0000000..109bf8d
--- /dev/null
+++ b/components/HomeAndProfileStack.js
@@ -0,0 +1,56 @@
+import { TouchableOpacity, View, Text } from "react-native";
+import Home from "../screens/Home";
+import CharacterProfile from "../screens/CharacterProfile";
+import React, { useState, useEffect } from "react";
+import { createStackNavigator } from "@react-navigation/stack";
+import Colors from "../constants/Colors";
+import { Ionicons } from "@expo/vector-icons";
+import ProfileHeaderRight from "./ProfileHeaderRight";
+const Stack = createStackNavigator();
+
+const HomeAndProfileStack = () => {
+ return (
+
+
+ {
+ const { character } = route.params;
+ const { char_id } = character;
+ return {
+ headerTitle: character.name,
+ headerStyle: {
+ backgroundColor: Colors.primary,
+ elevation: 0,
+ shadowColor: "transparent",
+ },
+ headerTintColor: "white",
+ headerTitleStyle: {
+ fontFamily: "Quicksand-SB",
+ },
+ headerRight: () => ,
+
+ headerRightContainerStyle: {
+ width: 50,
+ justifyContent: "center",
+ alignItems: "center",
+ height: "100%",
+ },
+ headerLeftContainerStyle: {
+ width: 50,
+ justifyContent: "center",
+ alignItems: "center",
+ height: "100%",
+ },
+ };
+ }}
+ name="CharacterProfile"
+ component={CharacterProfile}
+ />
+
+ );
+};
+export default HomeAndProfileStack;
diff --git a/components/KeyValue.js b/components/KeyValue.js
deleted file mode 100644
index e69de29..0000000
diff --git a/components/ProfileHeaderRight.js b/components/ProfileHeaderRight.js
new file mode 100644
index 0000000..75f8824
--- /dev/null
+++ b/components/ProfileHeaderRight.js
@@ -0,0 +1,47 @@
+import React, { useState, useEffect, useContext } from "react";
+import { ReducerContext } from "../contexts";
+import { ACTIONS } from "../contexts/reducer";
+import { StyleSheet, TouchableOpacity } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+const ProfileHeaderRight = ({ route }) => {
+ const context = useContext(ReducerContext);
+
+ const { character } = route.params;
+ const { char_id } = character;
+ const [starred, setStarred] = useState(false);
+ const toggleStar = () => setStarred(!starred);
+ useEffect(() => {
+ const isCharacterFavorited = context.state.favorites.some(
+ (fav) => fav.char_id === char_id
+ );
+ if (isCharacterFavorited) setStarred(true);
+ else setStarred(false);
+ }, [context.state.favorites.length]);
+
+ const toggleFavorites = () => {
+ if (starred) {
+ // If character is already starred, we should setStarred to false, and remove character from favorites
+ toggleStar();
+ const newFavs = context.state.favorites.filter(
+ (fav) => fav.char_id !== char_id
+ );
+ context.dispatch({ type: ACTIONS.REMOVE_FAVORITE, newFavs });
+ } else {
+ toggleStar();
+ context.dispatch({ type: ACTIONS.ADD_FAVORITE, character });
+ }
+ };
+ return (
+
+
+
+ );
+};
+
+export default ProfileHeaderRight;
+
+const styles = StyleSheet.create({});
diff --git a/contexts/index.js b/contexts/index.js
new file mode 100644
index 0000000..de065a7
--- /dev/null
+++ b/contexts/index.js
@@ -0,0 +1,6 @@
+import { createContext } from "react";
+
+export const ReducerContext = createContext();
+export const reducerInitalState = {
+ favorites: [],
+};
diff --git a/contexts/reducer.js b/contexts/reducer.js
new file mode 100644
index 0000000..8710f26
--- /dev/null
+++ b/contexts/reducer.js
@@ -0,0 +1,19 @@
+export const ACTIONS = {
+ REMOVE_FAVORITE: "REMOVE_FAVORITE",
+ ADD_FAVORITE: "ADD_FAVORITE",
+};
+
+const reducer = (state, action) => {
+ if (action.type === ACTIONS.ADD_FAVORITE) {
+ return {
+ ...state,
+ favorites: [...state.favorites, { ...action.character }],
+ };
+ }
+ if (action.type === ACTIONS.REMOVE_FAVORITE) {
+ return { ...state, favorites: action.newFavs };
+ }
+ return { ...state };
+};
+
+export default reducer;
diff --git a/navigation/stackNavigator.js b/navigation/stackNavigator.js
deleted file mode 100644
index 321f6d8..0000000
--- a/navigation/stackNavigator.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { createAppContainer } from "react-navigation";
-import { createStackNavigator } from "react-navigation-stack";
-
-// Screens
-import Home from "../screens/Home";
-import CharacterProfile from "../screens/CharacterProfile";
-// Constants
-import Colors from "../constants/Colors";
-
-const StackNavigator = createStackNavigator(
- {
- Home: {
- screen: Home,
- navigationOptions: {
- headerShown: false,
- },
- },
- CharacterProfile: {
- screen: CharacterProfile,
- },
- },
- {
- defaultNavigationOptions: {
- headerStyle: {
- backgroundColor: Colors.primary,
- elevation: 0,
- },
- headerTintColor: "white",
- headerTitleAlign: "left",
- headerTitleStyle: {
- fontFamily: "Quicksand-SB",
- fontWeight: "500",
- },
- },
- }
-);
-
-export default createAppContainer(StackNavigator);
diff --git a/package-lock.json b/package-lock.json
index f0739c8..3a9daa3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,14 @@
{
- "name": "test-project-v2",
+ "name": "breaking-bad-app",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"@react-native-community/masked-view": "^0.1.10",
+ "@react-navigation/bottom-tabs": "^5.11.13",
+ "@react-navigation/native": "^5.9.6",
+ "@react-navigation/stack": "^5.14.7",
"expo": "~42.0.1",
"expo-app-loading": "^1.1.2",
"expo-status-bar": "~1.0.4",
@@ -3125,6 +3128,22 @@
"react-native": ">=0.57"
}
},
+ "node_modules/@react-navigation/bottom-tabs": {
+ "version": "5.11.13",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.13.tgz",
+ "integrity": "sha512-Z8VAt76S7K8zqjwqfGJ7kC/E8LMDs8hEYgQYv5+JOG+zh9bCx1IAHV5RSDExVMcMDSFVFDerEK68wb49w4hFPQ==",
+ "dependencies": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^5.0.5",
+ "react": "*",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 0.6.0",
+ "react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0"
+ }
+ },
"node_modules/@react-navigation/core": {
"version": "3.7.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-3.7.9.tgz",
@@ -3145,12 +3164,74 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@react-navigation/native": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.8.4.tgz",
- "integrity": "sha512-gXSVcL7bfFDyVkvyg1FiAqTCIgZub5K1X/TZqURBs2CPqDpfX1OsCtB9D33eTF14SpbfgHW866btqrrxoCACfg==",
+ "version": "5.9.6",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.6.tgz",
+ "integrity": "sha512-m2F2AWBr0qbi4a5MBk2puGNWyVQnfmVHcpuIzQ37juptX6QCCuXjmOxvtdyqRzh2gKGnUlIeNaQKcACYj4zG/w==",
"dependencies": {
- "hoist-non-react-statics": "^3.3.2",
- "react-native-safe-area-view": "^0.14.9"
+ "@react-navigation/core": "^5.15.5",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@react-navigation/native/node_modules/@react-navigation/core": {
+ "version": "5.15.5",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.15.5.tgz",
+ "integrity": "sha512-xrUQ0xVQTMuuMiILRhhRpBzoI4TaFh4dJ4INCy6uwK9dwHjLwtsx+++ZefV/K4tbMQmGFxq4zSnLtTRtfMZKrA==",
+ "dependencies": {
+ "@react-navigation/routers": "^5.7.4",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15",
+ "query-string": "^6.13.6",
+ "react-is": "^16.13.0"
+ },
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
+ "node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@react-navigation/native/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/@react-navigation/routers": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.4.tgz",
+ "integrity": "sha512-0N202XAqsU/FlE53Nmh6GHyMtGm7g6TeC93mrFAFJOqGRKznT0/ail+cYlU6tNcPA9AHzZu1Modw1eoDINSliQ==",
+ "dependencies": {
+ "nanoid": "^3.1.15"
+ }
+ },
+ "node_modules/@react-navigation/stack": {
+ "version": "5.14.7",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.7.tgz",
+ "integrity": "sha512-Ew+MYaJGvJUpZ3XYIilSCRruldr3JXNOWYM8bqE21EeJ5d3mfynpTPihck5ol0AN8uFEAeskQzoixGWh5eMYuA==",
+ "dependencies": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ },
+ "peerDependencies": {
+ "@react-native-community/masked-view": ">= 0.1.0",
+ "@react-navigation/native": "^5.0.5",
+ "react": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": ">= 1.0.0",
+ "react-native-safe-area-context": ">= 0.6.0",
+ "react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0"
}
},
"node_modules/@types/hammerjs": {
@@ -8071,6 +8152,17 @@
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"optional": true
},
+ "node_modules/nanoid": {
+ "version": "3.1.25",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
+ "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
"node_modules/nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -9292,6 +9384,15 @@
"react-navigation": "^4.1.1"
}
},
+ "node_modules/react-navigation/node_modules/@react-navigation/native": {
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.8.4.tgz",
+ "integrity": "sha512-gXSVcL7bfFDyVkvyg1FiAqTCIgZub5K1X/TZqURBs2CPqDpfX1OsCtB9D33eTF14SpbfgHW866btqrrxoCACfg==",
+ "dependencies": {
+ "hoist-non-react-statics": "^3.3.2",
+ "react-native-safe-area-view": "^0.14.9"
+ }
+ },
"node_modules/react-refresh": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@@ -13608,6 +13709,15 @@
"integrity": "sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ==",
"requires": {}
},
+ "@react-navigation/bottom-tabs": {
+ "version": "5.11.13",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.13.tgz",
+ "integrity": "sha512-Z8VAt76S7K8zqjwqfGJ7kC/E8LMDs8hEYgQYv5+JOG+zh9bCx1IAHV5RSDExVMcMDSFVFDerEK68wb49w4hFPQ==",
+ "requires": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ }
+ },
"@react-navigation/core": {
"version": "3.7.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-3.7.9.tgz",
@@ -13627,12 +13737,54 @@
}
},
"@react-navigation/native": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.8.4.tgz",
- "integrity": "sha512-gXSVcL7bfFDyVkvyg1FiAqTCIgZub5K1X/TZqURBs2CPqDpfX1OsCtB9D33eTF14SpbfgHW866btqrrxoCACfg==",
+ "version": "5.9.6",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.6.tgz",
+ "integrity": "sha512-m2F2AWBr0qbi4a5MBk2puGNWyVQnfmVHcpuIzQ37juptX6QCCuXjmOxvtdyqRzh2gKGnUlIeNaQKcACYj4zG/w==",
"requires": {
- "hoist-non-react-statics": "^3.3.2",
- "react-native-safe-area-view": "^0.14.9"
+ "@react-navigation/core": "^5.15.5",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15"
+ },
+ "dependencies": {
+ "@react-navigation/core": {
+ "version": "5.15.5",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.15.5.tgz",
+ "integrity": "sha512-xrUQ0xVQTMuuMiILRhhRpBzoI4TaFh4dJ4INCy6uwK9dwHjLwtsx+++ZefV/K4tbMQmGFxq4zSnLtTRtfMZKrA==",
+ "requires": {
+ "@react-navigation/routers": "^5.7.4",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15",
+ "query-string": "^6.13.6",
+ "react-is": "^16.13.0"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
+ "@react-navigation/routers": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.4.tgz",
+ "integrity": "sha512-0N202XAqsU/FlE53Nmh6GHyMtGm7g6TeC93mrFAFJOqGRKznT0/ail+cYlU6tNcPA9AHzZu1Modw1eoDINSliQ==",
+ "requires": {
+ "nanoid": "^3.1.15"
+ }
+ },
+ "@react-navigation/stack": {
+ "version": "5.14.7",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.7.tgz",
+ "integrity": "sha512-Ew+MYaJGvJUpZ3XYIilSCRruldr3JXNOWYM8bqE21EeJ5d3mfynpTPihck5ol0AN8uFEAeskQzoixGWh5eMYuA==",
+ "requires": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
}
},
"@types/hammerjs": {
@@ -17663,6 +17815,11 @@
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"optional": true
},
+ "nanoid": {
+ "version": "3.1.25",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
+ "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q=="
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -18591,6 +18748,17 @@
"requires": {
"@react-navigation/core": "^3.7.9",
"@react-navigation/native": "^3.8.4"
+ },
+ "dependencies": {
+ "@react-navigation/native": {
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.8.4.tgz",
+ "integrity": "sha512-gXSVcL7bfFDyVkvyg1FiAqTCIgZub5K1X/TZqURBs2CPqDpfX1OsCtB9D33eTF14SpbfgHW866btqrrxoCACfg==",
+ "requires": {
+ "hoist-non-react-statics": "^3.3.2",
+ "react-native-safe-area-view": "^0.14.9"
+ }
+ }
}
},
"react-navigation-stack": {
diff --git a/package.json b/package.json
index 5b9eae6..929cb95 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,9 @@
},
"dependencies": {
"@react-native-community/masked-view": "^0.1.10",
+ "@react-navigation/bottom-tabs": "^5.11.13",
+ "@react-navigation/native": "^5.9.6",
+ "@react-navigation/stack": "^5.14.7",
"expo": "~42.0.1",
"expo-app-loading": "^1.1.2",
"expo-status-bar": "~1.0.4",
diff --git a/screens/CharacterProfile.js b/screens/CharacterProfile.js
index 667079b..0c8f946 100644
--- a/screens/CharacterProfile.js
+++ b/screens/CharacterProfile.js
@@ -1,16 +1,14 @@
import React from "react";
import { Image, ScrollView, StyleSheet, Text, View } from "react-native";
import Colors from "../constants/Colors";
-const CharacterProfile = ({ navigation }) => {
- const img = navigation.getParam("img");
- const name = navigation.getParam("name");
- const appearances = navigation.getParam("appearance");
+const CharacterProfile = ({ route }) => {
+ const { character } = route.params;
return (
-
+
-
+
{
fontFamily: "Quicksand-Bold",
}}
>
- {name}
+ {character.name}
@@ -29,7 +27,7 @@ const CharacterProfile = ({ navigation }) => {
Appearances:{" "}
- {appearances.join(" · ")}
+ {character.appearance.join(" · ")}
@@ -37,16 +35,14 @@ const CharacterProfile = ({ navigation }) => {
{/* Detail */}
-
- Nickname: {navigation.getParam("nickname")}
-
+ Nickname: {character.nickname}
{/* Detail */}
- Occupations: {navigation.getParam("occupation").join(" , ")}
+ Occupations: {character.occupation.join(" , ")}
@@ -54,14 +50,14 @@ const CharacterProfile = ({ navigation }) => {
- Actor: {navigation.getParam("portrayed")}
+ Actor: {character.portrayed}
{/* Detail */}
- Status: {navigation.getParam("status")}
+ Status: {character.status}
@@ -69,11 +65,7 @@ const CharacterProfile = ({ navigation }) => {
);
};
-CharacterProfile.navigationOptions = ({ navigation }) => {
- return {
- headerTitle: navigation.getParam("name"),
- };
-};
+
const styles = StyleSheet.create({
container: {
flex: 1,
@@ -87,6 +79,8 @@ const styles = StyleSheet.create({
width: "100%",
height: "100%",
alignItems: "center",
+ // paddingBottom: 100,
+
// justifyContent: "center",
marginTop: 20,
},
diff --git a/screens/Favorites.js b/screens/Favorites.js
new file mode 100644
index 0000000..c3b81f9
--- /dev/null
+++ b/screens/Favorites.js
@@ -0,0 +1,100 @@
+import React, { useContext } from "react";
+import {
+ ScrollView,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from "react-native";
+import Constants from "expo-constants";
+import Colors from "../constants/Colors";
+import { ReducerContext } from "../contexts";
+import BoldText from "../components/BoldText";
+import Character from "../components/Character";
+const Favorites = ({ navigation }) => {
+ const context = useContext(ReducerContext);
+ if (context.state.favorites.length === 0) {
+ const stylesInner = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ backgroundColor: Colors.primary,
+ },
+ boldText: {
+ fontSize: 30,
+ color: "white",
+ textAlign: "center",
+ },
+ button: {
+ marginTop: 15,
+ backgroundColor: Colors.secondary,
+ width: "40%",
+ maxWidth: 200,
+ paddingHorizontal: 10,
+ paddingVertical: 10,
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ borderRadius: 5,
+ },
+ buttonText: {
+ color: "white",
+ },
+ });
+ return (
+
+
+ You have 0 favorites.
+
+ navigation.navigate("Home")}
+ >
+ Add Favorites!
+
+
+ );
+ }
+ return (
+
+
+
+ Your Favorites
+
+
+
+ {context.state.favorites.map((fav) => {
+ return (
+
+ );
+ })}
+
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ backgroundColor: Colors.primary,
+ paddingTop: Constants.statusBarHeight,
+ flex: 1,
+ },
+ favoritesContainer: {},
+ headerContainer: {
+ height: "20%",
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ boldText: {
+ fontSize: 30,
+ color: "white",
+ textAlign: "center",
+ },
+});
+export default Favorites;
diff --git a/screens/Home.js b/screens/Home.js
index 0275c72..15f1686 100644
--- a/screens/Home.js
+++ b/screens/Home.js
@@ -12,9 +12,10 @@ import Header from "../components/Header";
import { baseUrl, limiter } from "../config";
import Character from "../components/Character";
import Problem from "../components/Problem";
+import AppLoading from "expo-app-loading";
const Home = ({ navigation }) => {
- const [limit, setLimit] = useState(1111);
+ const [limit, setLimit] = useState(25);
const [filteredCharacters, setFilteredCharacters] = useState([]);
const [characters, setCharacters] = useState([]);
const [isLoading, setIsLoading] = useState(true);
@@ -53,21 +54,12 @@ const Home = ({ navigation }) => {
}, [characters]);
if (isLoading) {
- return (
-
-
-
- );
+ return ;
}
if (error) {
return (
-
+
{error}
@@ -97,6 +89,8 @@ const styles = StyleSheet.create({
backgroundColor: Colors.primary,
width: "100%",
alignItems: "center",
+ height: "100%",
+ // paddingBottom: 80,
},
touchable: {
marginVertical: 10,