import { Stack } from "expo-router/stack"; import { ConvexProvider, ConvexReactClient } from "convex/react"; import { useState, createContext, useContext, useEffect, useCallback, Component, type ReactNode, type ErrorInfo } from "react"; import { View, Text, Pressable, ScrollView } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { ThemeProvider, useTheme } from "../components/theme"; const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!); type AuthState = { token: string | null; userId: string | null; isAuthenticated: boolean; login: (token: string, userId: string) => Promise; logout: () => Promise; }; const AuthContext = createContext({ token: null, userId: null, isAuthenticated: false, login: async () => {}, logout: async () => {}, }); export function useAuth() { return useContext(AuthContext); } const TOKEN_KEY = "mojmajstor_auth_token"; const USER_ID_KEY = "mojmajstor_auth_userId"; class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean; error: Error | null }> { state: { hasError: boolean; error: Error | null } = { hasError: false, error: null }; static getDerivedStateFromError(error: Error) { return { hasError: true, error }; } reset = () => { this.setState({ hasError: false, error: null }); }; render() { if (this.state.hasError) { return ; } return this.props.children; } } function ErrorFallback({ error, onReset }: { error: Error; onReset: () => void }) { const theme = useTheme(); return ( ⚠️ Настана грешка Приложението наиде на неочекувана грешка. {__DEV__ && error?.message ? ( {error.message} ) : null} Обиди се повторно ); } export default function RootLayout() { const [token, setToken] = useState(null); const [userId, setUserId] = useState(null); const [loaded, setLoaded] = useState(false); useEffect(() => { Promise.all([ AsyncStorage.getItem(TOKEN_KEY), AsyncStorage.getItem(USER_ID_KEY), ]).then(([t, u]) => { if (t) setToken(t); if (u) setUserId(u); setLoaded(true); }); }, []); const login = useCallback(async (newToken: string, newUserId: string) => { await AsyncStorage.setItem(TOKEN_KEY, newToken); await AsyncStorage.setItem(USER_ID_KEY, newUserId); setToken(newToken); setUserId(newUserId); }, []); const logout = useCallback(async () => { await AsyncStorage.removeItem(TOKEN_KEY); await AsyncStorage.removeItem(USER_ID_KEY); setToken(null); setUserId(null); }, []); if (!loaded) return null; return ( ); }