diff --git a/src/components/MeasurementForm.tsx b/src/components/MeasurementForm.tsx new file mode 100644 index 0000000..4c2b842 --- /dev/null +++ b/src/components/MeasurementForm.tsx @@ -0,0 +1,87 @@ +import React, { useState } from 'react' +import { View, Text, TextInput, TouchableOpacity, StyleSheet, KeyboardAvoidingView, Platform, ScrollView } from 'react-native' +import { Measurement } from '../types' +import { generateId } from '../utils/uuid' + +type Props = { + onSubmit: (m: Measurement) => void + initialValues?: Partial +} + +const fields: { key: keyof Measurement; label: string; placeholder: string; keyboardType: 'decimal-pad' | 'number-pad' }[] = [ + { key: 'weight', label: 'Gewicht (kg)', placeholder: '75.5', keyboardType: 'decimal-pad' }, + { key: 'bmi', label: 'BMI', placeholder: '22.3', keyboardType: 'decimal-pad' }, + { key: 'bodyFatPercentage', label: 'Vetpercentage (%)', placeholder: '15.2', keyboardType: 'decimal-pad' }, + { key: 'fatMass', label: 'Vetmassa (kg)', placeholder: '11.5', keyboardType: 'decimal-pad' }, + { key: 'musclePercentage', label: 'Spierpercentage (%)', placeholder: '40.1', keyboardType: 'decimal-pad' }, + { key: 'muscleMass', label: 'Spiermassa (kg)', placeholder: '30.3', keyboardType: 'decimal-pad' }, + { key: 'visceralFat', label: 'Buikvet (index)', placeholder: '8', keyboardType: 'number-pad' }, + { key: 'bmr', label: 'Stofwisseling (kcal)', placeholder: '1650', keyboardType: 'number-pad' }, +] + +export default function MeasurementForm({ onSubmit, initialValues }: Props) { + const [values, setValues] = useState>(() => { + const init: Record = {} + for (const f of fields) { + init[f.key] = initialValues?.[f.key]?.toString() ?? '' + } + return init + }) + + const handleSubmit = () => { + const now = new Date().toISOString() + const m: Measurement = { + id: generateId(), + weight: parseFloat(values.weight) || 0, + bmi: parseFloat(values.bmi) || 0, + bodyFatPercentage: parseFloat(values.bodyFatPercentage) || 0, + fatMass: parseFloat(values.fatMass) || 0, + musclePercentage: parseFloat(values.musclePercentage) || 0, + muscleMass: parseFloat(values.muscleMass) || 0, + visceralFat: parseInt(values.visceralFat, 10) || 0, + bmr: parseFloat(values.bmr) || 0, + measuredAt: now, + createdAt: now, + updatedAt: now, + syncStatus: 'local', + } + onSubmit(m) + } + + const setField = (key: string, value: string) => { + setValues(prev => ({ ...prev, [key]: value })) + } + + return ( + + + {fields.map(f => ( + + {f.label} + setField(f.key, v)} + placeholderTextColor="#999" + /> + + ))} + + Opslaan + + + + ) +} + +const styles = StyleSheet.create({ + container: { flex: 1, backgroundColor: '#f5f5f5' }, + scroll: { padding: 16 }, + field: { marginBottom: 12 }, + label: { fontSize: 14, fontWeight: '600', color: '#333', marginBottom: 4 }, + input: { backgroundColor: '#fff', borderRadius: 8, padding: 12, fontSize: 16, borderWidth: 1, borderColor: '#ddd' }, + button: { backgroundColor: '#4CAF50', padding: 16, borderRadius: 8, alignItems: 'center', marginTop: 8 }, + buttonText: { color: '#fff', fontSize: 16, fontWeight: '700' }, +}) diff --git a/src/screens/NewMeasurementScreen.tsx b/src/screens/NewMeasurementScreen.tsx new file mode 100644 index 0000000..ad0edc3 --- /dev/null +++ b/src/screens/NewMeasurementScreen.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import { Alert } from 'react-native' +import MeasurementForm from '../components/MeasurementForm' +import { Measurement } from '../types' +import { initDatabase, insertMeasurement } from '../database/db' + +type Props = { + navigation: any +} + +export default function NewMeasurementScreen({ navigation }: Props) { + const handleSubmit = async (m: Measurement) => { + await initDatabase() + await insertMeasurement(m) + Alert.alert('Opgeslagen', 'Meting is opgeslagen', [ + { text: 'OK', onPress: () => navigation.goBack() }, + ]) + } + + return +}