Loading mobile/app/(tabs)/_layout.tsx +7 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,14 @@ export default function Layout() { screenOptions={{ tabBarActiveTintColor: LIGTHT_THEME.color.primary, tabBarInactiveTintColor: LIGTHT_THEME.color.secondary, headerStyle: { backgroundColor: LIGTHT_THEME.color.primary, }, headerTitleStyle: { color: LIGTHT_THEME.color.white, }, headerTitleAlign: "center", }} > <Tabs.Screen Loading mobile/app/_layout.tsx +21 −9 Original line number Diff line number Diff line Loading @@ -3,13 +3,18 @@ import { DataContextProvider } from "../src/contexts/data_context"; import { LIGTHT_THEME } from "../src/constants/theme"; import { AuthContextProvider, useAuth } from "../src/contexts/auth_context"; import { ActivityIndicator } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; export default function Root() { return <DataContextProvider> return ( <GestureHandlerRootView style={{ flex: 1 }}> <DataContextProvider> <AuthContextProvider> <MainLayout /> </AuthContextProvider> </DataContextProvider>; </DataContextProvider> </GestureHandlerRootView> ); } const MainLayout = () => { Loading @@ -20,12 +25,12 @@ const MainLayout = () => { } return ( <Stack initialRouteName="(tabs)" screenOptions={{}}> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack initialRouteName="(tabs)" > <Stack.Screen name="(tabs)" options={{ headerShown: false, statusBarColor: LIGTHT_THEME.color.primary }} /> <Stack.Screen name="(modal)/[id]" name="state" options={{ title: "Select town", headerShown: false, statusBarColor: LIGTHT_THEME.color.primary, }} /> Loading @@ -44,6 +49,13 @@ const MainLayout = () => { } } /> <Stack.Screen name="profile" options={{ title: "Profile", headerShown: false, }} /> </Stack> ); }; mobile/app/profile/_layout.tsx 0 → 100644 +12 −0 Original line number Diff line number Diff line import { Stack } from "expo-router"; export default function Layout() { return ( <Stack> <Stack.Screen name="edit" options={{ title: "Edit Profile", headerShown: true, }}/> </Stack> ); } No newline at end of file mobile/app/profile/edit.tsx 0 → 100644 +7 −0 Original line number Diff line number Diff line import { EditProfilePage } from "../../src/screens/edit_profile/edit_profile_page"; export default function EditProfileScreen() { return ( <EditProfilePage /> ); } No newline at end of file mobile/app/scan.tsx 0 → 100644 +113 −0 Original line number Diff line number Diff line import { View, Text, Button, StyleSheet, Animated } from "react-native"; import { useQRScanner } from "../src/hooks/useQRScanner"; import { CameraView } from "expo-camera/next"; import { BarCodeScanningResult } from "expo-camera"; import { useEffect, useRef } from "react"; export default function ScanScreen() { const { hasPermission, getPermission, scanning, onQRScanned, qrData } = useQRScanner(); const qrAnimation = useRef(new Animated.Value(0)).current; const startAnimation = () => { Animated.loop( Animated.sequence([ Animated.timing(qrAnimation, { toValue: 1, duration: 1000, useNativeDriver: true, }), Animated.timing(qrAnimation, { toValue: 0, duration: 1000, useNativeDriver: true, }), ]) ).start(); }; useEffect(() => { return () => { qrAnimation.stopAnimation(); }; }, []); if (!hasPermission) { return ( <View> <Text>No permission</Text> <Button title="Request permission" onPress={getPermission} /> </View> ); } if (!scanning) { return ( <View> <Text>{qrData}</Text> </View> ); } startAnimation(); return ( <View style={styles.container}> <View style={{borderRadius: 10, overflow: 'hidden'}}> <CameraView style={styles.camera} barcodeScannerSettings={{ barcodeTypes: ["qr"], }} onBarcodeScanned={onQRScanned} zoom={0.5} > <View style={styles.square}> <Animated.View style={{ width: "100%", height: 2, borderColor: "white", borderWidth: 1, borderRadius: 10, transform: [ { translateY: qrAnimation.interpolate({ inputRange: [0, 1], outputRange: [-10, 200], }), }, ], }} /> </View> </CameraView> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, camera: { width: 250, aspectRatio: 1, justifyContent: "center", alignItems: "center", borderRadius: 10, }, square: { width: 200, aspectRatio: 1, borderWidth: 2, borderColor: "white", borderRadius: 10, overflow: "hidden", backgroundColor: "rgba(0,0,0,0.2)", }, }); Loading
mobile/app/(tabs)/_layout.tsx +7 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,14 @@ export default function Layout() { screenOptions={{ tabBarActiveTintColor: LIGTHT_THEME.color.primary, tabBarInactiveTintColor: LIGTHT_THEME.color.secondary, headerStyle: { backgroundColor: LIGTHT_THEME.color.primary, }, headerTitleStyle: { color: LIGTHT_THEME.color.white, }, headerTitleAlign: "center", }} > <Tabs.Screen Loading
mobile/app/_layout.tsx +21 −9 Original line number Diff line number Diff line Loading @@ -3,13 +3,18 @@ import { DataContextProvider } from "../src/contexts/data_context"; import { LIGTHT_THEME } from "../src/constants/theme"; import { AuthContextProvider, useAuth } from "../src/contexts/auth_context"; import { ActivityIndicator } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; export default function Root() { return <DataContextProvider> return ( <GestureHandlerRootView style={{ flex: 1 }}> <DataContextProvider> <AuthContextProvider> <MainLayout /> </AuthContextProvider> </DataContextProvider>; </DataContextProvider> </GestureHandlerRootView> ); } const MainLayout = () => { Loading @@ -20,12 +25,12 @@ const MainLayout = () => { } return ( <Stack initialRouteName="(tabs)" screenOptions={{}}> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack initialRouteName="(tabs)" > <Stack.Screen name="(tabs)" options={{ headerShown: false, statusBarColor: LIGTHT_THEME.color.primary }} /> <Stack.Screen name="(modal)/[id]" name="state" options={{ title: "Select town", headerShown: false, statusBarColor: LIGTHT_THEME.color.primary, }} /> Loading @@ -44,6 +49,13 @@ const MainLayout = () => { } } /> <Stack.Screen name="profile" options={{ title: "Profile", headerShown: false, }} /> </Stack> ); };
mobile/app/profile/_layout.tsx 0 → 100644 +12 −0 Original line number Diff line number Diff line import { Stack } from "expo-router"; export default function Layout() { return ( <Stack> <Stack.Screen name="edit" options={{ title: "Edit Profile", headerShown: true, }}/> </Stack> ); } No newline at end of file
mobile/app/profile/edit.tsx 0 → 100644 +7 −0 Original line number Diff line number Diff line import { EditProfilePage } from "../../src/screens/edit_profile/edit_profile_page"; export default function EditProfileScreen() { return ( <EditProfilePage /> ); } No newline at end of file
mobile/app/scan.tsx 0 → 100644 +113 −0 Original line number Diff line number Diff line import { View, Text, Button, StyleSheet, Animated } from "react-native"; import { useQRScanner } from "../src/hooks/useQRScanner"; import { CameraView } from "expo-camera/next"; import { BarCodeScanningResult } from "expo-camera"; import { useEffect, useRef } from "react"; export default function ScanScreen() { const { hasPermission, getPermission, scanning, onQRScanned, qrData } = useQRScanner(); const qrAnimation = useRef(new Animated.Value(0)).current; const startAnimation = () => { Animated.loop( Animated.sequence([ Animated.timing(qrAnimation, { toValue: 1, duration: 1000, useNativeDriver: true, }), Animated.timing(qrAnimation, { toValue: 0, duration: 1000, useNativeDriver: true, }), ]) ).start(); }; useEffect(() => { return () => { qrAnimation.stopAnimation(); }; }, []); if (!hasPermission) { return ( <View> <Text>No permission</Text> <Button title="Request permission" onPress={getPermission} /> </View> ); } if (!scanning) { return ( <View> <Text>{qrData}</Text> </View> ); } startAnimation(); return ( <View style={styles.container}> <View style={{borderRadius: 10, overflow: 'hidden'}}> <CameraView style={styles.camera} barcodeScannerSettings={{ barcodeTypes: ["qr"], }} onBarcodeScanned={onQRScanned} zoom={0.5} > <View style={styles.square}> <Animated.View style={{ width: "100%", height: 2, borderColor: "white", borderWidth: 1, borderRadius: 10, transform: [ { translateY: qrAnimation.interpolate({ inputRange: [0, 1], outputRange: [-10, 200], }), }, ], }} /> </View> </CameraView> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, camera: { width: 250, aspectRatio: 1, justifyContent: "center", alignItems: "center", borderRadius: 10, }, square: { width: 200, aspectRatio: 1, borderWidth: 2, borderColor: "white", borderRadius: 10, overflow: "hidden", backgroundColor: "rgba(0,0,0,0.2)", }, });