refactor navigation: classic bottom tab bar with FAB + header icons
- Replace floating pill tab bar with classic anchored bottom bar (Home | FAB Scan | Map) - Add central FAB button (green, elevated) for Scanner - Move History → Notifications and Profile → Settings (accessible via header icons) - Add SearchHeader with bell (notifications) and settings icons - Add MapScreen placeholder - Extract SearchHeader component from HomeScreen - Switch to lucide-react-native icons for bottom tab bar - Fix react-dom version mismatch (19.2.4 → 19.1.0) - Clean up unused imports in homeheader.tsx - Update navigation types, deep links, and i18n keys Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3
.gitignore
vendored
|
|
@ -23,3 +23,6 @@ VinEye/.expo/
|
||||||
VinEye/dist/
|
VinEye/dist/
|
||||||
VinEye/ios/
|
VinEye/ios/
|
||||||
VinEye/android/
|
VinEye/android/
|
||||||
|
|
||||||
|
# dependances
|
||||||
|
node_modules/
|
||||||
65
AGENTS.md
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
# Repository Guidelines
|
||||||
|
|
||||||
|
Monorepo with two components: a **Python/TensorFlow CNN** for grapevine disease detection and a **React Native (Expo) mobile app** (VinEye) that runs the model on-device via TFLite.
|
||||||
|
|
||||||
|
## Project Structure & Module Organization
|
||||||
|
|
||||||
|
```
|
||||||
|
venv/src/ # Python ML pipeline (training, evaluation, attribution)
|
||||||
|
venv/models/ # Trained model artifacts (.keras, .tflite)
|
||||||
|
docs/images/ # Dataset & results visualizations
|
||||||
|
VinEye/ # Expo React Native mobile app
|
||||||
|
src/screens/ # 6 screens: Splash, Home, Scanner, Result, History, Profile
|
||||||
|
src/components/ # UI grouped by feature (gamification/, scanner/, history/, ui/)
|
||||||
|
src/services/ # TFLite inference, AsyncStorage, haptics
|
||||||
|
src/hooks/ # useDetection, useGameProgress, useHistory
|
||||||
|
src/navigation/ # React Navigation v7 (BottomTabs + NativeStack)
|
||||||
|
src/i18n/ # FR + EN translations (i18next)
|
||||||
|
src/theme/ # Design tokens (primary #2D6A4F, accent #7C3AED)
|
||||||
|
```
|
||||||
|
|
||||||
|
The ML model currently uses a mock TFLite detector in the mobile app (weighted random: 70% vine / 20% uncertain / 10% not_vine). The CNN trains on 9027 images (256x256) across 4 classes: Black Rot, ESCA, Healthy, Leaf Blight.
|
||||||
|
|
||||||
|
## Build, Test, and Development Commands
|
||||||
|
|
||||||
|
### VinEye (Mobile)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd VinEye
|
||||||
|
pnpm install # Install dependencies (pnpm only, never npm/yarn)
|
||||||
|
pnpm start # Start Expo dev server
|
||||||
|
pnpm android # Run on Android
|
||||||
|
pnpm ios # Run on iOS
|
||||||
|
pnpm web # Run on web
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python ML Pipeline
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd venv/src
|
||||||
|
python data_split.py # Split raw data into train/val/test (80/10/10)
|
||||||
|
python data_explore.py # EDA: class distribution, sample visualization
|
||||||
|
python model_train.py # Train CNN, exports .keras + .tflite to venv/models/
|
||||||
|
python evaluate_model.py # Accuracy/loss curves, confusion matrix, top-k predictions
|
||||||
|
python gradient.py # Integrated gradients attribution masks
|
||||||
|
```
|
||||||
|
|
||||||
|
Scripts must be run from `venv/src/` — paths are derived relative to that directory.
|
||||||
|
|
||||||
|
## Coding Style & Naming Conventions
|
||||||
|
|
||||||
|
**TypeScript (VinEye):**
|
||||||
|
- Strict mode enabled, path alias `@/*` maps to `src/*`
|
||||||
|
- Max 300 lines per file
|
||||||
|
- NativeWind (TailwindCSS) for styling — no inline styles
|
||||||
|
- `useEffect` must be imported from `react`, never from `react-native-reanimated`
|
||||||
|
- React Navigation v7 only (Expo Router is forbidden)
|
||||||
|
- RN-native UI components only (no web-based component libraries)
|
||||||
|
|
||||||
|
**Python:** TensorFlow/Keras Sequential API, scripts use `from module import *` pattern.
|
||||||
|
|
||||||
|
No linter or formatter configs are enforced.
|
||||||
|
|
||||||
|
## Commit Guidelines
|
||||||
|
|
||||||
|
Commit messages are informal, descriptive, lowercase. No conventional commits format is enforced. Examples from history: `add VinEye frontend app + fix hardcoded paths + gitignore`, `update`, `maj`.
|
||||||
BIN
VinEye/assets/logo.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
|
|
@ -28,8 +28,10 @@
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
"i18next": "^26.0.1",
|
"i18next": "^26.0.1",
|
||||||
"lottie-react-native": "^7.3.6",
|
"lottie-react-native": "^7.3.6",
|
||||||
|
"lucide-react-native": "^1.7.0",
|
||||||
"nativewind": "^4.2.3",
|
"nativewind": "^4.2.3",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
|
"react-dom": "19.1.0",
|
||||||
"react-i18next": "^17.0.1",
|
"react-i18next": "^17.0.1",
|
||||||
"react-lucid": "^0.0.1",
|
"react-lucid": "^0.0.1",
|
||||||
"react-native": "0.81.5",
|
"react-native": "0.81.5",
|
||||||
|
|
@ -37,6 +39,7 @@
|
||||||
"react-native-safe-area-context": "~5.6.0",
|
"react-native-safe-area-context": "~5.6.0",
|
||||||
"react-native-screens": "~4.16.0",
|
"react-native-screens": "~4.16.0",
|
||||||
"react-native-svg": "^15.12.1",
|
"react-native-svg": "^15.12.1",
|
||||||
|
"react-native-web": "^0.21.2",
|
||||||
"react-native-worklets": "0.5.1",
|
"react-native-worklets": "0.5.1",
|
||||||
"tailwind-merge": "^3.5.0",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tailwindcss": "3.4.17"
|
"tailwindcss": "3.4.17"
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,13 @@ importers:
|
||||||
version: 7.14.10(@react-navigation/native@7.2.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 7.14.10(@react-navigation/native@7.2.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
'@rn-primitives/portal':
|
'@rn-primitives/portal':
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
version: 1.4.0(@types/react@19.1.17)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))
|
version: 1.4.0(@types/react@19.1.17)(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))
|
||||||
'@rn-primitives/separator':
|
'@rn-primitives/separator':
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
version: 1.4.0(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 1.4.0(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
'@rn-primitives/slot':
|
'@rn-primitives/slot':
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
version: 1.4.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 1.4.0(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1
|
version: 0.7.1
|
||||||
|
|
@ -43,13 +43,13 @@ importers:
|
||||||
version: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
expo-camera:
|
expo-camera:
|
||||||
specifier: ~17.0.10
|
specifier: ~17.0.10
|
||||||
version: 17.0.10(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 17.0.10(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
expo-haptics:
|
expo-haptics:
|
||||||
specifier: ~15.0.8
|
specifier: ~15.0.8
|
||||||
version: 15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))
|
version: 15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))
|
||||||
expo-image:
|
expo-image:
|
||||||
specifier: ~3.0.11
|
specifier: ~3.0.11
|
||||||
version: 3.0.11(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 3.0.11(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
expo-linear-gradient:
|
expo-linear-gradient:
|
||||||
specifier: ~15.0.8
|
specifier: ~15.0.8
|
||||||
version: 15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
|
@ -65,15 +65,21 @@ importers:
|
||||||
lottie-react-native:
|
lottie-react-native:
|
||||||
specifier: ^7.3.6
|
specifier: ^7.3.6
|
||||||
version: 7.3.6(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 7.3.6(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
lucide-react-native:
|
||||||
|
specifier: ^1.7.0
|
||||||
|
version: 1.7.0(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
nativewind:
|
nativewind:
|
||||||
specifier: ^4.2.3
|
specifier: ^4.2.3
|
||||||
version: 4.2.3(react-native-reanimated@4.1.7(react-native-worklets@0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.17)
|
version: 4.2.3(react-native-reanimated@4.1.7(react-native-worklets@0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.17)
|
||||||
react:
|
react:
|
||||||
specifier: 19.1.0
|
specifier: 19.1.0
|
||||||
version: 19.1.0
|
version: 19.1.0
|
||||||
|
react-dom:
|
||||||
|
specifier: 19.1.0
|
||||||
|
version: 19.1.0(react@19.1.0)
|
||||||
react-i18next:
|
react-i18next:
|
||||||
specifier: ^17.0.1
|
specifier: ^17.0.1
|
||||||
version: 17.0.1(i18next@26.0.1(typescript@5.9.3))(react-dom@19.2.4(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(typescript@5.9.3)
|
version: 17.0.1(i18next@26.0.1(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(typescript@5.9.3)
|
||||||
react-lucid:
|
react-lucid:
|
||||||
specifier: ^0.0.1
|
specifier: ^0.0.1
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
|
|
@ -92,6 +98,9 @@ importers:
|
||||||
react-native-svg:
|
react-native-svg:
|
||||||
specifier: ^15.12.1
|
specifier: ^15.12.1
|
||||||
version: 15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
react-native-web:
|
||||||
|
specifier: ^0.21.2
|
||||||
|
version: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
react-native-worklets:
|
react-native-worklets:
|
||||||
specifier: 0.5.1
|
specifier: 0.5.1
|
||||||
version: 0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
version: 0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
|
@ -932,6 +941,9 @@ packages:
|
||||||
resolution: {integrity: sha512-KlRawK4aXxRLlR3HYVfZKhfQp7sejQefQ/LttUWUkErhKO0AFt+yznoSLq7xwIrH9K3A3YwImHuFVtUtuDmurA==}
|
resolution: {integrity: sha512-KlRawK4aXxRLlR3HYVfZKhfQp7sejQefQ/LttUWUkErhKO0AFt+yznoSLq7xwIrH9K3A3YwImHuFVtUtuDmurA==}
|
||||||
engines: {node: '>= 20.19.4'}
|
engines: {node: '>= 20.19.4'}
|
||||||
|
|
||||||
|
'@react-native/normalize-colors@0.74.89':
|
||||||
|
resolution: {integrity: sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==}
|
||||||
|
|
||||||
'@react-native/normalize-colors@0.81.5':
|
'@react-native/normalize-colors@0.81.5':
|
||||||
resolution: {integrity: sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==}
|
resolution: {integrity: sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==}
|
||||||
|
|
||||||
|
|
@ -1443,10 +1455,16 @@ packages:
|
||||||
core-js-compat@3.49.0:
|
core-js-compat@3.49.0:
|
||||||
resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==}
|
resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==}
|
||||||
|
|
||||||
|
cross-fetch@3.2.0:
|
||||||
|
resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
|
css-in-js-utils@3.1.0:
|
||||||
|
resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==}
|
||||||
|
|
||||||
css-select@5.2.2:
|
css-select@5.2.2:
|
||||||
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
|
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
|
||||||
|
|
||||||
|
|
@ -1742,6 +1760,12 @@ packages:
|
||||||
fb-watchman@2.0.2:
|
fb-watchman@2.0.2:
|
||||||
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
|
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
|
||||||
|
|
||||||
|
fbjs-css-vars@1.0.2:
|
||||||
|
resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==}
|
||||||
|
|
||||||
|
fbjs@3.0.5:
|
||||||
|
resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==}
|
||||||
|
|
||||||
fdir@6.5.0:
|
fdir@6.5.0:
|
||||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
@ -1872,6 +1896,9 @@ packages:
|
||||||
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
|
hyphenate-style-name@1.1.0:
|
||||||
|
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||||
|
|
||||||
i18next@26.0.1:
|
i18next@26.0.1:
|
||||||
resolution: {integrity: sha512-vtz5sXU4+nkCm8yEU+JJ6yYIx0mkg9e68W0G0PXpnOsmzLajNsW5o28DJMqbajxfsfq0gV3XdrBudsDQnwxfsQ==}
|
resolution: {integrity: sha512-vtz5sXU4+nkCm8yEU+JJ6yYIx0mkg9e68W0G0PXpnOsmzLajNsW5o28DJMqbajxfsfq0gV3XdrBudsDQnwxfsQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -1906,6 +1933,9 @@ packages:
|
||||||
ini@1.3.8:
|
ini@1.3.8:
|
||||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||||
|
|
||||||
|
inline-style-prefixer@7.0.1:
|
||||||
|
resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==}
|
||||||
|
|
||||||
invariant@2.2.4:
|
invariant@2.2.4:
|
||||||
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
||||||
|
|
||||||
|
|
@ -2224,6 +2254,13 @@ packages:
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||||
|
|
||||||
|
lucide-react-native@1.7.0:
|
||||||
|
resolution: {integrity: sha512-wGJY5nosSawh028jg8r1ZKqnGPDIVfIL9xvKOs4wPYFQHeJMHsADYm/lmuFYXMXXatSkHhpsCjeqIRgeFGzf8g==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-native: '*'
|
||||||
|
react-native-svg: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0
|
||||||
|
|
||||||
makeerror@1.0.12:
|
makeerror@1.0.12:
|
||||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||||
|
|
||||||
|
|
@ -2236,6 +2273,9 @@ packages:
|
||||||
memoize-one@5.2.1:
|
memoize-one@5.2.1:
|
||||||
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
|
||||||
|
|
||||||
|
memoize-one@6.0.0:
|
||||||
|
resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
|
||||||
|
|
||||||
merge-options@3.0.4:
|
merge-options@3.0.4:
|
||||||
resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==}
|
resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
@ -2454,6 +2494,15 @@ packages:
|
||||||
nested-error-stacks@2.0.1:
|
nested-error-stacks@2.0.1:
|
||||||
resolution: {integrity: sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==}
|
resolution: {integrity: sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-forge@1.4.0:
|
node-forge@1.4.0:
|
||||||
resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==}
|
resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==}
|
||||||
engines: {node: '>= 6.13.0'}
|
engines: {node: '>= 6.13.0'}
|
||||||
|
|
@ -2656,6 +2705,9 @@ packages:
|
||||||
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
|
|
||||||
|
promise@7.3.1:
|
||||||
|
resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==}
|
||||||
|
|
||||||
promise@8.3.0:
|
promise@8.3.0:
|
||||||
resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==}
|
resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==}
|
||||||
|
|
||||||
|
|
@ -2692,10 +2744,10 @@ packages:
|
||||||
react-devtools-core@6.1.5:
|
react-devtools-core@6.1.5:
|
||||||
resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==}
|
resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==}
|
||||||
|
|
||||||
react-dom@19.2.4:
|
react-dom@19.1.0:
|
||||||
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
|
resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^19.2.4
|
react: ^19.1.0
|
||||||
|
|
||||||
react-freeze@1.0.4:
|
react-freeze@1.0.4:
|
||||||
resolution: {integrity: sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==}
|
resolution: {integrity: sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==}
|
||||||
|
|
@ -2775,6 +2827,12 @@ packages:
|
||||||
react: '*'
|
react: '*'
|
||||||
react-native: '*'
|
react-native: '*'
|
||||||
|
|
||||||
|
react-native-web@0.21.2:
|
||||||
|
resolution: {integrity: sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
react-native-worklets@0.5.1:
|
react-native-worklets@0.5.1:
|
||||||
resolution: {integrity: sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==}
|
resolution: {integrity: sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -2889,9 +2947,6 @@ packages:
|
||||||
scheduler@0.26.0:
|
scheduler@0.26.0:
|
||||||
resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==}
|
resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==}
|
||||||
|
|
||||||
scheduler@0.27.0:
|
|
||||||
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
|
|
||||||
|
|
||||||
semver@6.3.1:
|
semver@6.3.1:
|
||||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -2918,6 +2973,9 @@ packages:
|
||||||
resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==}
|
resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
setimmediate@1.0.5:
|
||||||
|
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||||
|
|
||||||
setprototypeof@1.2.0:
|
setprototypeof@1.2.0:
|
||||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||||
|
|
||||||
|
|
@ -3025,6 +3083,9 @@ packages:
|
||||||
structured-headers@0.4.1:
|
structured-headers@0.4.1:
|
||||||
resolution: {integrity: sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==}
|
resolution: {integrity: sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==}
|
||||||
|
|
||||||
|
styleq@0.1.3:
|
||||||
|
resolution: {integrity: sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==}
|
||||||
|
|
||||||
sucrase@3.35.1:
|
sucrase@3.35.1:
|
||||||
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
|
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
|
@ -3105,6 +3166,9 @@ packages:
|
||||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
|
|
||||||
|
tr46@0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
|
||||||
ts-interface-checker@0.1.13:
|
ts-interface-checker@0.1.13:
|
||||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||||
|
|
||||||
|
|
@ -3125,6 +3189,10 @@ packages:
|
||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
ua-parser-js@1.0.41:
|
||||||
|
resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
undici-types@7.18.2:
|
undici-types@7.18.2:
|
||||||
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
||||||
|
|
||||||
|
|
@ -3203,6 +3271,9 @@ packages:
|
||||||
wcwidth@1.0.1:
|
wcwidth@1.0.1:
|
||||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1:
|
||||||
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
webidl-conversions@5.0.0:
|
webidl-conversions@5.0.0:
|
||||||
resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==}
|
resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -3214,6 +3285,9 @@ packages:
|
||||||
resolution: {integrity: sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==}
|
resolution: {integrity: sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
@ -4339,19 +4413,19 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.1.17
|
'@types/react': 19.1.17
|
||||||
|
|
||||||
'@radix-ui/react-primitive@2.1.4(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react@19.1.0)':
|
'@radix-ui/react-primitive@2.1.4(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-slot': 1.2.4(@types/react@19.1.17)(react@19.1.0)
|
'@radix-ui/react-slot': 1.2.4(@types/react@19.1.17)(react@19.1.0)
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.2.4(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.1.17
|
'@types/react': 19.1.17
|
||||||
|
|
||||||
'@radix-ui/react-separator@1.1.8(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react@19.1.0)':
|
'@radix-ui/react-separator@1.1.8(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-primitive': 2.1.4(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react@19.1.0)
|
'@radix-ui/react-primitive': 2.1.4(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.2.4(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.1.17
|
'@types/react': 19.1.17
|
||||||
|
|
||||||
|
|
@ -4560,6 +4634,8 @@ snapshots:
|
||||||
- supports-color
|
- supports-color
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@react-native/normalize-colors@0.74.89': {}
|
||||||
|
|
||||||
'@react-native/normalize-colors@0.81.5': {}
|
'@react-native/normalize-colors@0.81.5': {}
|
||||||
|
|
||||||
'@react-native/virtualized-lists@0.81.5(@types/react@19.1.17)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
'@react-native/virtualized-lists@0.81.5(@types/react@19.1.17)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
||||||
|
|
@ -4634,41 +4710,45 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.11
|
nanoid: 3.3.11
|
||||||
|
|
||||||
'@rn-primitives/portal@1.4.0(@types/react@19.1.17)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))':
|
'@rn-primitives/portal@1.4.0(@types/react@19.1.17)(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
zustand: 5.0.12(@types/react@19.1.17)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))
|
zustand: 5.0.12(@types/react@19.1.17)(react@19.1.0)(use-sync-external-store@1.6.0(react@19.1.0))
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
- immer
|
- immer
|
||||||
- use-sync-external-store
|
- use-sync-external-store
|
||||||
|
|
||||||
'@rn-primitives/separator@1.4.0(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
'@rn-primitives/separator@1.4.0(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@radix-ui/react-separator': 1.1.8(@types/react@19.1.17)(react-dom@19.2.4(react@19.1.0))(react@19.1.0)
|
'@radix-ui/react-separator': 1.1.8(@types/react@19.1.17)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
'@rn-primitives/slot': 1.4.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
'@rn-primitives/slot': 1.4.0(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
'@rn-primitives/types': 1.4.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
'@rn-primitives/types': 1.4.0(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
- '@types/react-dom'
|
- '@types/react-dom'
|
||||||
- react-dom
|
- react-dom
|
||||||
|
|
||||||
'@rn-primitives/slot@1.4.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
'@rn-primitives/slot@1.4.0(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
'@rn-primitives/types@1.4.0(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
'@rn-primitives/types@1.4.0(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
'@sinclair/typebox@0.27.10': {}
|
'@sinclair/typebox@0.27.10': {}
|
||||||
|
|
||||||
|
|
@ -5151,12 +5231,22 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.28.1
|
browserslist: 4.28.1
|
||||||
|
|
||||||
|
cross-fetch@3.2.0:
|
||||||
|
dependencies:
|
||||||
|
node-fetch: 2.7.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
shebang-command: 2.0.0
|
shebang-command: 2.0.0
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
|
|
||||||
|
css-in-js-utils@3.1.0:
|
||||||
|
dependencies:
|
||||||
|
hyphenate-style-name: 1.1.0
|
||||||
|
|
||||||
css-select@5.2.2:
|
css-select@5.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
boolbase: 1.0.0
|
boolbase: 1.0.0
|
||||||
|
|
@ -5280,12 +5370,14 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
expo-camera@17.0.10(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
expo-camera@17.0.10(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
invariant: 2.2.4
|
invariant: 2.2.4
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
optionalDependencies:
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
expo-constants@18.0.13(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)):
|
expo-constants@18.0.13(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -5312,11 +5404,13 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
expo-image@3.0.11(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
expo-image@3.0.11(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
expo: 54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
optionalDependencies:
|
||||||
|
react-native-web: 0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
expo-keep-awake@15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react@19.1.0):
|
expo-keep-awake@15.0.8(expo@54.0.33(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -5412,6 +5506,20 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
bser: 2.1.1
|
bser: 2.1.1
|
||||||
|
|
||||||
|
fbjs-css-vars@1.0.2: {}
|
||||||
|
|
||||||
|
fbjs@3.0.5:
|
||||||
|
dependencies:
|
||||||
|
cross-fetch: 3.2.0
|
||||||
|
fbjs-css-vars: 1.0.2
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
object-assign: 4.1.1
|
||||||
|
promise: 7.3.1
|
||||||
|
setimmediate: 1.0.5
|
||||||
|
ua-parser-js: 1.0.41
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
|
||||||
fdir@6.5.0(picomatch@4.0.4):
|
fdir@6.5.0(picomatch@4.0.4):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
picomatch: 4.0.4
|
picomatch: 4.0.4
|
||||||
|
|
@ -5536,6 +5644,8 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
hyphenate-style-name@1.1.0: {}
|
||||||
|
|
||||||
i18next@26.0.1(typescript@5.9.3):
|
i18next@26.0.1(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.29.2
|
'@babel/runtime': 7.29.2
|
||||||
|
|
@ -5561,6 +5671,10 @@ snapshots:
|
||||||
|
|
||||||
ini@1.3.8: {}
|
ini@1.3.8: {}
|
||||||
|
|
||||||
|
inline-style-prefixer@7.0.1:
|
||||||
|
dependencies:
|
||||||
|
css-in-js-utils: 3.1.0
|
||||||
|
|
||||||
invariant@2.2.4:
|
invariant@2.2.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
|
|
@ -5840,6 +5954,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 3.1.1
|
yallist: 3.1.1
|
||||||
|
|
||||||
|
lucide-react-native@1.7.0(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||||
|
dependencies:
|
||||||
|
react: 19.1.0
|
||||||
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
|
react-native-svg: 15.12.1(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||||
|
|
||||||
makeerror@1.0.12:
|
makeerror@1.0.12:
|
||||||
dependencies:
|
dependencies:
|
||||||
tmpl: 1.0.5
|
tmpl: 1.0.5
|
||||||
|
|
@ -5850,6 +5970,8 @@ snapshots:
|
||||||
|
|
||||||
memoize-one@5.2.1: {}
|
memoize-one@5.2.1: {}
|
||||||
|
|
||||||
|
memoize-one@6.0.0: {}
|
||||||
|
|
||||||
merge-options@3.0.4:
|
merge-options@3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-plain-obj: 2.1.0
|
is-plain-obj: 2.1.0
|
||||||
|
|
@ -6284,6 +6406,10 @@ snapshots:
|
||||||
|
|
||||||
nested-error-stacks@2.0.1: {}
|
nested-error-stacks@2.0.1: {}
|
||||||
|
|
||||||
|
node-fetch@2.7.0:
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
node-forge@1.4.0: {}
|
node-forge@1.4.0: {}
|
||||||
|
|
||||||
node-int64@0.4.0: {}
|
node-int64@0.4.0: {}
|
||||||
|
|
@ -6457,6 +6583,10 @@ snapshots:
|
||||||
|
|
||||||
progress@2.0.3: {}
|
progress@2.0.3: {}
|
||||||
|
|
||||||
|
promise@7.3.1:
|
||||||
|
dependencies:
|
||||||
|
asap: 2.0.6
|
||||||
|
|
||||||
promise@8.3.0:
|
promise@8.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
asap: 2.0.6
|
asap: 2.0.6
|
||||||
|
|
@ -6500,16 +6630,16 @@ snapshots:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
react-dom@19.2.4(react@19.1.0):
|
react-dom@19.1.0(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
scheduler: 0.27.0
|
scheduler: 0.26.0
|
||||||
|
|
||||||
react-freeze@1.0.4(react@19.1.0):
|
react-freeze@1.0.4(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
|
|
||||||
react-i18next@17.0.1(i18next@26.0.1(typescript@5.9.3))(react-dom@19.2.4(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(typescript@5.9.3):
|
react-i18next@17.0.1(i18next@26.0.1(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.29.2
|
'@babel/runtime': 7.29.2
|
||||||
html-parse-stringify: 3.0.1
|
html-parse-stringify: 3.0.1
|
||||||
|
|
@ -6517,7 +6647,7 @@ snapshots:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
use-sync-external-store: 1.6.0(react@19.1.0)
|
use-sync-external-store: 1.6.0(react@19.1.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-dom: 19.2.4(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
|
|
||||||
|
|
@ -6579,6 +6709,21 @@ snapshots:
|
||||||
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
react-native: 0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0)
|
||||||
warn-once: 0.1.1
|
warn-once: 0.1.1
|
||||||
|
|
||||||
|
react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.29.2
|
||||||
|
'@react-native/normalize-colors': 0.74.89
|
||||||
|
fbjs: 3.0.5
|
||||||
|
inline-style-prefixer: 7.0.1
|
||||||
|
memoize-one: 6.0.0
|
||||||
|
nullthrows: 1.1.1
|
||||||
|
postcss-value-parser: 4.2.0
|
||||||
|
react: 19.1.0
|
||||||
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
styleq: 0.1.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
|
||||||
react-native-worklets@0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
react-native-worklets@0.5.1(@babel/core@7.29.0)(react-native@0.81.5(@babel/core@7.29.0)(@react-native/metro-config@0.84.1(@babel/core@7.29.0))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.0
|
'@babel/core': 7.29.0
|
||||||
|
|
@ -6729,8 +6874,6 @@ snapshots:
|
||||||
|
|
||||||
scheduler@0.26.0: {}
|
scheduler@0.26.0: {}
|
||||||
|
|
||||||
scheduler@0.27.0: {}
|
|
||||||
|
|
||||||
semver@6.3.1: {}
|
semver@6.3.1: {}
|
||||||
|
|
||||||
semver@7.7.2: {}
|
semver@7.7.2: {}
|
||||||
|
|
@ -6766,6 +6909,8 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
setimmediate@1.0.5: {}
|
||||||
|
|
||||||
setprototypeof@1.2.0: {}
|
setprototypeof@1.2.0: {}
|
||||||
|
|
||||||
sf-symbols-typescript@2.2.0: {}
|
sf-symbols-typescript@2.2.0: {}
|
||||||
|
|
@ -6847,6 +6992,8 @@ snapshots:
|
||||||
|
|
||||||
structured-headers@0.4.1: {}
|
structured-headers@0.4.1: {}
|
||||||
|
|
||||||
|
styleq@0.1.3: {}
|
||||||
|
|
||||||
sucrase@3.35.1:
|
sucrase@3.35.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/gen-mapping': 0.3.13
|
'@jridgewell/gen-mapping': 0.3.13
|
||||||
|
|
@ -6958,6 +7105,8 @@ snapshots:
|
||||||
|
|
||||||
toidentifier@1.0.1: {}
|
toidentifier@1.0.1: {}
|
||||||
|
|
||||||
|
tr46@0.0.3: {}
|
||||||
|
|
||||||
ts-interface-checker@0.1.13: {}
|
ts-interface-checker@0.1.13: {}
|
||||||
|
|
||||||
type-detect@4.0.8: {}
|
type-detect@4.0.8: {}
|
||||||
|
|
@ -6968,6 +7117,8 @@ snapshots:
|
||||||
|
|
||||||
typescript@5.9.3: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
|
ua-parser-js@1.0.41: {}
|
||||||
|
|
||||||
undici-types@7.18.2: {}
|
undici-types@7.18.2: {}
|
||||||
|
|
||||||
undici@6.24.1: {}
|
undici@6.24.1: {}
|
||||||
|
|
@ -7023,6 +7174,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
defaults: 1.0.4
|
defaults: 1.0.4
|
||||||
|
|
||||||
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
webidl-conversions@5.0.0: {}
|
webidl-conversions@5.0.0: {}
|
||||||
|
|
||||||
whatwg-fetch@3.6.20: {}
|
whatwg-fetch@3.6.20: {}
|
||||||
|
|
@ -7033,6 +7186,11 @@ snapshots:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
webidl-conversions: 5.0.0
|
webidl-conversions: 5.0.0
|
||||||
|
|
||||||
|
whatwg-url@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
tr46: 0.0.3
|
||||||
|
webidl-conversions: 3.0.1
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 4.4 KiB |
57
VinEye/src/components/home/SearchHeader.tsx
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { View, TouchableOpacity, TextInput } from "react-native";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useNavigation } from "@react-navigation/native";
|
||||||
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
import { colors } from "@/theme/colors";
|
||||||
|
import type { RootStackParamList } from "@/types/navigation";
|
||||||
|
|
||||||
|
type Nav = NativeStackNavigationProp<RootStackParamList>;
|
||||||
|
|
||||||
|
export default function SearchHeader() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigation = useNavigation<Nav>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="flex-row items-center justify-between px-5 pt-3 pb-4">
|
||||||
|
<View className="flex-1 flex-row items-center gap-2">
|
||||||
|
<View className="flex-1 flex-row items-center rounded-full bg-neutral-200 px-3 py-2">
|
||||||
|
<Ionicons
|
||||||
|
name="search-outline"
|
||||||
|
size={18}
|
||||||
|
color={colors.neutral[500]}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
className="ml-2 flex-1 text-[14px]"
|
||||||
|
placeholder={t("history.search")}
|
||||||
|
placeholderTextColor={colors.neutral[500]}
|
||||||
|
style={{ color: colors.neutral[900], paddingVertical: 0 }}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
className="h-9 w-9 items-center justify-center rounded-full bg-neutral-200"
|
||||||
|
activeOpacity={0.7}
|
||||||
|
onPress={() => navigation.navigate("Notifications")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="notifications-outline"
|
||||||
|
size={20}
|
||||||
|
color={colors.neutral[800]}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
className="h-9 w-9 items-center justify-center rounded-full bg-white border border-neutral-200"
|
||||||
|
activeOpacity={0.7}
|
||||||
|
onPress={() => navigation.navigate("Settings")}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name="settings-outline"
|
||||||
|
size={20}
|
||||||
|
color={colors.neutral[900]}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,8 @@
|
||||||
import { useEffect } from "react";
|
import { View, TouchableOpacity } from "react-native";
|
||||||
import { View, ScrollView, TouchableOpacity, TextInput } from "react-native";
|
|
||||||
import { SafeAreaView } from "react-native-safe-area-context";
|
|
||||||
import { useNavigation } from "@react-navigation/native";
|
|
||||||
import type { BottomTabNavigationProp } from "@react-navigation/bottom-tabs";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
|
||||||
import Animated, {
|
|
||||||
useSharedValue,
|
|
||||||
useAnimatedStyle,
|
|
||||||
withRepeat,
|
|
||||||
withSequence,
|
|
||||||
withTiming,
|
|
||||||
} from "react-native-reanimated";
|
|
||||||
|
|
||||||
import { Text } from "@/components/ui/text";
|
import { Text } from "@/components/ui/text";
|
||||||
import { ProgressRing } from "@/components/gamification/ProgressRing";
|
|
||||||
import { ScanCard } from "@/components/history/ScanCard";
|
|
||||||
import { useGameProgress } from "@/hooks/useGameProgress";
|
|
||||||
import { useHistory } from "@/hooks/useHistory";
|
|
||||||
import { colors } from "@/theme/colors";
|
import { colors } from "@/theme/colors";
|
||||||
import {
|
|
||||||
getLevelForXP,
|
|
||||||
getLevelNumber,
|
|
||||||
getXPProgress,
|
|
||||||
} from "@/utils/achievements";
|
|
||||||
import type { BottomTabParamList } from "@/types/navigation";
|
|
||||||
import StatCard from "@/components/home/gamificationstat";
|
|
||||||
import StatisticsSection from "@/components/home/statssection";
|
|
||||||
|
|
||||||
export default function SectionHeader({
|
export default function SectionHeader({
|
||||||
title,
|
title,
|
||||||
|
|
@ -53,4 +29,4 @@ export default function SectionHeader({
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,10 @@
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
"retry": "Retry"
|
"retry": "Retry",
|
||||||
|
"map": "Map",
|
||||||
|
"notifications": "Notifications",
|
||||||
|
"settings": "Settings"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"greeting": "Hello, Winemaker!",
|
"greeting": "Hello, Winemaker!",
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,10 @@
|
||||||
"confirm": "Confirmer",
|
"confirm": "Confirmer",
|
||||||
"loading": "Chargement...",
|
"loading": "Chargement...",
|
||||||
"error": "Erreur",
|
"error": "Erreur",
|
||||||
"retry": "Réessayer"
|
"retry": "Réessayer",
|
||||||
|
"map": "Carte",
|
||||||
|
"notifications": "Notifications",
|
||||||
|
"settings": "Paramètres"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"greeting": "Bonjour, Vigneron !",
|
"greeting": "Bonjour, Vigneron !",
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,51 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import { View, Text, TouchableOpacity, Platform, LayoutAnimation, UIManager } from 'react-native';
|
import { View, Text, TouchableOpacity, Platform } from "react-native";
|
||||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useTranslation } from "react-i18next";
|
||||||
import { useTranslation } from 'react-i18next';
|
import * as Haptics from "expo-haptics";
|
||||||
import * as Haptics from 'expo-haptics';
|
import { House, ScanLine, MapPin } from "lucide-react-native";
|
||||||
|
|
||||||
// Imports de tes écrans
|
import HomeScreen from "@/screens/HomeScreen";
|
||||||
import HomeScreen from '@/screens/HomeScreen';
|
import ScannerScreen from "@/screens/ScannerScreen";
|
||||||
import ScannerScreen from '@/screens/ScannerScreen';
|
import MapScreen from "@/screens/MapScreen";
|
||||||
import HistoryScreen from '@/screens/HistoryScreen';
|
import { colors } from "@/theme/colors";
|
||||||
import ProfileScreen from '@/screens/ProfileScreen';
|
|
||||||
|
|
||||||
// Activation de LayoutAnimation pour Android
|
|
||||||
if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
|
|
||||||
UIManager.setLayoutAnimationEnabledExperimental(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator();
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
const TAB_ICONS: Record<string, any> = {
|
||||||
|
Home: House,
|
||||||
|
Map: MapPin,
|
||||||
|
};
|
||||||
|
|
||||||
function MyCustomTabBar({ state, descriptors, navigation }: any) {
|
function MyCustomTabBar({ state, descriptors, navigation }: any) {
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
// Gestion de la marge basse pour éviter la superposition avec la barre système
|
|
||||||
const safeBottom = Platform.OS === 'android' ? Math.max(insets.bottom, 24) : insets.bottom;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
className="absolute bg-white flex-row items-center justify-between px-2"
|
|
||||||
style={{
|
style={{
|
||||||
bottom: safeBottom + 10,
|
flexDirection: "row",
|
||||||
left: 20,
|
backgroundColor: colors.surface,
|
||||||
right: 20,
|
borderTopWidth: 1,
|
||||||
height: 70,
|
borderTopColor: colors.neutral[300],
|
||||||
borderRadius: 35,
|
paddingBottom: insets.bottom,
|
||||||
elevation: 12,
|
paddingTop: 8,
|
||||||
shadowColor: '#000',
|
alignItems: "flex-end",
|
||||||
shadowOffset: { width: 0, height: 10 },
|
|
||||||
shadowOpacity: 0.15,
|
|
||||||
shadowRadius: 20,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{state.routes.map((route: any, index: number) => {
|
{state.routes.map((route: any, index: number) => {
|
||||||
const { options } = descriptors[route.key];
|
const { options } = descriptors[route.key];
|
||||||
const isFocused = state.index === index;
|
const isFocused = state.index === index;
|
||||||
|
const label = options.tabBarLabel || route.name;
|
||||||
|
const isScanner = route.name === "Scanner";
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
// 1. Retour Haptique (Vibration légère "Impact")
|
if (Platform.OS !== "web") {
|
||||||
if (Platform.OS !== 'web') {
|
|
||||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Animation de la transition (Pill expansion)
|
|
||||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
||||||
|
|
||||||
const event = navigation.emit({
|
const event = navigation.emit({
|
||||||
type: 'tabPress',
|
type: "tabPress",
|
||||||
target: route.key,
|
target: route.key,
|
||||||
canPreventDefault: true,
|
canPreventDefault: true,
|
||||||
});
|
});
|
||||||
|
|
@ -66,48 +55,80 @@ function MyCustomTabBar({ state, descriptors, navigation }: any) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Choix de l'icône (Outline vs Solid)
|
// FAB central pour Scanner
|
||||||
const getIcon = (name: string, focused: boolean) => {
|
if (isScanner) {
|
||||||
switch (name) {
|
return (
|
||||||
case 'Home': return focused ? 'home' : 'home-outline';
|
<TouchableOpacity
|
||||||
case 'History': return focused ? 'receipt' : 'receipt-outline';
|
key={route.key}
|
||||||
case 'Scanner': return focused ? 'scan' : 'scan-outline';
|
onPress={onPress}
|
||||||
case 'Profile': return focused ? 'person' : 'person-outline';
|
activeOpacity={0.8}
|
||||||
default: return 'help-outline';
|
accessibilityRole="button"
|
||||||
}
|
accessibilityLabel={label}
|
||||||
};
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
borderRadius: 28,
|
||||||
|
backgroundColor: colors.primary[800],
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
marginTop: -28,
|
||||||
|
shadowColor: colors.primary[900],
|
||||||
|
shadowOffset: { width: 0, height: 4 },
|
||||||
|
shadowOpacity: 0.3,
|
||||||
|
shadowRadius: 8,
|
||||||
|
elevation: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ScanLine size={26} color="#FFFFFF" />
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const label = options.tabBarLabel || route.name;
|
// Onglets classiques (Home, Map)
|
||||||
|
const Icon = TAB_ICONS[route.name];
|
||||||
|
const tintColor = isFocused ? colors.primary[700] : colors.neutral[400];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
key={index}
|
key={route.key}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
activeOpacity={0.7}
|
activeOpacity={0.7}
|
||||||
style={{ flex: isFocused ? 2 : 1 }}
|
accessibilityRole="button"
|
||||||
className="items-center justify-center h-full"
|
accessibilityState={isFocused ? { selected: true } : {}}
|
||||||
|
accessibilityLabel={label}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingVertical: 6,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<View
|
{Icon && (
|
||||||
className={`flex-row items-center justify-center py-2.5 ${
|
<Icon
|
||||||
isFocused ? 'bg-gray-900 px-5' : 'bg-transparent px-0'
|
size={22}
|
||||||
}`}
|
color={tintColor}
|
||||||
style={{ borderRadius: 999 }}
|
strokeWidth={isFocused ? 2.5 : 1.8}
|
||||||
>
|
|
||||||
<Ionicons
|
|
||||||
name={getIcon(route.name, isFocused) as any}
|
|
||||||
size={22}
|
|
||||||
color={isFocused ? '#FFFFFF' : '#9CA3AF'}
|
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
{isFocused && (
|
<Text
|
||||||
<Text
|
numberOfLines={1}
|
||||||
numberOfLines={1}
|
style={{
|
||||||
className="ml-2 text-white font-bold text-[13px]"
|
fontSize: 11,
|
||||||
>
|
marginTop: 4,
|
||||||
{label}
|
color: tintColor,
|
||||||
</Text>
|
fontWeight: isFocused ? "600" : "400",
|
||||||
)}
|
}}
|
||||||
</View>
|
>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
@ -123,26 +144,21 @@ export default function BottomTabNavigator() {
|
||||||
tabBar={(props) => <MyCustomTabBar {...props} />}
|
tabBar={(props) => <MyCustomTabBar {...props} />}
|
||||||
screenOptions={{ headerShown: false }}
|
screenOptions={{ headerShown: false }}
|
||||||
>
|
>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Home"
|
name="Home"
|
||||||
component={HomeScreen}
|
component={HomeScreen}
|
||||||
options={{ tabBarLabel: t('common.home') }}
|
options={{ tabBarLabel: t("common.home") }}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="History"
|
name="Scanner"
|
||||||
component={HistoryScreen}
|
component={ScannerScreen}
|
||||||
options={{ tabBarLabel: t('common.history') }}
|
options={{ tabBarLabel: t("common.scan") }}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Scanner"
|
name="Map"
|
||||||
component={ScannerScreen}
|
component={MapScreen}
|
||||||
options={{ tabBarLabel: 'Scan' }}
|
options={{ tabBarLabel: t("common.map") }}
|
||||||
/>
|
|
||||||
<Tab.Screen
|
|
||||||
name="Profile"
|
|
||||||
component={ProfileScreen}
|
|
||||||
options={{ tabBarLabel: t('common.profile') }}
|
|
||||||
/>
|
/>
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import { NavigationContainer } from '@react-navigation/native';
|
||||||
|
|
||||||
import SplashScreen from '@/screens/SplashScreen';
|
import SplashScreen from '@/screens/SplashScreen';
|
||||||
import ResultScreen from '@/screens/ResultScreen';
|
import ResultScreen from '@/screens/ResultScreen';
|
||||||
|
import HistoryScreen from '@/screens/HistoryScreen';
|
||||||
|
import ProfileScreen from '@/screens/ProfileScreen';
|
||||||
import BottomTabNavigator from './BottomTabNavigator';
|
import BottomTabNavigator from './BottomTabNavigator';
|
||||||
import linking from './linking';
|
import linking from './linking';
|
||||||
import type { RootStackParamList } from '@/types/navigation';
|
import type { RootStackParamList } from '@/types/navigation';
|
||||||
|
|
@ -23,6 +25,16 @@ export default function RootNavigator() {
|
||||||
component={ResultScreen}
|
component={ResultScreen}
|
||||||
options={{ animation: 'slide_from_bottom', presentation: 'modal' }}
|
options={{ animation: 'slide_from_bottom', presentation: 'modal' }}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Notifications"
|
||||||
|
component={HistoryScreen}
|
||||||
|
options={{ animation: 'slide_from_right' }}
|
||||||
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Settings"
|
||||||
|
component={ProfileScreen}
|
||||||
|
options={{ animation: 'slide_from_right' }}
|
||||||
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@ const linking: LinkingOptions<RootStackParamList> = {
|
||||||
screens: {
|
screens: {
|
||||||
Home: 'home',
|
Home: 'home',
|
||||||
Scanner: 'scan',
|
Scanner: 'scan',
|
||||||
History: 'history',
|
Map: 'map',
|
||||||
Profile: 'profile',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Result: 'result',
|
Result: 'result',
|
||||||
|
Notifications: 'notifications',
|
||||||
|
Settings: 'settings',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { useEffect } from "react";
|
||||||
import { View, ScrollView, TouchableOpacity, TextInput } from "react-native";
|
import { View, ScrollView, TouchableOpacity, TextInput } from "react-native";
|
||||||
import { SafeAreaView } from "react-native-safe-area-context";
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import type { BottomTabNavigationProp } from "@react-navigation/bottom-tabs";
|
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import Animated, {
|
import Animated, {
|
||||||
|
|
@ -24,13 +24,14 @@ import {
|
||||||
getLevelNumber,
|
getLevelNumber,
|
||||||
getXPProgress,
|
getXPProgress,
|
||||||
} from "@/utils/achievements";
|
} from "@/utils/achievements";
|
||||||
import type { BottomTabParamList } from "@/types/navigation";
|
import type { RootStackParamList } from "@/types/navigation";
|
||||||
import StatCard from "@/components/home/gamificationstat";
|
import StatCard from "@/components/home/gamificationstat";
|
||||||
import StatisticsSection from "@/components/home/statssection";
|
import StatisticsSection from "@/components/home/statssection";
|
||||||
|
import SearchHeader from "@/components/home/SearchHeader";
|
||||||
import SectionHeader from "@/components/home/components/homeheader";
|
import SectionHeader from "@/components/home/components/homeheader";
|
||||||
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
||||||
|
|
||||||
type HomeNav = BottomTabNavigationProp<BottomTabParamList, "Home">;
|
type HomeNav = NativeStackNavigationProp<RootStackParamList>;
|
||||||
|
|
||||||
interface GameProgress {
|
interface GameProgress {
|
||||||
totalScans: number;
|
totalScans: number;
|
||||||
|
|
@ -116,37 +117,10 @@ export default function HomeScreen() {
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
paddingBottom: 130, // La hauteur de ta barre (70) + le margin bas (~34) + de l'espace pour respirer (26)
|
paddingBottom: 24,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Header — title left, icons right */}
|
<SearchHeader />
|
||||||
<View className="flex-row items-center justify-between px-5 pt-3 pb-4">
|
|
||||||
<View className="flex-1 flex-row items-center gap-2">
|
|
||||||
<View className="flex-1 flex-row items-center rounded-full bg-neutral-200 px-3 py-2">
|
|
||||||
<Ionicons
|
|
||||||
name="search-outline"
|
|
||||||
size={18}
|
|
||||||
color={colors.neutral[500]}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
className="ml-2 flex-1 text-[14px]"
|
|
||||||
placeholder={t("history.search")}
|
|
||||||
placeholderTextColor={colors.neutral[500]}
|
|
||||||
style={{ color: colors.neutral[900], paddingVertical: 0 }}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<TouchableOpacity
|
|
||||||
className="h-9 w-9 items-center justify-center rounded-full bg-neutral-200"
|
|
||||||
activeOpacity={0.7}
|
|
||||||
>
|
|
||||||
<Ionicons
|
|
||||||
name="add-outline"
|
|
||||||
size={22}
|
|
||||||
color={colors.neutral[800]}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<StatisticsSection progress={userProgress} />
|
<StatisticsSection progress={userProgress} />
|
||||||
|
|
||||||
|
|
@ -204,7 +178,7 @@ export default function HomeScreen() {
|
||||||
<View className="mx-5 mb-6 gap-2">
|
<View className="mx-5 mb-6 gap-2">
|
||||||
<SectionHeader
|
<SectionHeader
|
||||||
title={t("home.lastScan")}
|
title={t("home.lastScan")}
|
||||||
onViewAll={() => navigation.navigate("History")}
|
onViewAll={() => navigation.navigate("Notifications")}
|
||||||
/>
|
/>
|
||||||
<ScanCard record={lastScan} />
|
<ScanCard record={lastScan} />
|
||||||
</View>
|
</View>
|
||||||
|
|
|
||||||
30
VinEye/src/screens/MapScreen.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { View } from "react-native";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
|
import { Text } from "@/components/ui/text";
|
||||||
|
import { colors } from "@/theme/colors";
|
||||||
|
|
||||||
|
export default function MapScreen() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView className="flex-1 bg-[#FAFAFA]" edges={["top"]}>
|
||||||
|
<View className="flex-1 items-center justify-center px-8">
|
||||||
|
<View
|
||||||
|
className="mb-6 h-20 w-20 items-center justify-center rounded-full"
|
||||||
|
style={{ backgroundColor: colors.primary[100] }}
|
||||||
|
>
|
||||||
|
<Ionicons name="map-outline" size={36} color={colors.primary[700]} />
|
||||||
|
</View>
|
||||||
|
<Text className="mb-2 text-xl font-semibold" style={{ color: colors.neutral[900] }}>
|
||||||
|
{t("common.map")}
|
||||||
|
</Text>
|
||||||
|
<Text className="text-center text-sm" style={{ color: colors.neutral[500] }}>
|
||||||
|
Coming soon
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { View, Text, StyleSheet } from 'react-native';
|
import { View, Text, Image, StyleSheet } from 'react-native';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import { colors } from '@/theme/colors';
|
import { colors } from '@/theme/colors';
|
||||||
|
|
@ -21,9 +21,13 @@ export default function SplashScreen() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.leafEmoji}>🍃</Text>
|
<Image
|
||||||
<Text style={styles.logo}>VinEye</Text>
|
source={require('@/assets/images/icon.png')}
|
||||||
<Text style={styles.subtitle}>Détection de vignes par IA</Text>
|
style={styles.logoImage}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
{/* <Text style={styles.logo}>VinEye</Text>
|
||||||
|
<Text style={styles.subtitle}>Détection de vignes par IA</Text> */}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -31,12 +35,15 @@ export default function SplashScreen() {
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: colors.primary[900],
|
backgroundColor: colors.surface,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
gap: 24,
|
|
||||||
|
},
|
||||||
|
logoImage: {
|
||||||
|
width: 198,
|
||||||
|
height: 198,
|
||||||
},
|
},
|
||||||
leafEmoji: { fontSize: 80 },
|
|
||||||
logo: {
|
logo: {
|
||||||
fontSize: typography.fontSizes['4xl'],
|
fontSize: typography.fontSizes['4xl'],
|
||||||
fontWeight: typography.fontWeights.extrabold,
|
fontWeight: typography.fontWeights.extrabold,
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ export type RootStackParamList = {
|
||||||
Splash: undefined;
|
Splash: undefined;
|
||||||
Main: undefined;
|
Main: undefined;
|
||||||
Result: { detection: Detection };
|
Result: { detection: Detection };
|
||||||
|
Notifications: undefined;
|
||||||
|
Settings: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BottomTabParamList = {
|
export type BottomTabParamList = {
|
||||||
Home: undefined;
|
Home: undefined;
|
||||||
Scanner: undefined;
|
Scanner: undefined;
|
||||||
History: undefined;
|
Map: undefined;
|
||||||
Profile: undefined;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||