feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,29 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_1 = require("@expo/config");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const possibleProjectRoot = process.argv[2];
const destinationDir = process.argv[3];
// TODO: Verify we can remove projectRoot validation, now that we no longer
// support React Native <= 62
let projectRoot;
if (fs_1.default.existsSync(path_1.default.join(possibleProjectRoot, 'package.json'))) {
projectRoot = possibleProjectRoot;
}
else if (fs_1.default.existsSync(path_1.default.join(possibleProjectRoot, '..', 'package.json'))) {
projectRoot = path_1.default.resolve(possibleProjectRoot, '..');
}
else {
throw new Error(`Unable to locate project (no package.json found) at path: ${possibleProjectRoot}`);
}
require('@expo/env').load(projectRoot);
process.chdir(projectRoot);
const { exp } = (0, config_1.getConfig)(projectRoot, {
isPublicConfig: true,
skipSDKVersionRequirement: true,
});
fs_1.default.writeFileSync(path_1.default.join(destinationDir, 'app.config'), JSON.stringify(exp));

View File

@@ -0,0 +1,44 @@
// Gradle script for generating serialized public app config (from app.config.js/ts or app.json) and bundling it into the APK
import org.apache.tools.ant.taskdefs.condition.Os
def expoConstantsDir = project.providers.exec {
workingDir(projectDir)
commandLine("node", "-e", "console.log(require('path').dirname(require.resolve('expo-constants/package.json')));")
}.standardOutput.asText.get().trim()
def config = project.hasProperty("react") ? project.react : [];
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
afterEvaluate {
def projectRoot = file("${rootProject.projectDir}")
def assetsDir = file("$buildDir/generated/assets/expo-constants")
def currentCreateConfigTask = tasks.register('createExpoConfig', Exec) {
description = 'expo-constants: Create app.config.'
doFirst {
assetsDir.deleteDir()
assetsDir.mkdirs()
}
// Add generated assetsDir into assets.srcDirs
project.android.sourceSets.main.assets.srcDirs += assetsDir
// Set up outputs so gradle can cache the result
outputs.dir assetsDir
// Switch to project root and generate the app config
workingDir projectRoot
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine("cmd", "/c", *nodeExecutableAndArgs, "$expoConstantsDir/scripts/getAppConfig.js", projectRoot, assetsDir)
} else {
commandLine(*nodeExecutableAndArgs, "$expoConstantsDir/scripts/getAppConfig.js", projectRoot, assetsDir)
}
}
// Generate app.config at preBuild
tasks.getByName('preBuild').dependsOn(currentCreateConfigTask)
}

View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -eo pipefail
DEST="$CONFIGURATION_BUILD_DIR"
RESOURCE_BUNDLE_NAME="EXConstants.bundle"
EXPO_CONSTANTS_PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
# For classic main project build phases integration, will be no-op to prevent duplicated app.config creation.
#
# `$PROJECT_DIR` is passed by Xcode as the directory to the xcodeproj file.
# in classic main project setup it is something like /path/to/app/ios
# in new style pod project setup it is something like /path/to/app/ios/Pods
PROJECT_DIR_BASENAME=$(basename $PROJECT_DIR)
if [ "x$PROJECT_DIR_BASENAME" != "xPods" ]; then
exit 0
fi
# If PROJECT_ROOT is not specified, fallback to use Xcode PROJECT_DIR
PROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR/../.."}
PROJECT_ROOT=${PROJECT_ROOT:-"$EXPO_CONSTANTS_PACKAGE_DIR/../.."}
cd "$PROJECT_ROOT" || exit
if [ "$BUNDLE_FORMAT" == "shallow" ]; then
RESOURCE_DEST="$DEST/$RESOURCE_BUNDLE_NAME"
elif [ "$BUNDLE_FORMAT" == "deep" ]; then
RESOURCE_DEST="$DEST/$RESOURCE_BUNDLE_NAME/Contents/Resources"
mkdir -p "$RESOURCE_DEST"
else
echo "Unsupported bundle format: $BUNDLE_FORMAT"
exit 1
fi
"${EXPO_CONSTANTS_PACKAGE_DIR}/scripts/with-node.sh" "${EXPO_CONSTANTS_PACKAGE_DIR}/scripts/getAppConfig.js" "$PROJECT_ROOT" "$RESOURCE_DEST"

View File

@@ -0,0 +1 @@
require('./build/getAppConfig');

View File

@@ -0,0 +1 @@
module.exports = require('expo-module-scripts/jest-preset-scripts');

View File

@@ -0,0 +1,28 @@
import { getConfig } from '@expo/config';
import fs from 'fs';
import path from 'path';
const possibleProjectRoot = process.argv[2];
const destinationDir = process.argv[3];
// TODO: Verify we can remove projectRoot validation, now that we no longer
// support React Native <= 62
let projectRoot;
if (fs.existsSync(path.join(possibleProjectRoot, 'package.json'))) {
projectRoot = possibleProjectRoot;
} else if (fs.existsSync(path.join(possibleProjectRoot, '..', 'package.json'))) {
projectRoot = path.resolve(possibleProjectRoot, '..');
} else {
throw new Error(
`Unable to locate project (no package.json found) at path: ${possibleProjectRoot}`
);
}
require('@expo/env').load(projectRoot);
process.chdir(projectRoot);
const { exp } = getConfig(projectRoot, {
isPublicConfig: true,
skipSDKVersionRequirement: true,
});
fs.writeFileSync(path.join(destinationDir, 'app.config'), JSON.stringify(exp));

View File

@@ -0,0 +1,9 @@
{
"extends": "expo-module-scripts/tsconfig.plugin",
"compilerOptions": {
"outDir": "build",
"rootDir": "src"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}

View File

@@ -0,0 +1,44 @@
#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# Copyright 2018-present 650 Industries. All rights reserved.
#
# @generated by expo-module-scripts
#
# USAGE:
# ./with-node.sh command
CURR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
# Start with a default
NODE_BINARY=$(command -v node)
export NODE_BINARY
# Override the default with the global environment
ENV_PATH="$PODS_ROOT/../.xcode.env"
if [[ -f "$ENV_PATH" ]]; then
source "$ENV_PATH"
fi
# Override the global with the local environment
LOCAL_ENV_PATH="${ENV_PATH}.local"
if [[ -f "$LOCAL_ENV_PATH" ]]; then
source "$LOCAL_ENV_PATH"
fi
if [[ -n "$NODE_BINARY" && -x "$NODE_BINARY" ]]; then
echo "Node found at: ${NODE_BINARY}"
else
cat >&2 << EOF
[ERROR] Could not find "node" while running an Xcode build script. You need to specify the path to your Node.js executable by defining an environment variable named NODE_BINARY in your project's .xcode.env or .xcode.env.local file. You can set this up quickly by running:
echo "export NODE_BINARY=\$(command -v node)" >> .xcode.env
in the ios folder of your project.
EOF
exit 1
fi
# Execute argument, if present
if [[ "$#" -gt 0 ]]; then
"$NODE_BINARY" "$@"
fi