118 lines
3.0 KiB
JavaScript
118 lines
3.0 KiB
JavaScript
import { useState } from 'react';
|
|
import { Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
|
|
|
|
import { budgetPeriodLabels, colors } from '../../utils/constants';
|
|
|
|
const budgetPeriods = ['day', 'week', 'month', 'shoppingTrip'];
|
|
|
|
export default function BudgetInput({ value, currency, period, onChangePeriod, onChangeValue }) {
|
|
const [inputValue, setInputValue] = useState(String(value ?? ''));
|
|
|
|
function updateValue(text) {
|
|
setInputValue(text);
|
|
const parsedValue = Number(text.replace(',', '.'));
|
|
onChangeValue(text.trim() && Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : undefined);
|
|
}
|
|
|
|
return (
|
|
<View style={styles.wrap}>
|
|
<Text style={styles.label}>Betrag (optional)</Text>
|
|
<Text style={styles.hint}>Ohne Budget bleibt die Preisbewertung offen.</Text>
|
|
<View style={styles.row}>
|
|
<Text style={styles.currency}>{currency}</Text>
|
|
<TextInput
|
|
accessibilityLabel="Budgetbetrag"
|
|
keyboardType="decimal-pad"
|
|
onChangeText={updateValue}
|
|
placeholder="z. B. 45.00"
|
|
placeholderTextColor={colors.muted}
|
|
style={styles.input}
|
|
value={inputValue}
|
|
/>
|
|
</View>
|
|
<View style={styles.periodGrid}>
|
|
{budgetPeriods.map((option) => {
|
|
const isActive = period === option;
|
|
return (
|
|
<Pressable
|
|
accessibilityRole="button"
|
|
accessibilityState={{ selected: isActive }}
|
|
key={option}
|
|
onPress={() => onChangePeriod(option)}
|
|
style={[styles.periodChip, isActive ? styles.activePeriodChip : null]}
|
|
>
|
|
<Text style={[styles.periodText, isActive ? styles.activePeriodText : null]}>
|
|
pro {budgetPeriodLabels[option]}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
wrap: {
|
|
gap: 10
|
|
},
|
|
hint: {
|
|
color: colors.muted,
|
|
fontSize: 13,
|
|
lineHeight: 18
|
|
},
|
|
label: {
|
|
color: colors.text,
|
|
fontSize: 15,
|
|
fontWeight: '800'
|
|
},
|
|
row: {
|
|
alignItems: 'center',
|
|
flexDirection: 'row',
|
|
gap: 10
|
|
},
|
|
currency: {
|
|
color: colors.muted,
|
|
fontSize: 16,
|
|
fontWeight: '800'
|
|
},
|
|
input: {
|
|
borderColor: colors.border,
|
|
borderRadius: 12,
|
|
borderWidth: 1,
|
|
color: colors.text,
|
|
flex: 1,
|
|
fontSize: 16,
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 10
|
|
},
|
|
periodGrid: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
gap: 8
|
|
},
|
|
periodChip: {
|
|
alignItems: 'center',
|
|
borderColor: colors.border,
|
|
borderRadius: 12,
|
|
borderWidth: 1,
|
|
flexGrow: 1,
|
|
minHeight: 44,
|
|
justifyContent: 'center',
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 9
|
|
},
|
|
activePeriodChip: {
|
|
backgroundColor: colors.primary,
|
|
borderColor: colors.primary
|
|
},
|
|
periodText: {
|
|
color: colors.text,
|
|
fontSize: 13,
|
|
fontWeight: '800'
|
|
},
|
|
activePeriodText: {
|
|
color: colors.surface
|
|
}
|
|
});
|