login register
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { Tabs } from "expo-router";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { Button, Alert } from "react-native";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { useRouter } from "expo-router";
|
||||
|
||||
export default function TabsLayout() {
|
||||
const router = useRouter();
|
||||
|
||||
const handleLogout = async () => {
|
||||
Alert.alert("Đăng xuất", "Bạn có chắc muốn đăng xuất?", [
|
||||
{
|
||||
text: "Hủy",
|
||||
style: "cancel",
|
||||
},
|
||||
{
|
||||
text: "Đăng xuất",
|
||||
style: "destructive",
|
||||
onPress: async () => {
|
||||
await AsyncStorage.removeItem("authToken");
|
||||
router.replace("/"); // quay về màn hình đăng nhập
|
||||
},
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tabs screenOptions={{ headerShown: true, tabBarActiveTintColor: "#007AFF" }}>
|
||||
<Tabs.Screen
|
||||
name="home"
|
||||
options={{
|
||||
title: "Trang chủ",
|
||||
tabBarIcon: ({ color, size }) => <Ionicons name="home" color={color} size={size} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="products"
|
||||
options={{
|
||||
title: "Sản phẩm",
|
||||
tabBarIcon: ({ color, size }) => <Ionicons name="pricetags" color={color} size={size} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="account"
|
||||
options={{
|
||||
title: "Tài khoản",
|
||||
tabBarIcon: ({ color, size }) => <Ionicons name="person" color={color} size={size} />,
|
||||
headerRight: () => <Button title="Logout" onPress={handleLogout} color="#FF3B30" />,
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { View, Text } from "react-native";
|
||||
|
||||
export default function HomeScreen() {
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
||||
<Text>Chào mừng đến Tài khoản!</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
9
app/(tabs)/home.tsx
Normal file
9
app/(tabs)/home.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { View, Text } from "react-native";
|
||||
|
||||
export default function HomeScreen() {
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
||||
<Text>Chào mừng đến Trang chủ!</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { View, Text } from "react-native";
|
||||
|
||||
export default function HomeScreen() {
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
|
||||
<Text>Chào mừng đến Sản phẩm!</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Stack, router } from "expo-router";
|
||||
import { useEffect, useState } from "react";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
|
||||
export default function RootLayout() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkAuth = async () => {
|
||||
const token = await AsyncStorage.getItem("authToken");
|
||||
setIsLoggedIn(!!token);
|
||||
setIsLoading(false);
|
||||
};
|
||||
checkAuth();
|
||||
}, []);
|
||||
|
||||
if (isLoading) return null;
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
{!isLoggedIn && <Stack.Screen name="index" options={{ title: "Đăng ký / Đăng nhập" }} />}
|
||||
{isLoggedIn && <Stack.Screen name="(tabs)" options={{ headerShown: false }} />}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
72
app/index.tsx
Normal file
72
app/index.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import { useState } from "react";
|
||||
import { View, TextInput, Button, Text, Alert, ScrollView } from "react-native";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { useRouter } from "expo-router";
|
||||
import { login, register } from "@/services/auth";
|
||||
|
||||
export default function AuthScreen() {
|
||||
const router = useRouter();
|
||||
const [mode, setMode] = useState<"login" | "register">("register");
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!email.trim() || !password.trim()) {
|
||||
Alert.alert("Lỗi", "Vui lòng nhập email và mật khẩu");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let res;
|
||||
if (mode === "register") {
|
||||
res = await register(email, password);
|
||||
} else {
|
||||
res = await login(email, password);
|
||||
}
|
||||
|
||||
await AsyncStorage.setItem("authToken", res.token);
|
||||
router.replace("/(tabs)/home");
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
Alert.alert("Lỗi", "Sai thông tin đăng nhập hoặc server lỗi");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: "center", padding: 20 }}>
|
||||
<Text style={{ fontSize: 24, fontWeight: "bold", marginBottom: 20 }}>
|
||||
{mode === "register" ? "Đăng ký tài khoản" : "Đăng nhập"}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
placeholder="Email"
|
||||
style={styles.input}
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="Mật khẩu"
|
||||
secureTextEntry
|
||||
style={styles.input}
|
||||
value={password}
|
||||
onChangeText={setPassword}
|
||||
/>
|
||||
|
||||
<Button title={mode === "register" ? "Đăng ký" : "Đăng nhập"} onPress={handleSubmit} />
|
||||
|
||||
<Text
|
||||
style={{ color: "blue", marginTop: 20, textAlign: "center" }}
|
||||
onPress={() => setMode(mode === "register" ? "login" : "register")}
|
||||
>
|
||||
{mode === "register" ? "Đã có tài khoản? Đăng nhập" : "Chưa có tài khoản? Đăng ký"}
|
||||
</Text>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = {
|
||||
input: { borderWidth: 1, marginBottom: 10, padding: 10, borderRadius: 5 },
|
||||
};
|
||||
Reference in New Issue
Block a user