From c601a688e00d71b1475b5a7a4c01b3c801a43f22 Mon Sep 17 00:00:00 2001 From: Bro Date: Sun, 16 Aug 2026 21:07:38 +0700 Subject: [PATCH] Kantongku: fitur pilih tanggal saat catat & edit transaksi (backdate) --- app.json | 3 +- package-lock.json | 24 ++++++++++++++ package.json | 1 + src/screens/AddTransactionScreen.tsx | 44 ++++++++++++++++++++++++++ src/screens/EditTransactionScreen.tsx | 45 +++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) diff --git a/app.json b/app.json index a420c06..c84b762 100644 --- a/app.json +++ b/app.json @@ -35,7 +35,8 @@ "resizeMode": "contain" } ], - "expo-font" + "expo-font", + "@react-native-community/datetimepicker" ], "extra": { "eas": { diff --git a/package-lock.json b/package-lock.json index daf97ce..749fef9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@expo/vector-icons": "^15.0.2", "@react-native-async-storage/async-storage": "2.2.0", + "@react-native-community/datetimepicker": "9.1.0", "@react-navigation/bottom-tabs": "^7.18.16", "@react-navigation/native": "^7.3.16", "@react-navigation/native-stack": "^7.18.8", @@ -1529,6 +1530,29 @@ "react-native": "^0.0.0-0 || >=0.65 <1.0" } }, + "node_modules/@react-native-community/datetimepicker": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-9.1.0.tgz", + "integrity": "sha512-eadbnk+I2vxvW30iTAsm/qlCnMMAadkifIMYNEB2lzhxN/SvlKc7S2V4k5DyrwjdCbqdcMk3t9K6fnUMcAV34w==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "expo": ">=52.0.0", + "react": "*", + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + } + }, "node_modules/@react-native/assets-registry": { "version": "0.86.2", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.86.2.tgz", diff --git a/package.json b/package.json index 6cb0e32..eaa1577 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@expo/vector-icons": "^15.0.2", "@react-native-async-storage/async-storage": "2.2.0", + "@react-native-community/datetimepicker": "9.1.0", "@react-navigation/bottom-tabs": "^7.18.16", "@react-navigation/native": "^7.3.16", "@react-navigation/native-stack": "^7.18.8", diff --git a/src/screens/AddTransactionScreen.tsx b/src/screens/AddTransactionScreen.tsx index 8842734..ed7f3e6 100644 --- a/src/screens/AddTransactionScreen.tsx +++ b/src/screens/AddTransactionScreen.tsx @@ -1,3 +1,5 @@ +import { Ionicons } from '@expo/vector-icons'; +import DateTimePicker from '@react-native-community/datetimepicker'; import { LinearGradient } from 'expo-linear-gradient'; import { useFocusEffect, useRoute } from '@react-navigation/native'; import type { RouteProp } from '@react-navigation/native'; @@ -40,6 +42,8 @@ export function AddTransactionScreen() { const [categories, setCategories] = useState([]); const [selectedCategoryId, setSelectedCategoryId] = useState(null); const [note, setNote] = useState(''); + const [occurredAt, setOccurredAt] = useState(new Date()); + const [showDate, setShowDate] = useState(false); const [percent, setPercent] = useState(10); const [saving, setSaving] = useState(false); @@ -84,6 +88,7 @@ export function AddTransactionScreen() { amount, categoryId: selectedCategoryId, note: note.trim(), + occurredAt, }); if (type === 'income') { Alert.alert( @@ -181,6 +186,32 @@ export function AddTransactionScreen() { )} + {/* Tanggal */} + Tanggal + setShowDate(true)}> + + + {occurredAt.toLocaleDateString('id-ID', { + weekday: 'long', + day: 'numeric', + month: 'long', + year: 'numeric', + })} + + + + {showDate && ( + { + setShowDate(false); + if (d) setOccurredAt(d); + }} + /> + )} + {/* Kategori */} Kategori @@ -297,6 +328,19 @@ const styles = StyleSheet.create({ paddingVertical: 4, }, amountPreview: { fontSize: 13, color: colors.textMuted }, + dateRow: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + backgroundColor: colors.surface, + borderWidth: 1, + borderColor: colors.border, + borderRadius: 14, + paddingHorizontal: 14, + paddingVertical: 12, + marginBottom: 4, + }, + dateRowText: { flex: 1, fontSize: 14, color: colors.text, fontWeight: '600' }, saveHintCard: { flexDirection: 'row', alignItems: 'center', diff --git a/src/screens/EditTransactionScreen.tsx b/src/screens/EditTransactionScreen.tsx index 18e5825..6050b1b 100644 --- a/src/screens/EditTransactionScreen.tsx +++ b/src/screens/EditTransactionScreen.tsx @@ -1,3 +1,5 @@ +import { Ionicons } from '@expo/vector-icons'; +import DateTimePicker from '@react-native-community/datetimepicker'; import { LinearGradient } from 'expo-linear-gradient'; import { useNavigation, useRoute } from '@react-navigation/native'; import type { RouteProp } from '@react-navigation/native'; @@ -36,6 +38,8 @@ export function EditTransactionScreen() { const [categories, setCategories] = useState([]); const [selectedCategoryId, setSelectedCategoryId] = useState(null); const [note, setNote] = useState(''); + const [occurredAt, setOccurredAt] = useState(new Date()); + const [showDate, setShowDate] = useState(false); const [percent, setPercent] = useState(10); const [saving, setSaving] = useState(false); const [loaded, setLoaded] = useState(false); @@ -52,6 +56,7 @@ export function EditTransactionScreen() { setAmountText(String(tx.amount)); setSelectedCategoryId(tx.categoryId); setNote(tx.note); + setOccurredAt(new Date(tx.occurredAt)); const p = await getSettingNumber('auto_save_percent', 10); setPercent(p); const cats = await getCategories(tx.type); @@ -85,6 +90,7 @@ export function EditTransactionScreen() { amount, categoryId: selectedCategoryId, note: note.trim(), + occurredAt, }); Alert.alert('Tersimpan ✅', 'Transaksi berhasil diperbarui.', [ { text: 'Oke', onPress: () => navigation.goBack() }, @@ -175,6 +181,32 @@ export function EditTransactionScreen() { )} + {/* Tanggal */} + Tanggal + setShowDate(true)}> + + + {occurredAt.toLocaleDateString('id-ID', { + weekday: 'long', + day: 'numeric', + month: 'long', + year: 'numeric', + })} + + + + {showDate && ( + { + setShowDate(false); + if (d) setOccurredAt(d); + }} + /> + )} + {/* Kategori */} Kategori @@ -290,6 +322,19 @@ const styles = StyleSheet.create({ color: colors.text, paddingVertical: 4, }, + dateRow: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + backgroundColor: colors.surface, + borderWidth: 1, + borderColor: colors.border, + borderRadius: 14, + paddingHorizontal: 14, + paddingVertical: 12, + marginBottom: 4, + }, + dateRowText: { flex: 1, fontSize: 14, color: colors.text, fontWeight: '600' }, saveHintCard: { flexDirection: 'row', alignItems: 'center',