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,18 @@
// Copyright 2018-present 650 Industries. All rights reserved.
#import <ExpoModulesCore/EXExportedModule.h>
#import <ExpoModulesCore/EXEventEmitter.h>
#import <ExpoModulesCore/EXModuleRegistryConsumer.h>
#import <ExpoModulesCore/EXEventEmitterService.h>
#import <EXNotifications/EXNotificationsDelegate.h>
static NSString * const onDidReceiveNotification = @"onDidReceiveNotification";
static NSString * const onDidReceiveNotificationResponse = @"onDidReceiveNotificationResponse";
static NSString * const onDidClearNotificationResponse = @"onDidClearNotificationResponse";
@interface EXNotificationsEmitter : EXExportedModule <EXEventEmitter, EXModuleRegistryConsumer, EXNotificationsDelegate>
@property (nonatomic, weak, readonly) id<EXEventEmitterService> eventEmitter;
@end

View File

@@ -0,0 +1,120 @@
// Copyright 2018-present 650 Industries. All rights reserved.
#import <EXNotifications/EXNotificationsEmitter.h>
#import <EXNotifications/EXNotificationSerializer.h>
#import <EXNotifications/EXNotificationCenterDelegate.h>
#import <ExpoModulesCore/EXEventEmitterService.h>
@interface EXNotificationsEmitter ()
@property (nonatomic, weak) id<EXNotificationCenterDelegate> notificationCenterDelegate;
@property (nonatomic, assign) BOOL isBeingObserved;
@property (nonatomic, assign) BOOL isListening;
@property (nonatomic, weak) id<EXEventEmitterService> eventEmitter;
@end
@implementation EXNotificationsEmitter
EX_EXPORT_MODULE(ExpoNotificationsEmitter);
EX_EXPORT_METHOD_AS(getLastNotificationResponseAsync,
getLastNotificationResponseAsyncWithResolver:(EXPromiseResolveBlock)resolve reject:(EXPromiseRejectBlock)reject)
{
UNNotificationResponse* lastResponse = _notificationCenterDelegate.lastNotificationResponse;
resolve(lastResponse ? [self serializedNotificationResponse:lastResponse] : [NSNull null]);
}
EX_EXPORT_METHOD_AS(clearLastNotificationResponseAsync,
clearLastNotificationResponseAsyncWithResolver:(EXPromiseResolveBlock)resolve reject:(EXPromiseRejectBlock)reject)
{
_notificationCenterDelegate.lastNotificationResponse = nil;
resolve([NSNull null]);
}
# pragma mark - EXModuleRegistryConsumer
- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
{
_eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)];
_notificationCenterDelegate = [moduleRegistry getSingletonModuleForName:@"NotificationCenterDelegate"];
}
# pragma mark - EXEventEmitter
- (NSArray<NSString *> *)supportedEvents
{
return @[onDidReceiveNotification, onDidReceiveNotificationResponse, onDidClearNotificationResponse];
}
- (void)startObserving
{
[self setIsBeingObserved:YES];
}
- (void)stopObserving
{
[self setIsBeingObserved:NO];
}
- (void)setIsBeingObserved:(BOOL)isBeingObserved
{
_isBeingObserved = isBeingObserved;
BOOL shouldListen = _isBeingObserved;
if (shouldListen && !_isListening) {
[_notificationCenterDelegate addDelegate:self];
_isListening = YES;
} else if (!shouldListen && _isListening) {
[_notificationCenterDelegate removeDelegate:self];
_isListening = NO;
}
}
# pragma mark - EXNotificationsDelegate
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
// Background task execution would happen here.
completionHandler(UIBackgroundFetchResultNoData);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
_notificationCenterDelegate.lastNotificationResponse = response;
[self sendEventWithName:onDidReceiveNotificationResponse body:[self serializedNotificationResponse:response]];
completionHandler();
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
[self sendEventWithName:onDidReceiveNotification body:[self serializedNotification:notification]];
completionHandler(UNNotificationPresentationOptionNone);
}
- (void)sendEventWithName:(NSString *)eventName body:(id)body
{
// Silence React Native warning: "Sending ... with no listeners registered."
// See: https://github.com/expo/expo/pull/10883#pullrequestreview-529183413
// While in practice we don't need to verify this, as as of the end of 2020
// we wouldn't send any event to JS if we weren't being observed because
// we wouldn't be subscribed to the notification center delegate it's nice
// to be sure this problem won't ever arise.
if (_isBeingObserved) {
[_eventEmitter sendEventWithName:eventName body:body];
}
}
- (NSDictionary *)serializedNotification:(UNNotification *)notification
{
return [EXNotificationSerializer serializedNotification:notification];
}
- (NSDictionary *)serializedNotificationResponse:(UNNotificationResponse *)notificationResponse
{
return [EXNotificationSerializer serializedNotificationResponse:notificationResponse];
}
@end