Skip to content

Instantly share code, notes, and snippets.

@yukster
Last active March 14, 2021 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yukster/d79051380f540f523d71573291b87c13 to your computer and use it in GitHub Desktop.
Save yukster/d79051380f540f523d71573291b87c13 to your computer and use it in GitHub Desktop.
// App.js:
export default function App(props) {
const [isLoadingComplete, setLoadingComplete] = useState(false);
const [state, dispatch] = React.useReducer(
(prevState, action) => {
switch (action.type) {
case "RESTORE_TOKEN":
return {
...prevState,
token: action.token,
isLoading: false,
isLoggedIn: true,
};
case "SIGN_IN":
return {
...prevState,
isSignout: false,
token: action.token,
isLoggedIn: true,
};
case "SIGN_OUT":
clearToken();
return {
...prevState,
isSignout: true,
token: null,
isLoggedIn: false,
};
}
},
{
isLoading: true,
isSignout: false,
token: null,
isLoggedIn: false,
}
);
React.useEffect(() => {
const getAuthToken = async () => {
let token;
try {
token = await AsyncStorage.getItem("auth-token");
} catch (e) {
console.error("Error retrieving auth token! %o", e);
}
dispatch({ type: "RESTORE_TOKEN", token: token });
};
getAuthToken();
}, []);
const contextVal = {
token: state.token,
setAuth: (token) => {
dispatch({ type: "SIGN_IN", token: token });
},
signOut: () => dispatch({ type: "SIGN_OUT" }),
};
const Stack = createStackNavigator();
if (!isLoadingComplete && !props.skipLoadingScreen) {
return (
<AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>
);
} else {
return (
<ApolloProvider client={client}>
<UserContext.Provider value={contextVal}>
<NavigationContainer>
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="default" />}
<Stack.Navigator>
{state.isLoggedIn ? (
<Stack.Screen name="Main" component={MainTabNavigator} options={{ headerShown: false }} />
) : (
<Stack.Screen name="Login" component={LoginScreen} />
)}
</Stack.Navigator>
</View>
</NavigationContainer>
</UserContext.Provider>
</ApolloProvider>
);
}
}
const clearToken = async () => {
try {
await AsyncStorage.removeItem("auth-token");
} catch (e) {
console.error("Error removing auth token! %o", e);
}
};
async function loadResourcesAsync() {
await Promise.all([
Asset.loadAsync([
require("./assets/images/robot-dev.png"),
require("./assets/images/robot-prod.png"),
]),
Font.loadAsync({
// This is the font that we are using for our tab bar
...Ionicons.font,
// We include SpaceMono because we use it in HomeScreen.js. Feel free to
// remove this if you are not using it in your app
// TODO: don't think I need this
"space-mono": require("./assets/fonts/SpaceMono-Regular.ttf"),
}),
]);
}
function handleLoadingError(error) {
// In this case, you might want to report the error to your error reporting
// service, for example Sentry
console.warn(error);
}
function handleFinishLoading(setLoadingComplete) {
setLoadingComplete(true);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
});
// LoginScreen.js:
const storeAuthToken = async (token) => {
try {
await AsyncStorage.setItem("auth-token", token);
} catch (e) {
console.error("Error storing auth token! %o", e);
}
};
const LoginScreen = (props) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [signin, { data, error, loading }] = useMutation(SIGNIN_MUTATION);
const { setAuth } = useContext(UserContext);
if (loading) {
return (
<View style={styles.main}>
<Text style={styles.text}>Logging you in!</Text>
<ActivityIndicator size="large" />
</View>
);
}
if (data) {
storeAuthToken(data.signin.token);
setAuth(data.signin.token);
}
return (
<View style={styles.main}>
<Text style={styles.welcome}>Welcome to Bravauto!</Text>
<Text style={styles.error}>{error ? errorMessage(error) : ""}</Text>
<Text>Please login to continue:</Text>
<TextInput
style={styles.input}
onChangeText={(text) => setEmail(text)}
placeholder="email"
/>
<TextInput
style={styles.input}
onChangeText={(text) => setPassword(text)}
placeholder="password"
secureTextEntry={true}
/>
<Button
title="Login!"
onPress={() =>
signin({ variables: { email: email, password: password } })
}
/>
<Button
title="No Account? Register Here"
onPress={() => props.navigation.navigate("Registration")}
/>
</View>
);
};
//MainTabNavigator.js
const Stack = createStackNavigator();
const HomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Main" component={MainScreen} />
</Stack.Navigator>
);
};
const LinksStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Links" component={LinksScreen} />
</Stack.Navigator>
);
};
const SettingsStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
);
};
const Tab = createBottomTabNavigator();
const TabNav = () => {
return (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeStack}
screenOptions={() => ({
tabBarIcon: ({ focused }) => {
<TabBarIcon
focused={focused}
name={
Platform.OS === "ios"
? `ios-information-circle${focused ? "" : "-outline"}`
: "md-information-circle"
}
/>;
},
})}
/>
<Tab.Screen
name="Links"
component={LinksStack}
screenOptions={() => ({
tabBarIcon: ({ focused }) => {
<TabBarIcon
focused={focused}
name={Platform.OS === "ios" ? "ios-link" : "md-link"}
/>;
},
})}
/>
<Tab.Screen
name="Settings"
component={SettingsStack}
screenOptions={() => ({
tabBarIcon: ({ focused }) => {
<TabBarIcon
focused={focused}
name={Platform.OS === "ios" ? "ios-options" : "md-options"}
/>;
},
})}
/>
</Tab.Navigator>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment