diff --git a/app/App.tsx b/app/App.tsx index d0f9db1..cf07ae6 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -2,15 +2,18 @@ import React from 'react'; import { StatusBar } from 'expo-status-bar'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { AuthProvider } from '@/auth/AuthContext'; +import { ThemeProvider } from '@/theme/ThemeContext'; import { RootNavigator } from '@/navigation/RootNavigator'; export default function App() { return ( - - - - + + + + + + ); } diff --git a/app/app.json b/app/app.json index 83b4399..3660e48 100644 --- a/app/app.json +++ b/app/app.json @@ -44,7 +44,8 @@ "extra": { "psEnvironment": "prodv2", "mapStyleUrl": "https://tiles.openfreemap.org/styles/liberty", - "unifiedPushDefaultDistributor": "io.heckel.ntfy" + "unifiedPushDefaultDistributor": "io.heckel.ntfy", + "debugHttp": true } } } diff --git a/app/src/api/client.ts b/app/src/api/client.ts index 9ff8659..2f4891d 100644 --- a/app/src/api/client.ts +++ b/app/src/api/client.ts @@ -17,4 +17,7 @@ export const ps = new ParkSmarterClient({ tokens: secureTokenStore, localeCode: (Localization.getLocales()[0]?.languageCode ?? 'en').toLowerCase(), onUnauthorized: () => authBus.onUnauthorized?.(), + // Redacted request/response logging -> logcat (grep "PS →" / "PS ←"). + // Toggle at runtime with ps.setLogRequests(false), or flip extra.debugHttp. + logRequests: Boolean(Constants.expoConfig?.extra?.debugHttp), }); diff --git a/app/src/navigation/RootNavigator.tsx b/app/src/navigation/RootNavigator.tsx index cc6004f..e44dcfd 100644 --- a/app/src/navigation/RootNavigator.tsx +++ b/app/src/navigation/RootNavigator.tsx @@ -15,12 +15,20 @@ import { FavoritesScreen } from '@/screens/FavoritesScreen'; import { SessionsScreen } from '@/screens/SessionsScreen'; import { MeterDetailScreen } from '@/screens/MeterDetailScreen'; import { AboutScreen } from '@/screens/AboutScreen'; +import { AccountScreen } from '@/screens/AccountScreen'; +import { ProfileScreen } from '@/screens/ProfileScreen'; +import { VehiclesScreen } from '@/screens/VehiclesScreen'; +import { PaymentMethodsScreen } from '@/screens/PaymentMethodsScreen'; +import { useTheme } from '@/theme/ThemeContext'; import type { Zone } from 'parksmarter-client'; export type RootStackParamList = { Tabs: undefined; MeterDetail: { zone: Zone }; About: undefined; + Profile: undefined; + Vehicles: undefined; + PaymentMethods: undefined; }; export type TabParamList = { @@ -28,6 +36,7 @@ export type TabParamList = { Scan: undefined; Favorites: undefined; Sessions: undefined; + Account: undefined; }; const Stack = createNativeStackNavigator(); @@ -47,6 +56,7 @@ const TAB_ICONS: Record = { Scan: 'qr-code', Favorites: 'star', Sessions: 'time', + Account: 'person', }; function Tabs() { @@ -65,23 +75,32 @@ function Tabs() { + ); } export function RootNavigator() { const { status } = useAuth(); + const { navTheme } = useTheme(); if (status === 'loading') { return ( - - + + ); } return ( - + {status === 'signedIn' ? ( @@ -91,6 +110,13 @@ export function RootNavigator() { options={{ title: 'Meter' }} /> + + + ) : ( diff --git a/app/src/screens/AccountScreen.tsx b/app/src/screens/AccountScreen.tsx new file mode 100644 index 0000000..16aa1c6 --- /dev/null +++ b/app/src/screens/AccountScreen.tsx @@ -0,0 +1,102 @@ +import React, { useState } from 'react'; +import { ScrollView, StyleSheet, Switch, Text, TouchableOpacity, View } from 'react-native'; +import Constants from 'expo-constants'; +import { Ionicons } from '@expo/vector-icons'; +import { useNavigation } from '@react-navigation/native'; +import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; +import { ps } from '@/api/client'; +import { useAuth } from '@/auth/AuthContext'; +import { useTheme } from '@/theme/ThemeContext'; +import type { RootStackParamList } from '@/navigation/RootNavigator'; + +type Nav = NativeStackNavigationProp; + +export function AccountScreen() { + const { colors, mode, toggle } = useTheme(); + const { logout } = useAuth(); + const navigation = useNavigation