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,42 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<8509d5ee87efb5aa8da7efcd2085d0a2>>
* @flow strict-local
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
*/
import type {TurboModule} from '../../../Libraries/TurboModule/RCTExport';
import * as TurboModuleRegistry from '../../../Libraries/TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
+commonTestFlag?: () => boolean;
+enableBackgroundExecutor?: () => boolean;
+useModernRuntimeScheduler?: () => boolean;
+enableMicrotasks?: () => boolean;
+batchRenderingUpdatesInEventLoop?: () => boolean;
+enableSpannableBuildingUnification?: () => boolean;
+enableCustomDrawOrderFabric?: () => boolean;
+enableFixForClippedSubviewsCrash?: () => boolean;
+inspectorEnableCxxInspectorPackagerConnection?: () => boolean;
+inspectorEnableModernCDPRegistry?: () => boolean;
}
const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get<Spec>(
'NativeReactNativeFeatureFlagsCxx',
);
export default NativeReactNativeFeatureFlags;

View File

@@ -0,0 +1,140 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7c83d5613c3be517efe48378e6356e79>>
* @flow strict-local
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
*/
import {
type Getter,
createJavaScriptFlagGetter,
createNativeFlagGetter,
setOverrides,
} from './ReactNativeFeatureFlagsBase';
export type ReactNativeFeatureFlagsJsOnly = {
jsOnlyTestFlag: Getter<boolean>,
isLayoutAnimationEnabled: Getter<boolean>,
animatedShouldDebounceQueueFlush: Getter<boolean>,
animatedShouldUseSingleOp: Getter<boolean>,
enableAccessToHostTreeInFabric: Getter<boolean>,
shouldUseAnimatedObjectForTransform: Getter<boolean>,
shouldUseSetNativePropsInFabric: Getter<boolean>,
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean>,
};
export type ReactNativeFeatureFlagsJsOnlyOverrides = Partial<ReactNativeFeatureFlagsJsOnly>;
export type ReactNativeFeatureFlags = {
...ReactNativeFeatureFlagsJsOnly,
commonTestFlag: Getter<boolean>,
enableBackgroundExecutor: Getter<boolean>,
useModernRuntimeScheduler: Getter<boolean>,
enableMicrotasks: Getter<boolean>,
batchRenderingUpdatesInEventLoop: Getter<boolean>,
enableSpannableBuildingUnification: Getter<boolean>,
enableCustomDrawOrderFabric: Getter<boolean>,
enableFixForClippedSubviewsCrash: Getter<boolean>,
inspectorEnableCxxInspectorPackagerConnection: Getter<boolean>,
inspectorEnableModernCDPRegistry: Getter<boolean>,
}
/**
* JS-only flag for testing. Do NOT modify.
*/
export const jsOnlyTestFlag: Getter<boolean> = createJavaScriptFlagGetter('jsOnlyTestFlag', false);
/**
* Function used to enable / disabled Layout Animations in React Native.
*/
export const isLayoutAnimationEnabled: Getter<boolean> = createJavaScriptFlagGetter('isLayoutAnimationEnabled', true);
/**
* Enables an experimental flush-queue debouncing in Animated.js.
*/
export const animatedShouldDebounceQueueFlush: Getter<boolean> = createJavaScriptFlagGetter('animatedShouldDebounceQueueFlush', false);
/**
* Enables an experimental mega-operation for Animated.js that replaces many calls to native with a single call into native, to reduce JSI/JNI traffic.
*/
export const animatedShouldUseSingleOp: Getter<boolean> = createJavaScriptFlagGetter('animatedShouldUseSingleOp', false);
/**
* Enables access to the host tree in Fabric using DOM-compatible APIs.
*/
export const enableAccessToHostTreeInFabric: Getter<boolean> = createJavaScriptFlagGetter('enableAccessToHostTreeInFabric', false);
/**
* Enables use of AnimatedObject for animating transform values.
*/
export const shouldUseAnimatedObjectForTransform: Getter<boolean> = createJavaScriptFlagGetter('shouldUseAnimatedObjectForTransform', false);
/**
* Enables use of setNativeProps in JS driven animations.
*/
export const shouldUseSetNativePropsInFabric: Getter<boolean> = createJavaScriptFlagGetter('shouldUseSetNativePropsInFabric', true);
/**
* removeClippedSubviews prop will be used as the default in FlatList on iOS to match Android
*/
export const shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean> = createJavaScriptFlagGetter('shouldUseRemoveClippedSubviewsAsDefaultOnIOS', false);
/**
* Common flag for testing. Do NOT modify.
*/
export const commonTestFlag: Getter<boolean> = createNativeFlagGetter('commonTestFlag', false);
/**
* Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).
*/
export const enableBackgroundExecutor: Getter<boolean> = createNativeFlagGetter('enableBackgroundExecutor', false);
/**
* When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.
*/
export const useModernRuntimeScheduler: Getter<boolean> = createNativeFlagGetter('useModernRuntimeScheduler', false);
/**
* Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).
*/
export const enableMicrotasks: Getter<boolean> = createNativeFlagGetter('enableMicrotasks', false);
/**
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
*/
export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false);
/**
* Uses new, deduplicated logic for constructing Android Spannables from text fragments
*/
export const enableSpannableBuildingUnification: Getter<boolean> = createNativeFlagGetter('enableSpannableBuildingUnification', false);
/**
* When enabled, Fabric will use customDrawOrder in ReactViewGroup (similar to old architecture).
*/
export const enableCustomDrawOrderFabric: Getter<boolean> = createNativeFlagGetter('enableCustomDrawOrderFabric', false);
/**
* Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix
*/
export const enableFixForClippedSubviewsCrash: Getter<boolean> = createNativeFlagGetter('enableFixForClippedSubviewsCrash', false);
/**
* Flag determining if the C++ implementation of InspectorPackagerConnection should be used instead of the per-platform one. This flag is global and should not be changed across React Host lifetimes.
*/
export const inspectorEnableCxxInspectorPackagerConnection: Getter<boolean> = createNativeFlagGetter('inspectorEnableCxxInspectorPackagerConnection', false);
/**
* Flag determining if the modern CDP backend should be enabled. This flag is global and should not be changed across React Host lifetimes.
*/
export const inspectorEnableModernCDPRegistry: Getter<boolean> = createNativeFlagGetter('inspectorEnableModernCDPRegistry', false);
/**
* Overrides the feature flags with the provided methods.
* NOTE: Only JS-only flags can be overridden from JavaScript using this API.
*/
export const override = setOverrides;

View File

@@ -0,0 +1,84 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import type {
ReactNativeFeatureFlagsJsOnly,
ReactNativeFeatureFlagsJsOnlyOverrides,
} from './ReactNativeFeatureFlags';
import NativeReactNativeFeatureFlags from './NativeReactNativeFeatureFlags';
const accessedFeatureFlags: Set<string> = new Set();
let overrides: ?ReactNativeFeatureFlagsJsOnlyOverrides;
export type Getter<T> = () => T;
function createGetter<T: boolean | number | string>(
configName: string,
customValueGetter: Getter<?T>,
defaultValue: T,
): Getter<T> {
let cachedValue: ?T;
return () => {
if (cachedValue == null) {
accessedFeatureFlags.add(configName);
cachedValue = customValueGetter() ?? defaultValue;
}
return cachedValue;
};
}
export function createJavaScriptFlagGetter<
K: $Keys<ReactNativeFeatureFlagsJsOnly>,
>(
configName: K,
defaultValue: ReturnType<ReactNativeFeatureFlagsJsOnly[K]>,
): Getter<ReturnType<ReactNativeFeatureFlagsJsOnly[K]>> {
return createGetter(
configName,
() => overrides?.[configName]?.(),
defaultValue,
);
}
type NativeFeatureFlags = $NonMaybeType<typeof NativeReactNativeFeatureFlags>;
export function createNativeFlagGetter<K: $Keys<NativeFeatureFlags>>(
configName: K,
defaultValue: ReturnType<$NonMaybeType<NativeFeatureFlags[K]>>,
): Getter<ReturnType<$NonMaybeType<NativeFeatureFlags[K]>>> {
return createGetter(
configName,
() => NativeReactNativeFeatureFlags?.[configName]?.(),
defaultValue,
);
}
export function getOverrides(): ?ReactNativeFeatureFlagsJsOnlyOverrides {
return overrides;
}
export function setOverrides(
newOverrides: ReactNativeFeatureFlagsJsOnlyOverrides,
): void {
if (overrides != null) {
throw new Error('Feature flags cannot be overridden more than once');
}
if (accessedFeatureFlags.size > 0) {
const accessedFeatureFlagsStr = Array.from(accessedFeatureFlags).join(', ');
throw new Error(
`Feature flags were accessed before being overridden: ${accessedFeatureFlagsStr}`,
);
}
overrides = newOverrides;
}

View File

@@ -0,0 +1,92 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall react_native
*/
describe('ReactNativeFeatureFlags', () => {
beforeEach(() => {
jest.resetModules();
});
it('should provide default values for common flags if the native module is NOT available', () => {
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
expect(ReactNativeFeatureFlags.commonTestFlag()).toBe(false);
});
it('should access and cache common flags from the native module if it is available', () => {
const commonTestFlagFn = jest.fn(() => true);
jest.doMock('../NativeReactNativeFeatureFlags', () => ({
__esModule: true,
default: {
commonTestFlag: commonTestFlagFn,
},
}));
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
expect(commonTestFlagFn).toHaveBeenCalledTimes(0);
expect(ReactNativeFeatureFlags.commonTestFlag()).toBe(true);
expect(commonTestFlagFn).toHaveBeenCalledTimes(1);
expect(ReactNativeFeatureFlags.commonTestFlag()).toBe(true);
expect(commonTestFlagFn).toHaveBeenCalledTimes(1);
});
it('should provide default values for JS-only flags', () => {
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
expect(ReactNativeFeatureFlags.jsOnlyTestFlag()).toBe(false);
});
it('should access and cache overridden JS-only flags', () => {
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
const jsOnlyTestFlagFn = jest.fn(() => true);
ReactNativeFeatureFlags.override({
jsOnlyTestFlag: jsOnlyTestFlagFn,
});
expect(jsOnlyTestFlagFn).toHaveBeenCalledTimes(0);
expect(ReactNativeFeatureFlags.jsOnlyTestFlag()).toBe(true);
expect(jsOnlyTestFlagFn).toHaveBeenCalledTimes(1);
expect(ReactNativeFeatureFlags.jsOnlyTestFlag()).toBe(true);
expect(jsOnlyTestFlagFn).toHaveBeenCalledTimes(1);
});
it('should throw an error if any of the flags has been accessed before overridding', () => {
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
ReactNativeFeatureFlags.commonTestFlag();
expect(() =>
ReactNativeFeatureFlags.override({
jsOnlyTestFlag: () => true,
}),
).toThrow(
'Feature flags were accessed before being overridden: commonTestFlag',
);
});
it('should throw an error when trying to set overrides twice', () => {
const ReactNativeFeatureFlags = require('../ReactNativeFeatureFlags');
ReactNativeFeatureFlags.override({
jsOnlyTestFlag: () => true,
});
expect(() =>
ReactNativeFeatureFlags.override({
jsOnlyTestFlag: () => false,
}),
).toThrow('Feature flags cannot be overridden more than once');
});
});