Skip to content

Instantly share code, notes, and snippets.

@happyharis
Last active December 7, 2022 00:56
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 happyharis/46680e40e73920df6ae31ccdc6df2cd7 to your computer and use it in GitHub Desktop.
Save happyharis/46680e40e73920df6ae31ccdc6df2cd7 to your computer and use it in GitHub Desktop.
PCMOB6 ProfileScreen & AuthScreen
import AsyncStorage from "@react-native-async-storage/async-storage";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import React, { useEffect, useState } from "react";
import { ActivityIndicator, StatusBar, StyleSheet, View } from "react-native";
import AuthScreen from "./screens/AuthScreen";
import ProfileScreen from "./screens/ProfileScreen";
import { AUTH_SCREEN, PROFILE_SCREEN } from "./constants";
const Stack = createStackNavigator();
export default function App() {
const [loading, setLoading] = useState(true);
const [loggedIn, setLoggedIn] = useState(false);
async function setToken() {
const token = await AsyncStorage.getItem("token");
// if there is not token, it will be falsey value
setLoggedIn(token);
setLoading(false);
}
useEffect(() => {
setToken();
}, []);
const LoadingScreen = () => (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
const AppScreen = () => (
<NavigationContainer>
<StatusBar />
<Stack.Navigator
initialRouteName={loggedIn ? PROFILE_SCREEN : AUTH_SCREEN}
screenOptions={{
animationEnabled: false,
headerShown: false,
}}
>
<Stack.Screen component={AuthScreen} name={AUTH_SCREEN} />
<Stack.Screen component={ProfileScreen} name={PROFILE_SCREEN} />
</Stack.Navigator>
</NavigationContainer>
);
return loading ? <LoadingScreen /> : <AppScreen />;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
import {
ActivityIndicator,
Keyboard,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import React, { useState } from "react";
import { useNavigation } from "@react-navigation/native";
import axios from "axios";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { PROFILE_SCREEN, API, API_LOGIN } from "../constants";
export default function AuthScreen() {
const navigation = useNavigation();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [errorText, setErrorText] = useState("");
const [loading, setLoading] = useState(false);
async function login() {
setErrorText("");
setLoading(true);
Keyboard.dismiss();
try {
const response = await axios.post(API + API_LOGIN, {
username,
password,
});
await AsyncStorage.setItem("token", response.data.access_token);
navigation.navigate(PROFILE_SCREEN);
} catch (error) {
console.log(error.response);
setErrorText(error.response.data.description);
}
setLoading(false);
}
return (
<View style={styles.container}>
<Text style={styles.title}>Login to your account</Text>
<TextInput
style={styles.inputView}
placeholder="Email"
value={username}
onChangeText={(username) => setUsername(username)}
/>
<TextInput
style={styles.inputView}
placeholder="Password"
secureTextEntry={true}
value={password}
onChangeText={(pw) => setPassword(pw)}
/>
<TouchableOpacity
style={styles.button}
onPress={async () => {
await login();
}}
>
{loading ? (
<ActivityIndicator style={styles.buttonText} />
) : (
<Text style={styles.buttonText}>Login</Text>
)}
</TouchableOpacity>
<Text style={styles.errorText}>{errorText}</Text>
</View>
);
}
const styles = StyleSheet.create({
errorText: {
marginTop: 20,
fontSize: 15,
color: "red",
},
container: {
flex: 1,
backgroundColor: "#fff",
paddingTop: 100,
padding: 25,
},
title: {
fontWeight: "bold",
fontSize: 40,
marginBottom: 50,
},
inputView: {
backgroundColor: "#F1F0F5",
borderRadius: 5,
marginBottom: 30,
padding: 20,
},
button: {
backgroundColor: "black",
borderRadius: 15,
width: "100%",
},
buttonText: {
textAlign: "center",
fontWeight: "400",
fontSize: 17,
padding: 20,
color: "white",
},
});
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import React, { useEffect, useState } from "react";
import { useNavigation } from "@react-navigation/native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { AUTH_SCREEN, API, API_WHOAMI } from "../constants";
import axios from "axios";
export default function ProfileScreen() {
const navigation = useNavigation();
const [username, setUsername] = useState("loading...");
async function loadUsername() {
const token = await AsyncStorage.getItem("token");
try {
const response = await axios.get(API + API_WHOAMI, {
headers: { Authorization: `JWT ${token}` },
});
setUsername(response.data.username);
} catch (error) {
console.log(error.response.data);
}
}
useEffect(() => {
const removeListener = navigation.addListener("focus", loadUsername);
loadUsername();
return () => {
removeListener();
};
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>profile</Text>
<Text style={{ fontSize: 20, fontWeight: "700", marginBottom: 10 }}>
your user name: {username}
</Text>
<View style={{ flex: 1 }} />
<TouchableOpacity
style={styles.button}
onPress={() => {
navigation.navigate(AUTH_SCREEN);
AsyncStorage.removeItem("token");
setUsername("loading...");
}}
>
<Text style={styles.buttonText}>Logout</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
paddingTop: 100,
padding: 25,
},
title: {
fontWeight: "bold",
fontSize: 40,
marginBottom: 20,
},
outlinedButton: {
borderRadius: 3,
borderWidth: 1,
width: 120,
},
outlinedButtonText: {
textAlign: "center",
fontWeight: "600",
fontSize: 12,
padding: 15,
color: "black",
},
button: {
backgroundColor: "black",
borderRadius: 15,
width: "100%",
},
buttonText: {
textAlign: "center",
fontWeight: "400",
fontSize: 17,
padding: 20,
color: "white",
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment