React Native Expo app — full mobile client
- Expo SDK 54, expo-router, NativeWind - 7 screens: login, tasks, calendar, goals, chat, settings, tabs - API client (api.hasdo.info), SecureStore auth, AuthContext - Tab navigation: Ukoly, Kalendar, Cile, Chat, Nastaveni - Pull-to-refresh, FAB, group colors, priority dots - Calendar grid with task dots - AI chat with keyboard avoiding - Web export verified (780 modules, 1.5MB bundle) - Bundle ID: info.hasdo.taskteam Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
32
mobile/app/_layout.tsx
Normal file
32
mobile/app/_layout.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Slot, useRouter, useSegments } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { AuthProvider, useAuthContext } from '../lib/AuthContext';
|
||||
|
||||
function AuthGate() {
|
||||
const { token, loading } = useAuthContext();
|
||||
const segments = useSegments();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
const inAuthGroup = segments[0] === 'login';
|
||||
|
||||
if (!token && !inAuthGroup) {
|
||||
router.replace('/login');
|
||||
} else if (token && inAuthGroup) {
|
||||
router.replace('/');
|
||||
}
|
||||
}, [token, loading, segments]);
|
||||
|
||||
return <Slot />;
|
||||
}
|
||||
|
||||
export default function RootLayout() {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<StatusBar style="auto" />
|
||||
<AuthGate />
|
||||
</AuthProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user