fix: keep save button visible when keyboard open, auto-sync after save

This commit is contained in:
Eddy de Vink 2026-06-27 23:40:14 +02:00
commit 1bad7684bc
2 changed files with 17 additions and 11 deletions

View file

@ -28,8 +28,6 @@ const fields: FieldDef[] = [
{ key: 'bmr', label: 'Stofwisseling (kcal)', placeholder: '1650', keyboardType: 'number-pad' }, { key: 'bmr', label: 'Stofwisseling (kcal)', placeholder: '1650', keyboardType: 'number-pad' },
] ]
const computedKeys = new Set<keyof Measurement>(['fatMass', 'muscleMass'])
export default function MeasurementForm({ onSubmit, initialValues }: Props) { export default function MeasurementForm({ onSubmit, initialValues }: Props) {
const [pickerOpen, setPickerOpen] = useState(false) const [pickerOpen, setPickerOpen] = useState(false)
const [measurementDate, setMeasurementDate] = useState<Date>(() => { const [measurementDate, setMeasurementDate] = useState<Date>(() => {
@ -89,7 +87,7 @@ export default function MeasurementForm({ onSubmit, initialValues }: Props) {
return ( return (
<KeyboardAvoidingView behavior="padding" style={styles.container}> <KeyboardAvoidingView behavior="padding" style={styles.container}>
<ScrollView contentContainerStyle={styles.scroll}> <ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
<View style={styles.field}> <View style={styles.field}>
<Text style={styles.label}>Datum</Text> <Text style={styles.label}>Datum</Text>
<TouchableOpacity style={styles.dateButton} onPress={() => setPickerOpen(true)}> <TouchableOpacity style={styles.dateButton} onPress={() => setPickerOpen(true)}>
@ -139,17 +137,17 @@ export default function MeasurementForm({ onSubmit, initialValues }: Props) {
</View> </View>
) )
})} })}
<TouchableOpacity style={styles.button} onPress={handleSubmit}>
<Text style={styles.buttonText}>Opslaan</Text>
</TouchableOpacity>
</ScrollView> </ScrollView>
<TouchableOpacity style={styles.button} onPress={handleSubmit}>
<Text style={styles.buttonText}>Opslaan</Text>
</TouchableOpacity>
</KeyboardAvoidingView> </KeyboardAvoidingView>
) )
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5' }, container: { flex: 1, backgroundColor: '#f5f5f5' },
scroll: { padding: 16 }, scroll: { padding: 16, paddingBottom: 0 },
field: { marginBottom: 12 }, field: { marginBottom: 12 },
label: { fontSize: 14, fontWeight: '600', color: '#333', marginBottom: 4 }, label: { fontSize: 14, fontWeight: '600', color: '#333', marginBottom: 4 },
input: { backgroundColor: '#fff', borderRadius: 8, padding: 12, fontSize: 16, borderWidth: 1, borderColor: '#ddd' }, input: { backgroundColor: '#fff', borderRadius: 8, padding: 12, fontSize: 16, borderWidth: 1, borderColor: '#ddd' },
@ -157,6 +155,6 @@ const styles = StyleSheet.create({
computedText: { fontSize: 16, color: '#666' }, computedText: { fontSize: 16, color: '#666' },
dateButton: { backgroundColor: '#fff', borderRadius: 8, padding: 12, borderWidth: 1, borderColor: '#ddd' }, dateButton: { backgroundColor: '#fff', borderRadius: 8, padding: 12, borderWidth: 1, borderColor: '#ddd' },
dateButtonText: { fontSize: 16, color: '#333' }, dateButtonText: { fontSize: 16, color: '#333' },
button: { backgroundColor: '#4CAF50', padding: 16, borderRadius: 8, alignItems: 'center', marginTop: 8 }, button: { backgroundColor: '#4CAF50', padding: 16, borderRadius: 8, alignItems: 'center', margin: 16 },
buttonText: { color: '#fff', fontSize: 16, fontWeight: '700' }, buttonText: { color: '#fff', fontSize: 16, fontWeight: '700' },
}) })

View file

@ -30,9 +30,17 @@ export default function NewMeasurementScreen({ navigation }: Props) {
const handleSubmit = async (m: Measurement) => { const handleSubmit = async (m: Measurement) => {
await initDatabase() await initDatabase()
await insertMeasurement(m) await insertMeasurement(m)
Alert.alert('Opgeslagen', 'Meting is opgeslagen', [ try {
{ text: 'OK', onPress: () => navigation.goBack() }, const { syncAll } = await import('../sync/syncService')
]) await syncAll()
Alert.alert('Opgeslagen & gesynct', 'Meting is opgeslagen en gesynchroniseerd', [
{ text: 'OK', onPress: () => navigation.goBack() },
])
} catch {
Alert.alert('Opgeslagen', 'Meting is opgeslagen (sync mislukt)', [
{ text: 'OK', onPress: () => navigation.goBack() },
])
}
} }
if (latest === undefined) { if (latest === undefined) {