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,52 @@
/*
* 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.
*/
#pragma once
#include <CoreFoundation/CFRunLoop.h>
#include <CoreFoundation/CoreFoundation.h>
#include <react/utils/RunLoopObserver.h>
namespace facebook::react {
/*
* Concrete iOS-specific implementation of `RunLoopObserver` using
* `CFRunLoopObserver` under the hood.
*/
class PlatformRunLoopObserver : public RunLoopObserver {
public:
PlatformRunLoopObserver(
RunLoopObserver::Activity activities,
const RunLoopObserver::WeakOwner& owner,
CFRunLoopRef runLoop);
~PlatformRunLoopObserver();
virtual bool isOnRunLoopThread() const noexcept override;
private:
void startObserving() const noexcept override;
void stopObserving() const noexcept override;
CFRunLoopRef runLoop_;
CFRunLoopObserverRef mainRunLoopObserver_;
};
/*
* Convenience specialization of `PlatformRunLoopObserver` observing the main
* run loop.
*/
class MainRunLoopObserver final : public PlatformRunLoopObserver {
public:
MainRunLoopObserver(
RunLoopObserver::Activity activities,
const RunLoopObserver::WeakOwner& owner)
: PlatformRunLoopObserver(activities, owner, CFRunLoopGetMain()) {}
};
} // namespace facebook::react

View File

@@ -0,0 +1,95 @@
/*
* 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.
*/
#import "PlatformRunLoopObserver.h"
#import <mutex>
namespace facebook::react {
static CFRunLoopActivity toCFRunLoopActivity(RunLoopObserver::Activity activity)
{
auto result = CFRunLoopActivity{};
if (RunLoopObserver::Activity(activity & RunLoopObserver::Activity::BeforeWaiting) ==
RunLoopObserver::Activity::BeforeWaiting) {
result = result | kCFRunLoopBeforeWaiting;
}
if (RunLoopObserver::Activity(activity & RunLoopObserver::Activity::AfterWaiting) ==
RunLoopObserver::Activity::AfterWaiting) {
result = result | kCFRunLoopAfterWaiting;
}
return result;
}
static RunLoopObserver::Activity toRunLoopActivity(CFRunLoopActivity activity)
{
auto result = RunLoopObserver::Activity{};
if (CFRunLoopActivity(activity & kCFRunLoopBeforeWaiting) == kCFRunLoopBeforeWaiting) {
result = RunLoopObserver::Activity(result | RunLoopObserver::Activity::BeforeWaiting);
}
if (CFRunLoopActivity(activity & kCFRunLoopAfterWaiting) == kCFRunLoopAfterWaiting) {
result = RunLoopObserver::Activity(result | RunLoopObserver::Activity::AfterWaiting);
}
return result;
}
PlatformRunLoopObserver::PlatformRunLoopObserver(
RunLoopObserver::Activity activities,
const RunLoopObserver::WeakOwner &owner,
CFRunLoopRef runLoop)
: RunLoopObserver(activities, owner), runLoop_(runLoop)
{
// A value (not a reference) to be captured by the block.
auto weakOwner = owner;
// The documentation for `CFRunLoop` family API states that all of the methods are thread-safe.
// See "Thread Safety and Run Loop Objects" section of the "Threading Programming Guide" for more details.
mainRunLoopObserver_ = CFRunLoopObserverCreateWithHandler(
NULL /* allocator */,
toCFRunLoopActivity(activities_) /* activities */,
true /* repeats */,
0 /* order */,
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
auto strongOwner = weakOwner.lock();
if (!strongOwner) {
return;
}
this->activityDidChange(toRunLoopActivity(activity));
});
assert(mainRunLoopObserver_);
}
PlatformRunLoopObserver::~PlatformRunLoopObserver()
{
stopObserving();
CFRelease(mainRunLoopObserver_);
}
void PlatformRunLoopObserver::startObserving() const noexcept
{
CFRunLoopAddObserver(runLoop_, mainRunLoopObserver_, kCFRunLoopCommonModes);
}
void PlatformRunLoopObserver::stopObserving() const noexcept
{
CFRunLoopRemoveObserver(runLoop_, mainRunLoopObserver_, kCFRunLoopCommonModes);
}
bool PlatformRunLoopObserver::isOnRunLoopThread() const noexcept
{
return CFRunLoopGetCurrent() == runLoop_;
}
} // namespace facebook::react

View File

@@ -0,0 +1,44 @@
/*
* 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.
*/
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* General purpose implementation of Delegate Splitter (or Multicast) pattern which allows subscribing multiple
* `receiving` objects to single `sending` object (which normally does not support that feature by itself).
*
* In the case where only one receiving object is registered, using Splitter has zero performance overhead because the
* receiver is being subscribed directly. In the case where more than one receiving objects are registered, using
* Splitter introduces some performance overhead.
*/
@interface RCTGenericDelegateSplitter<DelegateT> : NSObject
@property (nonatomic, copy, nullable) void (^delegateUpdateBlock)(DelegateT _Nullable delegate);
/*
* Creates an object with a given block that will be used to connect a `sending` object with a given `receiving` object.
* The class calls the block every time after each delegate adding or removing procedure, and it calls it twice: the
* first time with `nil` and the second time with actual delegate. This is required to establish a proper connection
* between sending and receiving objects (to reset caches storing information about supported (or not) optional
* methods).
*/
- (instancetype)initWithDelegateUpdateBlock:(void (^)(DelegateT _Nullable delegate))block;
/*
* Adds and removes a delegate.
* The delegates will be called in order of registration.
* If a delegate returns a value, the value from the last call will be passed to the `sending` object.
*/
- (void)addDelegate:(DelegateT)delegate;
- (void)removeDelegate:(DelegateT)delegate;
- (void)removeAllDelegates;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,94 @@
/*
* 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.
*/
#import "RCTGenericDelegateSplitter.h"
@implementation RCTGenericDelegateSplitter {
NSHashTable *_delegates;
}
#pragma mark - Public
- (instancetype)initWithDelegateUpdateBlock:(void (^)(id _Nullable delegate))block
{
if (self = [super init]) {
_delegateUpdateBlock = block;
_delegates = [NSHashTable weakObjectsHashTable];
}
return self;
}
- (void)addDelegate:(id)delegate
{
[_delegates addObject:delegate];
[self _updateDelegate];
}
- (void)removeDelegate:(id)delegate
{
[_delegates removeObject:delegate];
[self _updateDelegate];
}
- (void)removeAllDelegates
{
[_delegates removeAllObjects];
[self _updateDelegate];
}
#pragma mark - Private
- (void)_updateDelegate
{
_delegateUpdateBlock(nil);
if (_delegates.count == 0) {
return;
}
_delegateUpdateBlock(_delegates.count == 1 ? [_delegates allObjects].firstObject : self);
}
#pragma mark - Fast Forwarding
- (BOOL)respondsToSelector:(SEL)selector
{
for (id delegate in _delegates) {
if ([delegate respondsToSelector:selector]) {
return YES;
}
}
return NO;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
for (id delegate in _delegates) {
if ([delegate respondsToSelector:selector]) {
return [delegate methodSignatureForSelector:selector];
}
}
return nil;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
NSMutableArray *targets = [[NSMutableArray alloc] initWithCapacity:_delegates.count];
for (id delegate in _delegates) {
if ([delegate respondsToSelector:[invocation selector]]) {
[targets addObject:delegate];
}
}
for (id target in targets) {
[invocation invokeWithTarget:target];
}
}
@end

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.
*/
#pragma once
#include <bitset>
namespace facebook::react {
template <size_t size>
class RCTIdentifierPool {
public:
void enqueue(int index) {
usage[index] = false;
}
int dequeue() {
while (true) {
if (!usage[lastIndex]) {
usage[lastIndex] = true;
return lastIndex;
}
lastIndex = (lastIndex + 1) % size;
}
}
void reset() {
for (int i = 0; i < size; i++) {
usage[i] = false;
}
}
private:
std::bitset<size> usage;
int lastIndex;
};
} // namespace facebook::react

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Lightweight wrapper class around a UIView with a react tag which registers a
* constant react tag at initialization time for a stable hash and provides the
* udnerlying view to a caller if that underlying view's react tag has not
* changed from the one provided at initialization time (i.e. recycled).
*/
@interface RCTReactTaggedView : NSObject {
UIView *_view;
NSInteger _tag;
}
+ (RCTReactTaggedView *)wrap:(UIView *)view;
- (instancetype)initWithView:(UIView *)view;
- (nullable UIView *)view;
- (NSInteger)tag;
- (BOOL)isEqual:(id)other;
- (NSUInteger)hash;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,55 @@
/*
* 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.
*/
#import "RCTReactTaggedView.h"
@implementation RCTReactTaggedView
+ (RCTReactTaggedView *)wrap:(UIView *)view
{
return [[RCTReactTaggedView alloc] initWithView:view];
}
- (instancetype)initWithView:(UIView *)view
{
if (self = [super init]) {
_view = view;
_tag = view.tag;
}
return self;
}
- (nullable UIView *)view
{
if (_view.tag == _tag) {
return _view;
}
return nil;
}
- (NSInteger)tag
{
return _tag;
}
- (BOOL)isEqual:(id)other
{
if (other == self) {
return YES;
}
if (!other || ![other isKindOfClass:[self class]]) {
return NO;
}
return _tag == [other tag];
}
- (NSUInteger)hash
{
return _tag;
}
@end