import { ThemedText } from "@/components/themed-text"; import { ThemedView } from "@/components/themed-view"; import { showToastError } from "@/config"; import { TOKEN } from "@/constants"; import { login } from "@/controller/AuthController"; import { getStorageItem, removeStorageItem, setStorageItem, } from "@/utils/storage"; import { parseJwtToken } from "@/utils/token"; import { useRouter } from "expo-router"; import React, { useCallback, useEffect, useState } from "react"; import { ActivityIndicator, KeyboardAvoidingView, Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from "react-native"; export default function LoginScreen() { const router = useRouter(); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); const checkLogin = useCallback(async () => { const token = await getStorageItem(TOKEN); if (!token) { return; } const parsed = parseJwtToken(token); console.log("Parse Token: ", parsed); const { exp } = parsed; const now = Math.floor(Date.now() / 1000); const oneHour = 60 * 60; if (exp - now < oneHour) { await removeStorageItem(TOKEN); } else { router.replace("/(tabs)"); } }, [router]); useEffect(() => { checkLogin(); }, [checkLogin]); const handleLogin = async () => { // Validate input if (!username.trim() || !password.trim()) { showToastError("Lỗi", "Vui lòng nhập tài khoản và mật khẩu"); return; } setLoading(true); try { const body: Model.LoginRequestBody = { username: username, password: password, }; const response = await login(body); // Nếu thành công, lưu token và chuyển sang (tabs) console.log("Login thành công với data:", response.data); if (response?.data.token) { // Lưu token vào storage nếu cần (thêm logic này sau) await setStorageItem(TOKEN, response.data.token); console.log("Token:", response.data.token); router.replace("/(tabs)"); } } catch (error) { showToastError( "Lỗi", error instanceof Error ? error.message : "Đăng nhập thất bại" ); } finally { setLoading(false); } }; return ( {/* Header */} SGW App Đăng nhập để tiếp tục {/* Form */} {/* Username Input */} Tài khoản {/* Password Input */} Mật khẩu {/* Login Button */} {loading ? ( ) : ( Đăng nhập )} {/* Footer text */} Chưa có tài khoản?{" "} Đăng ký ngay ); } const styles = StyleSheet.create({ scrollContainer: { flexGrow: 1, justifyContent: "center", }, container: { flex: 1, paddingHorizontal: 20, justifyContent: "center", }, headerContainer: { marginBottom: 40, alignItems: "center", }, title: { fontSize: 32, fontWeight: "bold", marginBottom: 8, }, subtitle: { fontSize: 16, opacity: 0.7, }, formContainer: { gap: 16, }, inputGroup: { gap: 8, }, label: { fontSize: 14, fontWeight: "600", }, input: { borderWidth: 1, borderColor: "#ddd", borderRadius: 8, paddingHorizontal: 12, paddingVertical: 12, fontSize: 16, backgroundColor: "#f5f5f5", color: "#000", }, loginButton: { backgroundColor: "#007AFF", paddingVertical: 14, borderRadius: 8, alignItems: "center", marginTop: 16, }, loginButtonDisabled: { opacity: 0.6, }, loginButtonText: { color: "#fff", fontSize: 16, fontWeight: "600", }, footerContainer: { marginTop: 16, alignItems: "center", }, footerText: { fontSize: 14, }, linkText: { color: "#007AFF", fontWeight: "600", }, });