Initial commit
Generated by create-expo-app 4.0.0.
This commit is contained in:
commit
f66034136d
19 changed files with 7409 additions and 0 deletions
5
.claude/settings.json
Normal file
5
.claude/settings.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"enabledPlugins": {
|
||||
"expo@claude-plugins-official": true
|
||||
}
|
||||
}
|
||||
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal 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
3
AGENTS.md
Normal 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
20
App.tsx
Normal 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
1
CLAUDE.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
@AGENTS.md
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal 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
25
app.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/android-icon-background.png
Normal file
BIN
assets/android-icon-background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
assets/android-icon-foreground.png
Normal file
BIN
assets/android-icon-foreground.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
BIN
assets/android-icon-monochrome.png
Normal file
BIN
assets/android-icon-monochrome.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4 KiB |
BIN
assets/favicon.png
Normal file
BIN
assets/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 384 KiB |
BIN
assets/splash-icon.png
Normal file
BIN
assets/splash-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
1186
docs/superpowers/plans/2026-06-27-weegschaal-app-implementation.md
Normal file
1186
docs/superpowers/plans/2026-06-27-weegschaal-app-implementation.md
Normal file
File diff suppressed because it is too large
Load diff
88
docs/superpowers/specs/2026-06-27-weegschaal-app-design.md
Normal file
88
docs/superpowers/specs/2026-06-27-weegschaal-app-design.md
Normal 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
8
index.ts
Normal 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
5983
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
22
package.json
Normal file
22
package.json
Normal 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
6
tsconfig.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": "expo/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue