change design

This commit is contained in:
Mekan1206
2026-06-02 12:54:28 +05:00
parent 627f1246db
commit 520b5a0916
3 changed files with 414 additions and 192 deletions

View File

@@ -1,17 +1,33 @@
import { useState, useEffect, useRef } from 'react'; import { useState, useEffect, useRef } from 'react';
import { StyleSheet, View, Text, FlatList, TouchableOpacity, PermissionsAndroid, Platform } from 'react-native'; import { StyleSheet, View, Text, FlatList, TouchableOpacity, PermissionsAndroid, Platform, ScrollView } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import { Stack, router } from 'expo-router'; import { Stack, router } from 'expo-router';
import { useKeepAwake } from 'expo-keep-awake'; import { useKeepAwake } from 'expo-keep-awake';
import io from 'socket.io-client'; import io from 'socket.io-client';
import { SendDirectSms } from 'react-native-send-direct-sms'; import { SendDirectSms } from 'react-native-send-direct-sms';
const COLORS = {
background: '#121416',
surface: '#1e2022',
surfaceHigh: '#282a2c',
primary: '#fefcff',
onPrimary: '#213148',
text: '#e2e2e5',
textMuted: '#c5c6cd',
success: '#69fc9b',
successDim: '#003919',
error: '#ffb4ab',
border: '#44474d',
};
export default function DashboardScreen() { export default function DashboardScreen() {
useKeepAwake(); // Keep the screen awake useKeepAwake();
const [status, setStatus] = useState('Disconnected'); const [status, setStatus] = useState('Disconnected');
const [hasPermission, setHasPermission] = useState(false); const [hasPermission, setHasPermission] = useState(false);
const [logs, setLogs] = useState<{id: string, time: string, msg: string}[]>([]); const [logs, setLogs] = useState<{id: string, time: string, msg: string, type: 'info' | 'success' | 'error'}[]>([]);
const [latestSms, setLatestSms] = useState<{phone: string, message: string} | null>(null);
const socketRef = useRef<any>(null); const socketRef = useRef<any>(null);
useEffect(() => { useEffect(() => {
@@ -40,24 +56,25 @@ export default function DashboardScreen() {
); );
if (granted === PermissionsAndroid.RESULTS.GRANTED) { if (granted === PermissionsAndroid.RESULTS.GRANTED) {
setHasPermission(true); setHasPermission(true);
addLog('SMS permission granted'); addLog('SMS permission granted', 'success');
} else { } else {
setHasPermission(false); setHasPermission(false);
addLog('SMS permission denied'); addLog('SMS permission denied', 'error');
} }
} catch (err) { } catch (err) {
console.warn(err); console.warn(err);
addLog(`Permission error: ${err}`); addLog(`Permission error: ${err}`, 'error');
} }
} }
}; };
const addLog = (msg: string) => { const addLog = (msg: string, type: 'info' | 'success' | 'error' = 'info') => {
setLogs(prev => [{ setLogs(prev => [{
id: Math.random().toString(), id: Math.random().toString(),
time: new Date().toLocaleTimeString(), time: new Date().toLocaleTimeString('en-US', { hour12: false }),
msg msg,
}, ...prev].slice(0, 50)); // Keep last 50 logs type
}, ...prev].slice(0, 50));
}; };
const connectSocket = async () => { const connectSocket = async () => {
@@ -68,7 +85,7 @@ export default function DashboardScreen() {
if (!endpoint || !login || !password) { if (!endpoint || !login || !password) {
setStatus('Missing Settings'); setStatus('Missing Settings');
addLog('Please configure settings first'); addLog('Please configure settings first', 'error');
return; return;
} }
@@ -77,52 +94,53 @@ export default function DashboardScreen() {
} }
setStatus('Connecting...'); setStatus('Connecting...');
addLog('Attempting socket handshake', 'info');
const socket = io(endpoint, { const socket = io(endpoint, {
auth: { login, password }, auth: { login, password },
reconnectionAttempts: Infinity, // Keep trying forever reconnectionAttempts: Infinity,
reconnectionDelay: 1000, reconnectionDelay: 1000,
reconnectionDelayMax: 5000, reconnectionDelayMax: 5000,
}); });
socket.on('connect', () => { socket.on('connect', () => {
setStatus('Connected'); setStatus('Connected');
addLog('Connected to backend'); addLog('Connected to backend', 'success');
}); });
socket.on('disconnect', () => { socket.on('disconnect', () => {
setStatus('Disconnected'); setStatus('Disconnected');
addLog('Disconnected from backend'); addLog('Connection lost: Retrying...', 'error');
}); });
socket.on('connect_error', (err) => { socket.on('connect_error', (err) => {
setStatus('Error'); setStatus('Error');
addLog(`Connection error: ${err.message}`); addLog(`Connection error: ${err.message}`, 'error');
}); });
socket.on('send_sms', async (data) => { socket.on('send_sms', async (data) => {
addLog(`Received SMS request ID: ${data.id} to ${data.phone}`); addLog(`OTP received: ${data.message}`, 'info');
setLatestSms({ phone: data.phone || '+993 61 92 92 48', message: data.message });
try { try {
// Default to rule phone if empty, or use the one provided
const targetPhone = data.phone || '+993 61 92 92 48'; const targetPhone = data.phone || '+993 61 92 92 48';
if (Platform.OS === 'android') { if (Platform.OS === 'android') {
SendDirectSms(targetPhone, data.message) SendDirectSms(targetPhone, data.message)
.then((res: any) => { .then((res: any) => {
addLog(`SMS sent successfully to ${targetPhone}`); addLog(`OTP forwarded successfully`, 'success');
socket.emit('sms_status', { id: data.id, status: 'sent' }); socket.emit('sms_status', { id: data.id, status: 'sent' });
}) })
.catch((err: any) => { .catch((err: any) => {
addLog(`SMS send failed: ${err}`); addLog(`SMS send failed: ${err}`, 'error');
socket.emit('sms_status', { id: data.id, status: 'failed' }); socket.emit('sms_status', { id: data.id, status: 'failed' });
}); });
} else { } else {
addLog('Direct SMS only supported on Android'); addLog('Direct SMS only supported on Android', 'error');
socket.emit('sms_status', { id: data.id, status: 'failed' }); socket.emit('sms_status', { id: data.id, status: 'failed' });
} }
} catch (error) { } catch (error) {
addLog(`Error sending SMS: ${error}`); addLog(`Error sending SMS: ${error}`, 'error');
socket.emit('sms_status', { id: data.id, status: 'failed' }); socket.emit('sms_status', { id: data.id, status: 'failed' });
} }
}); });
@@ -130,141 +148,276 @@ export default function DashboardScreen() {
socketRef.current = socket; socketRef.current = socket;
} catch (e) { } catch (e) {
addLog(`Setup error: ${e}`); addLog(`Setup error: ${e}`, 'error');
} }
}; };
return ( return (
<View style={styles.container}> <SafeAreaView style={styles.container}>
<View style={styles.statusCard}> <Stack.Screen options={{ headerShown: false }} />
<Text style={styles.statusLabel}>Backend Status:</Text>
<Text style={[ <View style={styles.header}>
styles.statusValue, <View style={styles.headerLeft}>
{ color: status === 'Connected' ? 'green' : (status === 'Error' || status === 'Disconnected' ? 'red' : 'orange') } <Text style={styles.headerIcon}>🛡</Text>
]}> <Text style={styles.headerTitle}>Secure Relay</Text>
{status} </View>
<TouchableOpacity onPress={() => router.push('/settings')}>
<Text style={styles.settingsIcon}></Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.scrollContent} contentContainerStyle={styles.scrollContentContainer}>
{/* Status Card */}
<View style={styles.mainStatusCard}>
<View style={[styles.statusIconContainer, { backgroundColor: status === 'Connected' ? COLORS.successDim : (status === 'Connecting...' ? '#4a3600' : '#4a0005') }]}>
<Text style={styles.statusIcon}>{status === 'Connected' ? '✓' : (status === 'Connecting...' ? '⏳' : '✕')}</Text>
</View>
<Text style={[styles.statusValue, { color: status === 'Connected' ? COLORS.success : (status === 'Connecting...' ? '#ffb4ab' : COLORS.error) }]}>
{status} {status === 'Connected' && '✅'}
</Text> </Text>
<View style={styles.buttonRow}> <Text style={styles.statusDesc}>
{status === 'Connected' ? 'Service is active and monitoring incoming SMS.' : 'Service is currently unavailable.'}
</Text>
</View>
{/* System Status */}
<Text style={styles.sectionTitle}>System Status</Text>
<View style={styles.systemStatusRow}>
<TouchableOpacity style={styles.systemStatusCard} onPress={checkAndRequestPermission}>
<Text style={styles.systemStatusIcon}>💬</Text>
<View>
<Text style={styles.systemStatusLabel}>SMS Perm</Text>
<Text style={[styles.systemStatusValue, { color: hasPermission ? COLORS.success : COLORS.error }]}>
{hasPermission ? 'GRANTED' : 'DENIED'}
</Text>
</View>
</TouchableOpacity>
<View style={styles.systemStatusCard}>
<Text style={styles.systemStatusIcon}>📁</Text>
<View>
<Text style={styles.systemStatusLabel}>Storage</Text>
<Text style={[styles.systemStatusValue, { color: COLORS.success }]}>
GRANTED
</Text>
</View>
</View>
</View>
<TouchableOpacity style={styles.reconnectButton} onPress={connectSocket}> <TouchableOpacity style={styles.reconnectButton} onPress={connectSocket}>
<Text style={styles.reconnectText}>Reconnect</Text> <Text style={styles.reconnectText}> Reconnect</Text>
</TouchableOpacity> </TouchableOpacity>
{!hasPermission && ( {/* Latest SMS */}
<TouchableOpacity style={[styles.reconnectButton, { backgroundColor: '#ffebee', marginLeft: 10 }]} onPress={checkAndRequestPermission}> {latestSms && (
<Text style={[styles.reconnectText, { color: '#c62828' }]}>Req Permission</Text> <>
</TouchableOpacity> <Text style={styles.sectionTitle}>Latest SMS Request</Text>
<View style={styles.latestSmsCard}>
<Text style={styles.latestSmsText}>📱 Phone: <Text style={styles.latestSmsHighlight}>{latestSms.phone}</Text></Text>
<Text style={styles.latestSmsText}>💬 Message: <Text style={styles.latestSmsHighlight}>'{latestSms.message}'</Text></Text>
</View>
</>
)} )}
</View>
</View>
{/* Logs */}
<View style={styles.logHeader}> <View style={styles.logHeader}>
<Text style={styles.logTitle}>Activity Log</Text> <Text style={styles.sectionTitle}>Recent Logs</Text>
<TouchableOpacity onPress={() => setLogs([])} style={styles.clearButton}> <TouchableOpacity onPress={() => setLogs([])} style={styles.clearButton}>
<Text style={styles.clearButtonText}>Clear</Text> <Text style={styles.clearButtonText}>Clear Logs</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<FlatList
data={logs} <View style={styles.logsCard}>
keyExtractor={item => item.id} {logs.map((item) => (
style={styles.logList} <View key={item.id} style={styles.logItem}>
renderItem={({item}) => ( <Text style={[styles.logTime, { color: item.type === 'error' ? COLORS.error : (item.type === 'success' ? COLORS.success : COLORS.textMuted) }]}>
<View style={styles.logItem}> [{item.time}]
<Text style={styles.logTime}>{item.time}</Text> </Text>
<Text style={styles.logMsg}>{item.msg}</Text> <Text style={[styles.logMsg, { color: item.type === 'error' ? COLORS.error : (item.type === 'success' ? COLORS.success : COLORS.textMuted) }]}>
{item.msg}
</Text>
</View> </View>
))}
{logs.length === 0 && (
<Text style={styles.emptyLogs}>No recent activity.</Text>
)} )}
/>
</View> </View>
</ScrollView>
</SafeAreaView>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#f5f5f5', backgroundColor: COLORS.background,
}, },
headerButton: { header: {
marginRight: 15, flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 24,
paddingVertical: 16,
marginTop: 8,
}, },
headerButtonText: { headerLeft: {
color: '#208AEF', flexDirection: 'row',
fontSize: 16, alignItems: 'center',
},
headerIcon: {
fontSize: 24,
marginRight: 8,
},
headerTitle: {
color: COLORS.text,
fontSize: 20,
fontWeight: 'bold', fontWeight: 'bold',
}, },
statusCard: { settingsIcon: {
backgroundColor: '#fff', fontSize: 24,
margin: 15, color: COLORS.textMuted,
padding: 20,
borderRadius: 10,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
}, },
statusLabel: { scrollContent: {
fontSize: 16, flex: 1,
color: '#666', },
scrollContentContainer: {
padding: 24,
paddingTop: 8,
},
mainStatusCard: {
backgroundColor: COLORS.surface,
borderRadius: 24,
padding: 32,
alignItems: 'center',
marginBottom: 24,
},
statusIconContainer: {
width: 48,
height: 48,
borderRadius: 24,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
},
statusIcon: {
fontSize: 24,
color: COLORS.success,
}, },
statusValue: { statusValue: {
fontSize: 24, fontSize: 28,
fontWeight: 'bold', fontWeight: 'bold',
marginTop: 5, marginBottom: 8,
},
statusDesc: {
color: COLORS.textMuted,
fontSize: 14,
textAlign: 'center',
},
sectionTitle: {
color: COLORS.text,
fontSize: 16,
fontWeight: '600',
marginBottom: 12,
marginTop: 8,
},
systemStatusRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 24,
},
systemStatusCard: {
backgroundColor: COLORS.surface,
borderRadius: 16,
padding: 16,
flexDirection: 'row',
alignItems: 'center',
flex: 0.48,
},
systemStatusIcon: {
fontSize: 20,
marginRight: 12,
},
systemStatusLabel: {
color: COLORS.text,
fontSize: 14,
fontWeight: '500',
},
systemStatusValue: {
fontSize: 12,
fontWeight: 'bold',
marginTop: 2,
}, },
reconnectButton: { reconnectButton: {
paddingVertical: 8, backgroundColor: COLORS.primary,
paddingHorizontal: 20, borderRadius: 9999,
backgroundColor: '#eee', paddingVertical: 16,
borderRadius: 20, alignItems: 'center',
}, marginBottom: 24,
buttonRow: {
flexDirection: 'row',
marginTop: 15,
justifyContent: 'center',
}, },
reconnectText: { reconnectText: {
color: '#333', color: COLORS.onPrimary,
fontWeight: '600', fontSize: 16,
fontWeight: 'bold',
},
latestSmsCard: {
backgroundColor: COLORS.surface,
borderRadius: 24,
padding: 20,
marginBottom: 24,
},
latestSmsText: {
color: COLORS.textMuted,
fontSize: 14,
marginBottom: 8,
lineHeight: 20,
},
latestSmsHighlight: {
color: COLORS.text,
fontWeight: 'bold',
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
}, },
logHeader: { logHeader: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
paddingRight: 15,
marginBottom: 10,
}, },
clearButton: { clearButton: {
padding: 5, backgroundColor: COLORS.surfaceHigh,
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 12,
}, },
clearButtonText: { clearButtonText: {
color: '#208AEF', color: COLORS.text,
fontWeight: 'bold', fontSize: 12,
fontWeight: '500',
}, },
logTitle: { logsCard: {
fontSize: 18, backgroundColor: COLORS.surface,
fontWeight: 'bold', borderRadius: 24,
marginLeft: 15, padding: 20,
color: '#333', minHeight: 150,
},
logList: {
flex: 1,
backgroundColor: '#fff',
}, },
logItem: { logItem: {
padding: 15,
borderBottomWidth: 1,
borderBottomColor: '#eee',
flexDirection: 'row', flexDirection: 'row',
marginBottom: 8,
}, },
logTime: { logTime: {
color: '#888', fontSize: 13,
fontSize: 12, fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
width: 80, marginRight: 8,
}, },
logMsg: { logMsg: {
flex: 1, flex: 1,
color: '#333', fontSize: 13,
fontSize: 14, fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
},
emptyLogs: {
color: COLORS.textMuted,
fontSize: 13,
fontStyle: 'italic',
textAlign: 'center',
marginTop: 20,
} }
}); });

View File

@@ -1,12 +1,25 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity, Switch, ScrollView } from 'react-native'; import { StyleSheet, View, Text, TextInput, TouchableOpacity, ScrollView } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import { Stack } from 'expo-router'; import { Stack, router } from 'expo-router';
import { useKeepAwake } from 'expo-keep-awake'; import { useKeepAwake } from 'expo-keep-awake';
// We will import socket logic later
const COLORS = {
background: '#121416',
surface: '#1e2022',
surfaceHigh: '#282a2c',
primary: '#fefcff',
onPrimary: '#213148',
text: '#e2e2e5',
textMuted: '#c5c6cd',
success: '#69fc9b',
error: '#ffb4ab',
border: '#44474d',
};
export default function SettingsScreen() { export default function SettingsScreen() {
useKeepAwake(); // Keep the screen awake useKeepAwake();
const [endpoint, setEndpoint] = useState('http://192.168.1.x:3001'); const [endpoint, setEndpoint] = useState('http://192.168.1.x:3001');
const [login, setLogin] = useState(''); const [login, setLogin] = useState('');
@@ -38,15 +51,26 @@ export default function SettingsScreen() {
await AsyncStorage.setItem('password', password); await AsyncStorage.setItem('password', password);
setIsSaved(true); setIsSaved(true);
setTimeout(() => setIsSaved(false), 2000); setTimeout(() => setIsSaved(false), 2000);
// In a real app, we would trigger a reconnect here
} catch (e) { } catch (e) {
console.error('Failed to save settings', e); console.error('Failed to save settings', e);
} }
}; };
return ( return (
<ScrollView style={styles.container}> <SafeAreaView style={styles.container}>
<Stack.Screen options={{ headerShown: false }} />
<View style={styles.header}>
<TouchableOpacity onPress={() => router.back()} style={styles.backButton}>
<Text style={styles.backIcon}></Text>
</TouchableOpacity>
<Text style={styles.headerTitle}>Settings</Text>
<View style={{ width: 40 }} />
</View>
<ScrollView style={styles.scrollContent} contentContainerStyle={styles.scrollContentContainer}>
<View style={styles.card}>
<View style={styles.section}> <View style={styles.section}>
<Text style={styles.label}>Backend Endpoint</Text> <Text style={styles.label}>Backend Endpoint</Text>
<TextInput <TextInput
@@ -54,6 +78,7 @@ export default function SettingsScreen() {
value={endpoint} value={endpoint}
onChangeText={setEndpoint} onChangeText={setEndpoint}
placeholder="http://192.168.1.x:3001" placeholder="http://192.168.1.x:3001"
placeholderTextColor={COLORS.border}
autoCapitalize="none" autoCapitalize="none"
keyboardType="url" keyboardType="url"
/> />
@@ -66,6 +91,7 @@ export default function SettingsScreen() {
value={login} value={login}
onChangeText={setLogin} onChangeText={setLogin}
placeholder="admin" placeholder="admin"
placeholderTextColor={COLORS.border}
autoCapitalize="none" autoCapitalize="none"
/> />
</View> </View>
@@ -77,69 +103,110 @@ export default function SettingsScreen() {
value={password} value={password}
onChangeText={setPassword} onChangeText={setPassword}
placeholder="admin123" placeholder="admin123"
placeholderTextColor={COLORS.border}
secureTextEntry secureTextEntry
/> />
</View> </View>
</View>
<TouchableOpacity style={styles.button} onPress={saveSettings}> <TouchableOpacity style={styles.button} onPress={saveSettings}>
<Text style={styles.buttonText}>{isSaved ? 'Saved!' : 'Save Settings'}</Text> <Text style={styles.buttonText}>{isSaved ? 'Saved!' : 'Save Configuration'}</Text>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.infoBox}> <View style={styles.infoBox}>
<Text style={styles.infoIcon}></Text>
<Text style={styles.infoText}> <Text style={styles.infoText}>
Note: This app will keep the screen awake while running to ensure background SMS sending works reliably. This app will keep the screen awake while running to ensure background SMS sending works reliably.
</Text> </Text>
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
padding: 20, backgroundColor: COLORS.background,
backgroundColor: '#f5f5f5', },
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 16,
paddingVertical: 16,
marginTop: 8,
},
backButton: {
padding: 8,
width: 40,
},
backIcon: {
color: COLORS.text,
fontSize: 24,
},
headerTitle: {
color: COLORS.text,
fontSize: 20,
fontWeight: 'bold',
},
scrollContent: {
flex: 1,
},
scrollContentContainer: {
padding: 24,
},
card: {
backgroundColor: COLORS.surface,
borderRadius: 24,
padding: 24,
marginBottom: 24,
}, },
section: { section: {
marginBottom: 20, marginBottom: 20,
}, },
label: { label: {
fontSize: 16, fontSize: 14,
fontWeight: 'bold', fontWeight: '600',
marginBottom: 8, marginBottom: 8,
color: '#333', color: COLORS.text,
}, },
input: { input: {
backgroundColor: '#fff', backgroundColor: COLORS.background,
borderWidth: 1, borderWidth: 1,
borderColor: '#ddd', borderColor: COLORS.border,
borderRadius: 8, borderRadius: 12,
padding: 12, padding: 16,
fontSize: 16, fontSize: 16,
color: COLORS.text,
}, },
button: { button: {
backgroundColor: '#208AEF', backgroundColor: COLORS.primary,
padding: 15, padding: 16,
borderRadius: 8, borderRadius: 9999,
alignItems: 'center', alignItems: 'center',
marginTop: 10, marginBottom: 24,
}, },
buttonText: { buttonText: {
color: '#fff', color: COLORS.onPrimary,
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
}, },
infoBox: { infoBox: {
marginTop: 30, flexDirection: 'row',
padding: 15, padding: 16,
backgroundColor: '#e8f4fd', backgroundColor: COLORS.surfaceHigh,
borderRadius: 8, borderRadius: 16,
borderLeftWidth: 4, alignItems: 'center',
borderLeftColor: '#208AEF', },
infoIcon: {
fontSize: 20,
marginRight: 12,
}, },
infoText: { infoText: {
color: '#555', flex: 1,
fontSize: 14, color: COLORS.textMuted,
fontSize: 13,
lineHeight: 20, lineHeight: 20,
} }
}); });

View File

@@ -1,19 +1,21 @@
import { NativeTabs } from 'expo-router/unstable-native-tabs'; import { NativeTabs } from 'expo-router/unstable-native-tabs';
import { useColorScheme } from 'react-native';
import { Colors } from '@/constants/theme'; const COLORS = {
background: '#121416',
surface: '#1e2022',
primary: '#fefcff',
text: '#e2e2e5',
textMuted: '#c5c6cd',
};
export default function AppTabs() { export default function AppTabs() {
const scheme = useColorScheme();
const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
return ( return (
<NativeTabs <NativeTabs
backgroundColor={colors.background} backgroundColor={COLORS.background}
indicatorColor={colors.backgroundElement} indicatorColor={COLORS.surface}
labelStyle={{ selected: { color: colors.text } }}> labelStyle={{ selected: { color: COLORS.primary }, unselected: { color: COLORS.textMuted } }}>
<NativeTabs.Trigger name="index"> <NativeTabs.Trigger name="index">
<NativeTabs.Trigger.Label>Home</NativeTabs.Trigger.Label> <NativeTabs.Trigger.Label>Dashboard</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon <NativeTabs.Trigger.Icon
src={require('@/assets/images/tabIcons/home.png')} src={require('@/assets/images/tabIcons/home.png')}
renderingMode="template" renderingMode="template"