90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { ActivityIndicator, StatusBar, StyleSheet, Text, View } from 'react-native';
|
|
import * as SplashScreen from 'expo-splash-screen';
|
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
import { NavigationContainer } from '@react-navigation/native';
|
|
import { initDatabase } from './src/db/database';
|
|
import { checkRecurringDue, getSetting } from './src/db/repositories';
|
|
import { scheduleDailyReminder } from './src/utils/notifications';
|
|
import { RootNavigator } from './src/navigation';
|
|
import { colors } from './src/theme/colors';
|
|
|
|
SplashScreen.preventAutoHideAsync().catch(() => {});
|
|
|
|
export default function App() {
|
|
const [ready, setReady] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [initialRoute, setInitialRoute] = useState<'Main' | 'Onboarding'>('Onboarding');
|
|
|
|
useEffect(() => {
|
|
initDatabase()
|
|
.then(async () => {
|
|
try {
|
|
// Buat transaksi berulang yang jatuh tempo hari ini
|
|
await checkRecurringDue();
|
|
} catch {
|
|
// jangan sampai mengganggu startup
|
|
}
|
|
const onboarded = await getSetting('onboarded');
|
|
const userName = await getSetting('user_name');
|
|
setInitialRoute(onboarded === '1' && userName ? 'Main' : 'Onboarding');
|
|
// Reschedule pengingat harian kalau aktif
|
|
try {
|
|
if ((await getSetting('reminder_enabled')) === '1') {
|
|
const h = Number(await getSetting('reminder_hour'));
|
|
await scheduleDailyReminder(Number.isFinite(h) ? h : 20, 0);
|
|
}
|
|
} catch {
|
|
// abaikan
|
|
}
|
|
setReady(true);
|
|
SplashScreen.hideAsync().catch(() => {});
|
|
})
|
|
.catch((e) => setError(String(e)));
|
|
}, []);
|
|
|
|
if (error) {
|
|
return (
|
|
<View style={styles.center}>
|
|
<Text style={styles.errorTitle}>Terjadi kesalahan 😢</Text>
|
|
<Text style={styles.errorText}>{error}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
if (!ready) {
|
|
return (
|
|
<View style={styles.center}>
|
|
<ActivityIndicator size="large" color={colors.primary} />
|
|
<Text style={styles.loadingText}>Menyiapkan Kantongku...</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<SafeAreaProvider>
|
|
<NavigationContainer>
|
|
<RootNavigator initialRoute={initialRoute} />
|
|
</NavigationContainer>
|
|
<StatusBar
|
|
barStyle="light-content"
|
|
translucent={false}
|
|
backgroundColor={colors.primary}
|
|
/>
|
|
</SafeAreaProvider>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
center: {
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
backgroundColor: colors.background,
|
|
padding: 24,
|
|
},
|
|
loadingText: { marginTop: 12, color: colors.textMuted, fontSize: 14 },
|
|
errorTitle: { fontSize: 16, fontWeight: '700', color: colors.text, marginBottom: 8 },
|
|
errorText: { color: colors.expense, fontSize: 13, textAlign: 'center' },
|
|
});
|