- lib/pinService.ts: PIN storage/verification via expo-secure-store - lib/syncService.ts: sync abstraction with full merge logic (mDNS/TCP stubbed) - app/lock.tsx: full-screen PIN lock with biometric support - components/ui/PinPad.tsx: reusable 6-digit PIN pad component - components/sync/QRScanner.tsx: QR code scanner via expo-camera - app/(tabs)/sync.tsx: Sync tab with QR display, partner input, history - app/sync-progress.tsx: animated sync progress screen with summary - app/(tabs)/settings.tsx: full settings with PIN setup, security, data sections - app/(tabs)/_layout.tsx: added Sync tab (RefreshCw icon) - app/_layout.tsx: AppState listener locks app after 60s background - package.json: added expo-secure-store, react-native-qrcode-svg
69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
// app/(tabs)/_layout.tsx
|
|
import { Tabs, router } from 'expo-router';
|
|
import { useEffect } from 'react';
|
|
import { Home, Users, Map, Settings, MapPin, RefreshCw } from 'lucide-react-native';
|
|
import { useUserStore } from '@/store/useUserStore';
|
|
|
|
export default function TabLayout() {
|
|
const user = useUserStore((s) => s.user);
|
|
|
|
useEffect(() => {
|
|
if (!user) {
|
|
router.replace('/onboarding');
|
|
}
|
|
}, [user]);
|
|
|
|
return (
|
|
<Tabs
|
|
screenOptions={{
|
|
tabBarActiveTintColor: '#1A6B72',
|
|
tabBarInactiveTintColor: '#9CA3AF',
|
|
headerShown: false,
|
|
}}
|
|
>
|
|
<Tabs.Screen
|
|
name="index"
|
|
options={{
|
|
title: 'Home',
|
|
tabBarIcon: ({ color, size }) => <Home size={size} color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="contacts"
|
|
options={{
|
|
title: 'Contacts',
|
|
tabBarIcon: ({ color, size }) => <Users size={size} color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="territories"
|
|
options={{
|
|
title: 'Territories',
|
|
tabBarIcon: ({ color, size }) => <MapPin size={size} color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="map"
|
|
options={{
|
|
title: 'Map',
|
|
tabBarIcon: ({ color, size }) => <Map size={size} color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="sync"
|
|
options={{
|
|
title: 'Sync',
|
|
tabBarIcon: ({ color, size }) => <RefreshCw size={size} color={color} />,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="settings"
|
|
options={{
|
|
title: 'Settings',
|
|
tabBarIcon: ({ color, size }) => <Settings size={size} color={color} />,
|
|
}}
|
|
/>
|
|
</Tabs>
|
|
);
|
|
}
|