Initial commit

Generated by create-expo-app 4.0.0.
This commit is contained in:
Eddy de Vink 2026-06-27 22:39:13 +02:00
commit f66034136d
19 changed files with 7409 additions and 0 deletions

5
.claude/settings.json Normal file
View file

@ -0,0 +1,5 @@
{
"enabledPlugins": {
"expo@claude-plugins-official": true
}
}

41
.gitignore vendored Normal file
View file

@ -0,0 +1,41 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
# dependencies
node_modules/
# Expo
.expo/
dist/
web-build/
expo-env.d.ts
# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
# Metro
.metro-health-check*
# debug
npm-debug.*
yarn-debug.*
yarn-error.*
# macOS
.DS_Store
*.pem
# local env files
.env*.local
# typescript
*.tsbuildinfo
# generated native folders
/ios
/android

3
AGENTS.md Normal file
View file

@ -0,0 +1,3 @@
# Expo HAS CHANGED
Read the exact versioned docs at https://docs.expo.dev/versions/v56.0.0/ before writing any code.

20
App.tsx Normal file
View file

@ -0,0 +1,20 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

1
CLAUDE.md Normal file
View file

@ -0,0 +1 @@
@AGENTS.md

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
app.json Normal file
View file

@ -0,0 +1,25 @@
{
"expo": {
"name": "weegschaal-app",
"slug": "weegschaal-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/android-icon-foreground.png",
"backgroundImage": "./assets/android-icon-background.png",
"monochromeImage": "./assets/android-icon-monochrome.png"
},
"predictiveBackGestureEnabled": false
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

BIN
assets/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

BIN
assets/splash-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,88 @@
# Weegschaal App — Design Doc
## Overzicht
React Native app voor het handmatig invoeren en opslaan van metingen van een slimme weegschaal. Data wordt lokaal opgeslagen in SQLite en gesynchroniseerd met Nextcloud via WebDAV.
## Data Model
```typescript
type Measurement = {
id: string // UUID v4
weight: number // kg
bmi: number
bodyFatPercentage: number
fatMass: number
musclePercentage: number
muscleMass: number
visceralFat: number // index
bmr: number // kcal (stofwisseling in rust)
measuredAt: string // ISO 8601 datum/tijd
createdAt: string
updatedAt: string
syncStatus: 'local' | 'synced'
}
```
## Technische Stack
| Laag | Keuze |
|---|---|
| Framework | Expo (managed workflow) |
| Lokale opslag | expo-sqlite |
| Navigatie | @react-navigation/native-stack |
| Grafiek | react-native-chart-kit |
| Sync | Eigen laag via fetch() naar Nextcloud WebDAV |
## Schermen
1. **Dashboard** — Toont de laatste meting en een lijn grafiek van het gewicht over de laatste 30 dagen.
2. **Nieuwe meting** — Formulier met genummerde invoervelden voor alle meetwaarden. Datum/tijd wordt automatisch ingevuld maar is aanpasbaar.
3. **Historie** — FlatList van alle metingen gesorteerd op `measuredAt` (nieuwste eerst).
4. **Instellingen** — WebDAV URL, gebruikersnaam, wachtwoord (opgeslagen in SecureStore), handmatige sync-knop.
## Component Structuur
```
App
├── NavigationContainer
│ ├── DashboardScreen
│ │ ├── LatestMeasurementCard
│ │ └── WeightChart
│ ├── NewMeasurementScreen
│ │ └── MeasurementForm
│ ├── HistoryScreen
│ │ └── MeasurementList → MeasurementRow
│ └── SettingsScreen
│ └── WebDAVConfigForm
├── database/
│ └── db.ts — SQLite initialisatie, CRUD operaties
├── sync/
│ └── syncService.ts — WebDAV upload/download/merge
├── types.ts — TypeScript types
└── utils/
└── uuid.ts — UUID generatie
```
## Sync Strategie
- **Opslag op WebDAV:** Enkel JSON-bestand op `weegschaal/measurements.json`
- **Bij app start:**
1. Download measurements.json van WebDAV
2. Merge met lokale SQLite: per meting de versie met laatste `updatedAt` behouden
3. Lokale database bijwerken
- **Na een nieuwe meting:**
1. Opslaan in SQLite met `syncStatus: 'local'`
2. Direct uploaden naar WebDAV
- **Handmatige sync:** Volledige merge + upload
## Foutafhandeling
- Geen netwerk → meting wordt lokaal opgeslagen met `syncStatus: 'local'`
- Conflict → last-write-wins op `updatedAt`
- WebDAV credentials fout → melding in Settings tonen
## Testen
- Jest voor unit tests (database, sync merge logica)
- Geen E2E in eerste versie

8
index.ts Normal file
View file

@ -0,0 +1,8 @@
import { registerRootComponent } from 'expo';
import App from './App';
// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

5983
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

22
package.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "weegschaal-app",
"version": "1.0.0",
"main": "index.ts",
"dependencies": {
"expo": "~56.0.12",
"expo-status-bar": "~56.0.4",
"react": "19.2.3",
"react-native": "0.85.3"
},
"devDependencies": {
"@types/react": "~19.2.2",
"typescript": "~6.0.3"
},
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"private": true
}

6
tsconfig.json Normal file
View file

@ -0,0 +1,6 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}