Kantongku: fitur pilih tanggal saat catat & edit transaksi (backdate)
This commit is contained in:
@@ -35,7 +35,8 @@
|
||||
"resizeMode": "contain"
|
||||
}
|
||||
],
|
||||
"expo-font"
|
||||
"expo-font",
|
||||
"@react-native-community/datetimepicker"
|
||||
],
|
||||
"extra": {
|
||||
"eas": {
|
||||
|
||||
Generated
+24
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Category[]>([]);
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(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() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Tanggal */}
|
||||
<Text style={styles.sectionTitle}>Tanggal</Text>
|
||||
<Pressable style={styles.dateRow} onPress={() => setShowDate(true)}>
|
||||
<Ionicons name="calendar" size={18} color={colors.primaryDark} />
|
||||
<Text style={styles.dateRowText}>
|
||||
{occurredAt.toLocaleDateString('id-ID', {
|
||||
weekday: 'long',
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={16} color={colors.textMuted} />
|
||||
</Pressable>
|
||||
{showDate && (
|
||||
<DateTimePicker
|
||||
value={occurredAt}
|
||||
mode="date"
|
||||
maximumDate={new Date()}
|
||||
onChange={(e, d) => {
|
||||
setShowDate(false);
|
||||
if (d) setOccurredAt(d);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Kategori */}
|
||||
<Text style={styles.sectionTitle}>Kategori</Text>
|
||||
<View style={styles.categoryGrid}>
|
||||
@@ -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',
|
||||
|
||||
@@ -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<Category[]>([]);
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(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() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Tanggal */}
|
||||
<Text style={styles.sectionTitle}>Tanggal</Text>
|
||||
<Pressable style={styles.dateRow} onPress={() => setShowDate(true)}>
|
||||
<Ionicons name="calendar" size={18} color={colors.primaryDark} />
|
||||
<Text style={styles.dateRowText}>
|
||||
{occurredAt.toLocaleDateString('id-ID', {
|
||||
weekday: 'long',
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</Text>
|
||||
<Ionicons name="chevron-down" size={16} color={colors.textMuted} />
|
||||
</Pressable>
|
||||
{showDate && (
|
||||
<DateTimePicker
|
||||
value={occurredAt}
|
||||
mode="date"
|
||||
maximumDate={new Date()}
|
||||
onChange={(e, d) => {
|
||||
setShowDate(false);
|
||||
if (d) setOccurredAt(d);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Kategori */}
|
||||
<Text style={styles.sectionTitle}>Kategori</Text>
|
||||
<View style={styles.categoryGrid}>
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user