top-tran/toptran-app/src/contexts/AuthContext.tsx
2026-05-03 01:16:25 -03:00

140 lines
3.2 KiB
TypeScript

import { useRouter } from "expo-router";
import React, { createContext, useContext, useEffect, useState } from "react";
import {
deleteSetting,
getSetting,
initDB,
setSetting,
} from "@/services/db";
type User = {
id: string;
email: string;
name: string;
};
type AuthContextType = {
user: User | null;
token: string | null;
isLoading: boolean;
login: (
email: string,
password: string,
token: string,
user: User,
) => Promise<void>;
signup: (
name: string,
email: string,
password: string,
token: string,
) => Promise<void>;
logout: () => Promise<void>;
isSignedIn: boolean;
};
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [token, setToken] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(true);
const router = useRouter();
useEffect(() => {
bootstrapAsync();
}, []);
const bootstrapAsync = async () => {
try {
await initDB();
const storedToken = await getSetting("authToken");
const storedUser = await getSetting("user");
if (storedToken && storedUser) {
setToken(storedToken);
setUser(JSON.parse(storedUser));
router.replace("/home");
} else {
setToken(null);
setUser(null);
router.replace("/");
}
} catch (e) {
console.error("Failed to restore token", e);
} finally {
setIsLoading(false);
}
};
const authContext: AuthContextType = {
user,
token,
isLoading,
isSignedIn: token !== null,
login: async (
_email: string,
_password: string,
authToken: string,
authUser: User,
) => {
try {
setToken(authToken);
setUser(authUser);
await setSetting("authToken", authToken);
await setSetting("user", JSON.stringify(authUser));
router.replace("/home");
} catch (error) {
console.error("Login failed:", error);
throw error;
}
},
signup: async (
name: string,
email: string,
password: string,
authToken: string,
) => {
try {
const newUser: User = {
id: Date.now().toString(),
email,
name,
};
setToken(authToken);
setUser(newUser);
await setSetting("authToken", authToken);
await setSetting("user", JSON.stringify(newUser));
router.replace("/home");
} catch (error) {
console.error("Signup failed:", error);
throw error;
}
},
logout: async () => {
try {
await deleteSetting("authToken");
await deleteSetting("user");
setToken(null);
setUser(null);
router.replace("/");
} catch (error) {
console.error("Logout failed:", error);
throw error;
}
},
};
return (
<AuthContext.Provider value={authContext}>{children}</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth must be used within an AuthProvider");
}
return context;
}