diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index 54e11d0..f3c9aa7 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -1,35 +1,49 @@
-import { Tabs } from 'expo-router';
-import React from 'react';
-
-import { HapticTab } from '@/components/haptic-tab';
-import { IconSymbol } from '@/components/ui/icon-symbol';
-import { Colors } from '@/constants/theme';
-import { useColorScheme } from '@/hooks/use-color-scheme';
+import { Tabs } from "expo-router";
+import { Ionicons } from "@expo/vector-icons";
export default function TabLayout() {
- const colorScheme = useColorScheme();
-
return (
+ tabBarActiveTintColor: "#2563EB",
+ tabBarInactiveTintColor: "#9CA3AF",
+ tabBarStyle: {
+ height: 65,
+ paddingBottom: 8,
+ paddingTop: 8,
+ },
+ }}
+ >
,
+ title: "Home",
+ tabBarIcon: ({ color, size }) => (
+
+ ),
}}
/>
+
,
+ title: "History",
+ tabBarIcon: ({ color, size }) => (
+
+ ),
+ }}
+ />
+
+ (
+
+ ),
}}
/>
);
-}
+}
\ No newline at end of file
diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx
deleted file mode 100644
index 71518f9..0000000
--- a/app/(tabs)/explore.tsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import { Image } from 'expo-image';
-import { Platform, StyleSheet } from 'react-native';
-
-import { Collapsible } from '@/components/ui/collapsible';
-import { ExternalLink } from '@/components/external-link';
-import ParallaxScrollView from '@/components/parallax-scroll-view';
-import { ThemedText } from '@/components/themed-text';
-import { ThemedView } from '@/components/themed-view';
-import { IconSymbol } from '@/components/ui/icon-symbol';
-import { Fonts } from '@/constants/theme';
-
-export default function TabTwoScreen() {
- return (
-
- }>
-
-
- Explore
-
-
- This app includes example code to help you get started.
-
-
- This app has two screens:{' '}
- app/(tabs)/index.tsx and{' '}
- app/(tabs)/explore.tsx
-
-
- The layout file in app/(tabs)/_layout.tsx{' '}
- sets up the tab navigator.
-
-
- Learn more
-
-
-
-
- You can open this project on Android, iOS, and the web. To open the web version, press{' '}
- w in the terminal running this project.
-
-
-
-
- For static images, you can use the @2x and{' '}
- @3x suffixes to provide files for
- different screen densities
-
-
-
- Learn more
-
-
-
-
- This template has light and dark mode support. The{' '}
- useColorScheme() hook lets you inspect
- what the user's current color scheme is, and so you can adjust UI colors accordingly.
-
-
- Learn more
-
-
-
-
- This template includes an example of an animated component. The{' '}
- components/HelloWave.tsx component uses
- the powerful{' '}
-
- react-native-reanimated
- {' '}
- library to create a waving hand animation.
-
- {Platform.select({
- ios: (
-
- The components/ParallaxScrollView.tsx{' '}
- component provides a parallax effect for the header image.
-
- ),
- })}
-
-
- );
-}
-
-const styles = StyleSheet.create({
- headerImage: {
- color: '#808080',
- bottom: -90,
- left: -35,
- position: 'absolute',
- },
- titleContainer: {
- flexDirection: 'row',
- gap: 8,
- },
-});
diff --git a/app/(tabs)/history.tsx b/app/(tabs)/history.tsx
new file mode 100644
index 0000000..07d2bda
--- /dev/null
+++ b/app/(tabs)/history.tsx
@@ -0,0 +1,166 @@
+import { View, Text, StyleSheet, ScrollView } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+
+export default function HistoryScreen() {
+ const transactions = [
+ {
+ id: 1,
+ title: "Gaji Bulanan",
+ amount: "Rp 5.000.000",
+ type: "income",
+ date: "12 April 2026",
+ icon: "wallet",
+ },
+ {
+ id: 2,
+ title: "Makan Siang",
+ amount: "Rp 50.000",
+ type: "expense",
+ date: "13 April 2026",
+ icon: "restaurant",
+ },
+ {
+ id: 3,
+ title: "Transport",
+ amount: "Rp 20.000",
+ type: "expense",
+ date: "14 April 2026",
+ icon: "car",
+ },
+ {
+ id: 4,
+ title: "Freelance Project",
+ amount: "Rp 1.500.000",
+ type: "income",
+ date: "15 April 2026",
+ icon: "briefcase",
+ },
+ ];
+
+ return (
+
+ Riwayat Transaksi
+
+ Semua pemasukan dan pengeluaran kamu
+
+
+ {transactions.map((item) => (
+
+
+
+
+
+
+
+ {item.title}
+ {item.date}
+
+
+
+
+ {item.type === "income" ? "+" : "-"} {item.amount}
+
+
+ ))}
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: "#F5F7FA",
+ padding: 20,
+ paddingTop: 55,
+ },
+
+ title: {
+ fontSize: 30,
+ fontWeight: "bold",
+ marginBottom: 6,
+ },
+
+ subtitle: {
+ fontSize: 15,
+ color: "#666",
+ marginBottom: 28,
+ },
+
+ card: {
+ backgroundColor: "#FFFFFF",
+ borderRadius: 18,
+ padding: 18,
+ marginBottom: 16,
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ shadowColor: "#000",
+ shadowOpacity: 0.05,
+ shadowRadius: 6,
+ elevation: 3,
+ },
+
+ leftSection: {
+ flexDirection: "row",
+ alignItems: "center",
+ gap: 14,
+ },
+
+ iconContainer: {
+ width: 48,
+ height: 48,
+ borderRadius: 14,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+
+ incomeBg: {
+ backgroundColor: "#DCFCE7",
+ },
+
+ expenseBg: {
+ backgroundColor: "#FEE2E2",
+ },
+
+ transactionTitle: {
+ fontSize: 16,
+ fontWeight: "600",
+ marginBottom: 4,
+ },
+
+ transactionDate: {
+ fontSize: 13,
+ color: "#777",
+ },
+
+ amount: {
+ fontSize: 15,
+ fontWeight: "700",
+ },
+
+ incomeText: {
+ color: "#16A34A",
+ },
+
+ expenseText: {
+ color: "#DC2626",
+ },
+});
\ No newline at end of file
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
index 786b736..d13641e 100644
--- a/app/(tabs)/index.tsx
+++ b/app/(tabs)/index.tsx
@@ -1,98 +1,136 @@
-import { Image } from 'expo-image';
-import { Platform, StyleSheet } from 'react-native';
-
-import { HelloWave } from '@/components/hello-wave';
-import ParallaxScrollView from '@/components/parallax-scroll-view';
-import { ThemedText } from '@/components/themed-text';
-import { ThemedView } from '@/components/themed-view';
-import { Link } from 'expo-router';
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { router } from "expo-router";
+import { Ionicons } from "@expo/vector-icons";
export default function HomeScreen() {
return (
-
- }>
-
- Welcome!
-
-
-
- Step 1: Try it
-
- Edit app/(tabs)/index.tsx to see changes.
- Press{' '}
-
- {Platform.select({
- ios: 'cmd + d',
- android: 'cmd + m',
- web: 'F12',
- })}
- {' '}
- to open developer tools.
-
-
-
-
-
- Step 2: Explore
-
-
-
- alert('Action pressed')} />
- alert('Share pressed')}
- />
-
- alert('Delete pressed')}
- />
-
-
-
+
+ Tabungan H.Hadi
+ Kelola pemasukan & pengeluaranmu untuk nikah
-
- {`Tap the Explore tab to learn more about what's included in this starter app.`}
-
-
-
- Step 3: Get a fresh start
-
- {`When you're ready, run `}
- npm run reset-project to get a fresh{' '}
- app directory. This will move the current{' '}
- app to{' '}
- app-example.
-
-
-
+
+ Total Saldo
+ Rp 500.000.000.000
+
+
+
+
+
+ Income
+ Rp 7.000.000
+
+
+
+
+ Expense
+ Rp 2.000.000
+
+
+
+ router.push("/add-income")}
+ >
+ + Tambah Pemasukan
+
+
+ router.push("/add-expense")}
+ >
+ - Tambah Pengeluaran
+
+
);
}
const styles = StyleSheet.create({
- titleContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- gap: 8,
+ container: {
+ flex: 1,
+ backgroundColor: "#F5F7FA",
+ padding: 24,
+ paddingTop: 60,
},
- stepContainer: {
- gap: 8,
+
+ title: {
+ fontSize: 30,
+ fontWeight: "bold",
marginBottom: 8,
},
- reactLogo: {
- height: 178,
- width: 290,
- bottom: 0,
- left: 0,
- position: 'absolute',
+
+ subtitle: {
+ fontSize: 16,
+ color: "#666",
+ marginBottom: 28,
},
-});
+
+ balanceCard: {
+ backgroundColor: "#2563EB",
+ borderRadius: 20,
+ padding: 24,
+ marginBottom: 24,
+ },
+
+ balanceLabel: {
+ color: "#E0E7FF",
+ fontSize: 16,
+ marginBottom: 8,
+ },
+
+ balanceAmount: {
+ color: "#FFFFFF",
+ fontSize: 32,
+ fontWeight: "bold",
+ },
+
+ summaryContainer: {
+ flexDirection: "row",
+ justifyContent: "space-between",
+ marginBottom: 32,
+ },
+
+ summaryCard: {
+ backgroundColor: "#FFFFFF",
+ width: "48%",
+ padding: 20,
+ borderRadius: 16,
+ alignItems: "center",
+ shadowColor: "#000",
+ shadowOpacity: 0.05,
+ shadowRadius: 6,
+ elevation: 3,
+ },
+
+ summaryTitle: {
+ marginTop: 10,
+ fontSize: 15,
+ color: "#666",
+ },
+
+ summaryAmount: {
+ marginTop: 6,
+ fontSize: 16,
+ fontWeight: "600",
+ },
+
+ buttonIncome: {
+ backgroundColor: "#16A34A",
+ paddingVertical: 16,
+ borderRadius: 14,
+ alignItems: "center",
+ marginBottom: 16,
+ },
+
+ buttonExpense: {
+ backgroundColor: "#DC2626",
+ paddingVertical: 16,
+ borderRadius: 14,
+ alignItems: "center",
+ },
+
+ buttonText: {
+ color: "#FFFFFF",
+ fontSize: 16,
+ fontWeight: "600",
+ },
+});
\ No newline at end of file
diff --git a/app/(tabs)/profile.tsx b/app/(tabs)/profile.tsx
new file mode 100644
index 0000000..2b7f685
--- /dev/null
+++ b/app/(tabs)/profile.tsx
@@ -0,0 +1,137 @@
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { Ionicons } from "@expo/vector-icons";
+
+export default function ProfileScreen() {
+ return (
+
+ {/* Header */}
+ Profile
+ Informasi pengguna aplikasi
+
+ {/* Profile Card */}
+
+
+
+
+
+ Fahrul
+ fahrul@email.com
+
+
+ {/* Info Card */}
+
+
+
+ Aplikasi: Hitung Duit
+
+
+
+
+ Versi: 1.0.0
+
+
+
+
+ Project Tugas Mobile Programming
+
+
+
+ {/* Logout Button */}
+
+
+ Logout
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: "#F5F7FA",
+ padding: 24,
+ paddingTop: 60,
+ },
+
+ title: {
+ fontSize: 30,
+ fontWeight: "bold",
+ marginBottom: 6,
+ },
+
+ subtitle: {
+ fontSize: 15,
+ color: "#666",
+ marginBottom: 28,
+ },
+
+ profileCard: {
+ backgroundColor: "#2563EB",
+ borderRadius: 20,
+ padding: 28,
+ alignItems: "center",
+ marginBottom: 24,
+ },
+
+ avatar: {
+ width: 80,
+ height: 80,
+ borderRadius: 40,
+ backgroundColor: "rgba(255,255,255,0.25)",
+ justifyContent: "center",
+ alignItems: "center",
+ marginBottom: 16,
+ },
+
+ name: {
+ fontSize: 24,
+ fontWeight: "bold",
+ color: "#FFFFFF",
+ marginBottom: 6,
+ },
+
+ email: {
+ fontSize: 14,
+ color: "#DBEAFE",
+ },
+
+ infoCard: {
+ backgroundColor: "#FFFFFF",
+ borderRadius: 18,
+ padding: 20,
+ marginBottom: 28,
+ shadowColor: "#000",
+ shadowOpacity: 0.05,
+ shadowRadius: 6,
+ elevation: 3,
+ },
+
+ infoRow: {
+ flexDirection: "row",
+ alignItems: "center",
+ gap: 12,
+ marginBottom: 18,
+ },
+
+ infoText: {
+ fontSize: 15,
+ color: "#333",
+ flex: 1,
+ },
+
+ logoutButton: {
+ backgroundColor: "#DC2626",
+ paddingVertical: 16,
+ borderRadius: 14,
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center",
+ gap: 10,
+ },
+
+ logoutText: {
+ color: "#FFFFFF",
+ fontSize: 16,
+ fontWeight: "600",
+ },
+});
\ No newline at end of file
diff --git a/app/_layout.tsx b/app/_layout.tsx
index f518c9b..0a6866d 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -1,24 +1,16 @@
-import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
-import { Stack } from 'expo-router';
-import { StatusBar } from 'expo-status-bar';
-import 'react-native-reanimated';
-
-import { useColorScheme } from '@/hooks/use-color-scheme';
-
-export const unstable_settings = {
- anchor: '(tabs)',
-};
+import { Stack } from "expo-router";
+import { StatusBar } from "expo-status-bar";
export default function RootLayout() {
- const colorScheme = useColorScheme();
-
return (
-
-
-
-
+ <>
+
+
+
+
+
-
+ >
);
-}
+}
\ No newline at end of file
diff --git a/app/add-expense.tsx b/app/add-expense.tsx
new file mode 100644
index 0000000..08b373b
--- /dev/null
+++ b/app/add-expense.tsx
@@ -0,0 +1,97 @@
+import { useState } from "react";
+import {
+ View,
+ Text,
+ TextInput,
+ StyleSheet,
+ TouchableOpacity,
+} from "react-native";
+import { router } from "expo-router";
+
+export default function AddExpenseScreen() {
+ const [amount, setAmount] = useState("");
+
+ const formatRupiah = (value: string) => {
+ const numberString = value.replace(/[^,\d]/g, "");
+ const split = numberString.split(",");
+ const sisa = split[0].length % 3;
+
+ let rupiah = split[0].substring(0, sisa);
+ const ribuan = split[0].substring(sisa).match(/\d{3}/gi);
+
+ if (ribuan) {
+ const separator = sisa ? "." : "";
+ rupiah += separator + ribuan.join(".");
+ }
+
+ return rupiah ? `Rp ${rupiah}` : "";
+ };
+
+ const handleAmountChange = (value: string) => {
+ setAmount(formatRupiah(value));
+ };
+
+ return (
+
+ Tambah Pengeluaran
+
+
+
+
+
+ router.back()}
+ >
+ Simpan
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ padding: 24,
+ backgroundColor: "#fff",
+ justifyContent: "center",
+ },
+
+ title: {
+ fontSize: 28,
+ fontWeight: "bold",
+ marginBottom: 24,
+ textAlign: "center",
+ },
+
+ input: {
+ borderWidth: 1,
+ borderColor: "#ddd",
+ padding: 16,
+ borderRadius: 12,
+ marginBottom: 16,
+ fontSize: 16,
+ },
+
+ button: {
+ backgroundColor: "#DC2626",
+ padding: 16,
+ borderRadius: 12,
+ alignItems: "center",
+ },
+
+ buttonText: {
+ color: "#fff",
+ fontWeight: "600",
+ fontSize: 16,
+ },
+});
\ No newline at end of file
diff --git a/app/add-income.tsx b/app/add-income.tsx
new file mode 100644
index 0000000..b4375f1
--- /dev/null
+++ b/app/add-income.tsx
@@ -0,0 +1,97 @@
+import { useState } from "react";
+import {
+ View,
+ Text,
+ TextInput,
+ StyleSheet,
+ TouchableOpacity,
+} from "react-native";
+import { router } from "expo-router";
+
+export default function AddIncomeScreen() {
+ const [amount, setAmount] = useState("");
+
+ const formatRupiah = (value: string) => {
+ const numberString = value.replace(/[^,\d]/g, "");
+ const split = numberString.split(",");
+ const sisa = split[0].length % 3;
+
+ let rupiah = split[0].substring(0, sisa);
+ const ribuan = split[0].substring(sisa).match(/\d{3}/gi);
+
+ if (ribuan) {
+ const separator = sisa ? "." : "";
+ rupiah += separator + ribuan.join(".");
+ }
+
+ return rupiah ? `Rp ${rupiah}` : "";
+ };
+
+ const handleAmountChange = (value: string) => {
+ setAmount(formatRupiah(value));
+ };
+
+ return (
+
+ Tambah Pemasukan
+
+
+
+
+
+ router.back()}
+ >
+ Simpan
+
+
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ padding: 24,
+ backgroundColor: "#fff",
+ justifyContent: "center",
+ },
+
+ title: {
+ fontSize: 28,
+ fontWeight: "bold",
+ marginBottom: 24,
+ textAlign: "center",
+ },
+
+ input: {
+ borderWidth: 1,
+ borderColor: "#ddd",
+ padding: 16,
+ borderRadius: 12,
+ marginBottom: 16,
+ fontSize: 16,
+ },
+
+ button: {
+ backgroundColor: "#16A34A",
+ padding: 16,
+ borderRadius: 12,
+ alignItems: "center",
+ },
+
+ buttonText: {
+ color: "#fff",
+ fontWeight: "600",
+ fontSize: 16,
+ },
+});
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 59c8a09..3963783 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5811,6 +5811,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",