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,32 @@
# 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.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fexceptions
-frtti
-std=c++20
-Wall
-Wpedantic
-DLOG_TAG=\"Fabric\")
file(GLOB react_render_componentregistry_SRC CONFIGURE_DEPENDS *.cpp)
add_library(react_render_componentregistry SHARED ${react_render_componentregistry_SRC})
target_include_directories(react_render_componentregistry PUBLIC ${REACT_COMMON_DIR})
target_link_libraries(react_render_componentregistry
folly_runtime
glog_init
jsi
react_config
react_debug
react_render_core
react_render_debug
react_utils
rrc_legacyviewmanagerinterop
)

View File

@@ -0,0 +1,32 @@
/*
* 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 <memory>
#include <react/renderer/core/ComponentDescriptor.h>
#include <react/renderer/core/EventDispatcher.h>
#include <react/utils/ContextContainer.h>
#include "ComponentDescriptorRegistry.h"
namespace facebook::react {
/**
* A factory to provide hosting app specific set of ComponentDescriptor's.
* Each app must provide an implementation of the static class method which
* should register its specific set of supported components.
*/
using ComponentRegistryFactory =
std::function<SharedComponentDescriptorRegistry(
const EventDispatcher::Weak& eventDispatcher,
const ContextContainer::Shared& contextContainer)>;
ComponentRegistryFactory getDefaultComponentRegistryFactory();
} // namespace facebook::react

View File

@@ -0,0 +1,72 @@
/*
* 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 <react/renderer/core/ComponentDescriptor.h>
#include <react/renderer/core/EventDispatcher.h>
#include <react/utils/ContextContainer.h>
namespace facebook::react {
/*
* Callable signature that represents the signature of `ComponentDescriptor`
* constructor. The callable returns a unique pointer conveniently represents an
* abstract type and ownership of the newly created object.
*/
using ComponentDescriptorConstructor = ComponentDescriptor::Unique(
const ComponentDescriptorParameters& parameters);
/*
* Represents a unified way to construct an instance of a particular stored
* `ComponentDescriptor` class. C++ does not allow to create pointers to
* constructors, so we have to have such data structure to manipulate a
* collection of classes.
*
* Note: The actual values of `handle` and `name` for some components depend on
* `flavor`. The provider is valid if instantiated by `constructor` object with
* given `flavor` exposes the same values of `handle` and `name`.
*/
class ComponentDescriptorProvider final {
public:
ComponentHandle handle;
ComponentName name;
ComponentDescriptor::Flavor flavor;
ComponentDescriptorConstructor* constructor;
};
/*
* Creates a `ComponentDescriptor` for given `ComponentDescriptorParameters`.
*/
template <typename ComponentDescriptorT>
ComponentDescriptor::Unique concreteComponentDescriptorConstructor(
const ComponentDescriptorParameters& parameters) {
static_assert(
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
return std::make_unique<const ComponentDescriptorT>(parameters);
}
/*
* Creates a `ComponentDescriptorProvider` for given `ComponentDescriptor`
* class.
*/
template <typename ComponentDescriptorT>
ComponentDescriptorProvider concreteComponentDescriptorProvider() {
static_assert(
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
return {
ComponentDescriptorT::ConcreteShadowNode::Handle(),
ComponentDescriptorT::ConcreteShadowNode::Name(),
nullptr,
&concreteComponentDescriptorConstructor<ComponentDescriptorT>};
}
} // namespace facebook::react

View File

@@ -0,0 +1,83 @@
/*
* 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.
*/
#include "ComponentDescriptorProviderRegistry.h"
namespace facebook::react {
void ComponentDescriptorProviderRegistry::add(
const ComponentDescriptorProvider& provider) const {
std::unique_lock lock(mutex_);
/*
// TODO: T57583139
The assert is temporarily disabled to reduce the volume of the signal.
assert(
componentDescriptorProviders_.find(provider.handle) ==
componentDescriptorProviders_.end() &&
"Attempt to register an already registered ComponentDescriptorProvider.");
*/
if (componentDescriptorProviders_.find(provider.handle) !=
componentDescriptorProviders_.end()) {
// Re-registering a provider makes no sense because it's copyable: already
// registered one is as good as any new can be.
return;
}
componentDescriptorProviders_.insert({provider.handle, provider});
for (const auto& weakRegistry : componentDescriptorRegistries_) {
auto registry = weakRegistry.lock();
if (!registry) {
continue;
}
registry->add(provider);
}
}
void ComponentDescriptorProviderRegistry::setComponentDescriptorProviderRequest(
ComponentDescriptorProviderRequest componentDescriptorProviderRequest)
const {
std::shared_lock lock(mutex_);
componentDescriptorProviderRequest_ =
std::move(componentDescriptorProviderRequest);
}
void ComponentDescriptorProviderRegistry::request(
ComponentName componentName) const {
ComponentDescriptorProviderRequest componentDescriptorProviderRequest;
{
std::shared_lock lock(mutex_);
componentDescriptorProviderRequest = componentDescriptorProviderRequest_;
}
if (componentDescriptorProviderRequest) {
componentDescriptorProviderRequest(componentName);
}
}
ComponentDescriptorRegistry::Shared
ComponentDescriptorProviderRegistry::createComponentDescriptorRegistry(
const ComponentDescriptorParameters& parameters) const {
std::shared_lock lock(mutex_);
auto registry = std::make_shared<const ComponentDescriptorRegistry>(
parameters, *this, parameters.contextContainer);
for (const auto& pair : componentDescriptorProviders_) {
registry->add(pair.second);
}
componentDescriptorRegistries_.push_back(registry);
return registry;
}
} // namespace facebook::react

View File

@@ -0,0 +1,70 @@
/*
* 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 <shared_mutex>
#include <unordered_map>
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
#include <react/renderer/core/ComponentDescriptor.h>
namespace facebook::react {
using ComponentDescriptorProviderRequest =
std::function<void(ComponentName componentName)>;
/*
* Registry of `ComponentDescriptorProvider`s (and managed
* `ComponentDescriptorRegistry`s). The class maintains a list of
* `ComponentDescriptorRegistry`s (retaining pointers weakly) and update them
* accordingly to changes in the provider registry.
*/
class ComponentDescriptorProviderRegistry final {
public:
/*
* Adds a `ComponentDescriptorProvider`s and update the managed
* `ComponentDescriptorRegistry`s accordingly.
* The methods can be called on any thread.
*/
void add(const ComponentDescriptorProvider& provider) const;
/*
* ComponenDescriptorRegistry will call the `request` in case if a component
* with given name wasn't registered yet.
* The request handler must register a ComponentDescriptor with requested name
* synchronously during handling the request.
* The request can be called on any thread.
* The methods can be called on any thread.
*/
void setComponentDescriptorProviderRequest(
ComponentDescriptorProviderRequest request) const;
/*
* Creates managed `ComponentDescriptorRegistry` based on a stored list of
* `ComponentDescriptorProvider`s and given `ComponentDescriptorParameters`.
* The methods can be called on any thread.
*/
ComponentDescriptorRegistry::Shared createComponentDescriptorRegistry(
const ComponentDescriptorParameters& parameters) const;
private:
friend class ComponentDescriptorRegistry;
void request(ComponentName componentName) const;
mutable std::shared_mutex mutex_;
mutable std::vector<std::weak_ptr<const ComponentDescriptorRegistry>>
componentDescriptorRegistries_;
mutable std::unordered_map<ComponentHandle, ComponentDescriptorProvider const>
componentDescriptorProviders_;
mutable ComponentDescriptorProviderRequest
componentDescriptorProviderRequest_{};
};
} // namespace facebook::react

View File

@@ -0,0 +1,148 @@
/*
* 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.
*/
#include "ComponentDescriptorRegistry.h"
#include "componentNameByReactViewName.h"
#include <react/config/ReactNativeConfig.h>
#include <react/debug/react_native_assert.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/legacyviewmanagerinterop/UnstableLegacyViewManagerAutomaticComponentDescriptor.h>
#include <react/renderer/components/legacyviewmanagerinterop/UnstableLegacyViewManagerAutomaticShadowNode.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/ShadowNodeFragment.h>
#include <utility>
namespace facebook::react {
ComponentDescriptorRegistry::ComponentDescriptorRegistry(
ComponentDescriptorParameters parameters,
const ComponentDescriptorProviderRegistry& providerRegistry,
ContextContainer::Shared contextContainer)
: parameters_(std::move(parameters)),
providerRegistry_(providerRegistry),
contextContainer_(std::move(contextContainer)) {}
void ComponentDescriptorRegistry::add(
ComponentDescriptorProvider componentDescriptorProvider) const {
std::unique_lock lock(mutex_);
auto componentDescriptor = componentDescriptorProvider.constructor(
{parameters_.eventDispatcher,
parameters_.contextContainer,
componentDescriptorProvider.flavor});
react_native_assert(
componentDescriptor->getComponentHandle() ==
componentDescriptorProvider.handle);
react_native_assert(
componentDescriptor->getComponentName() ==
componentDescriptorProvider.name);
auto sharedComponentDescriptor = std::shared_ptr<const ComponentDescriptor>(
std::move(componentDescriptor));
_registryByHandle[componentDescriptorProvider.handle] =
sharedComponentDescriptor;
_registryByName[componentDescriptorProvider.name] = sharedComponentDescriptor;
}
void ComponentDescriptorRegistry::registerComponentDescriptor(
const SharedComponentDescriptor& componentDescriptor) const {
ComponentHandle componentHandle = componentDescriptor->getComponentHandle();
_registryByHandle[componentHandle] = componentDescriptor;
ComponentName componentName = componentDescriptor->getComponentName();
_registryByName[componentName] = componentDescriptor;
}
const ComponentDescriptor& ComponentDescriptorRegistry::at(
const std::string& componentName) const {
std::shared_lock lock(mutex_);
auto unifiedComponentName = componentNameByReactViewName(componentName);
auto it = _registryByName.find(unifiedComponentName);
if (it == _registryByName.end()) {
lock.unlock();
providerRegistry_.request(unifiedComponentName.c_str());
lock.lock();
it = _registryByName.find(unifiedComponentName);
/*
* TODO: T54849676
* Uncomment the `assert` after the following block that checks
* `_fallbackComponentDescriptor` is no longer needed. The assert assumes
* that `componentDescriptorProviderRequest` is always not null and register
* some component on every single request.
*/
// assert(it != _registryByName.end());
}
if (it == _registryByName.end()) {
auto reactNativeConfig_ =
contextContainer_->at<std::shared_ptr<const ReactNativeConfig>>(
"ReactNativeConfig");
if (reactNativeConfig_->getBool(
"react_fabric:enabled_automatic_interop_android")) {
auto componentDescriptor = std::make_shared<
const UnstableLegacyViewManagerAutomaticComponentDescriptor>(
parameters_, unifiedComponentName);
registerComponentDescriptor(componentDescriptor);
return *_registryByName.find(unifiedComponentName)->second;
} else if (_fallbackComponentDescriptor == nullptr) {
throw std::invalid_argument(
("Unable to find componentDescriptor for " + unifiedComponentName)
.c_str());
} else {
return *_fallbackComponentDescriptor.get();
}
}
return *it->second;
}
const ComponentDescriptor* ComponentDescriptorRegistry::
findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
ComponentHandle componentHandle) const {
std::shared_lock lock(mutex_);
auto iterator = _registryByHandle.find(componentHandle);
if (iterator == _registryByHandle.end()) {
return nullptr;
}
return iterator->second.get();
}
const ComponentDescriptor& ComponentDescriptorRegistry::at(
ComponentHandle componentHandle) const {
std::shared_lock lock(mutex_);
return *_registryByHandle.at(componentHandle);
}
bool ComponentDescriptorRegistry::hasComponentDescriptorAt(
ComponentHandle componentHandle) const {
std::shared_lock lock(mutex_);
auto iterator = _registryByHandle.find(componentHandle);
return iterator != _registryByHandle.end();
}
void ComponentDescriptorRegistry::setFallbackComponentDescriptor(
const SharedComponentDescriptor& descriptor) {
_fallbackComponentDescriptor = descriptor;
registerComponentDescriptor(descriptor);
}
ComponentDescriptor::Shared
ComponentDescriptorRegistry::getFallbackComponentDescriptor() const {
return _fallbackComponentDescriptor;
}
} // namespace facebook::react

View File

@@ -0,0 +1,87 @@
/*
* 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 <memory>
#include <shared_mutex>
#include <unordered_map>
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
#include <react/renderer/core/ComponentDescriptor.h>
#include <react/renderer/core/InstanceHandle.h>
#include <react/utils/ContextContainer.h>
namespace facebook::react {
class ComponentDescriptorProviderRegistry;
class ComponentDescriptorRegistry;
using SharedComponentDescriptorRegistry =
std::shared_ptr<const ComponentDescriptorRegistry>;
/*
* Registry of particular `ComponentDescriptor`s.
*/
class ComponentDescriptorRegistry {
public:
using Shared = std::shared_ptr<const ComponentDescriptorRegistry>;
/*
* Creates an object with stored `ComponentDescriptorParameters` which will
* be used later to create `ComponentDescriptor`s.
*/
ComponentDescriptorRegistry(
ComponentDescriptorParameters parameters,
const ComponentDescriptorProviderRegistry& providerRegistry,
ContextContainer::Shared contextContainer);
/*
* This is broken. Please do not use.
* If you requesting a ComponentDescriptor and unsure that it's there, you are
* doing something wrong.
*/
const ComponentDescriptor*
findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
ComponentHandle componentHandle) const;
const ComponentDescriptor& at(const std::string& componentName) const;
const ComponentDescriptor& at(ComponentHandle componentHandle) const;
bool hasComponentDescriptorAt(ComponentHandle componentHandle) const;
void setFallbackComponentDescriptor(
const SharedComponentDescriptor& descriptor);
ComponentDescriptor::Shared getFallbackComponentDescriptor() const;
private:
friend class ComponentDescriptorProviderRegistry;
void registerComponentDescriptor(
const SharedComponentDescriptor& componentDescriptor) const;
/*
* Creates a `ComponentDescriptor` using specified
* `ComponentDescriptorProvider` and stored `ComponentDescriptorParameters`,
* and then adds that to the registry.
* To be used by `ComponentDescriptorProviderRegistry` only.
* Thread safe.
*/
void add(ComponentDescriptorProvider componentDescriptorProvider) const;
mutable std::shared_mutex mutex_;
mutable std::unordered_map<ComponentHandle, SharedComponentDescriptor>
_registryByHandle;
mutable std::unordered_map<std::string, SharedComponentDescriptor>
_registryByName;
ComponentDescriptor::Shared _fallbackComponentDescriptor;
ComponentDescriptorParameters parameters_{};
const ComponentDescriptorProviderRegistry& providerRegistry_;
ContextContainer::Shared contextContainer_;
};
} // namespace facebook::react

View File

@@ -0,0 +1,72 @@
/*
* 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.
*/
#include "componentNameByReactViewName.h"
#include <algorithm>
namespace facebook::react {
std::string componentNameByReactViewName(std::string viewName) {
// We need this function only for the transition period;
// eventually, all names will be unified.
// TODO T97384889: unify component names between JS - Android - iOS - C++
std::string rctPrefix("RCT");
if (std::mismatch(rctPrefix.begin(), rctPrefix.end(), viewName.begin())
.first == rctPrefix.end()) {
// If `viewName` has "RCT" prefix, remove it.
viewName.erase(0, rctPrefix.length());
}
// Fabric uses slightly new names for Text components because of differences
// in semantic.
if (viewName == "Text") {
return "Paragraph";
}
// TODO T63839307: remove this condition after deleting TextInlineImage from
// old renderer code
if (viewName == "TextInlineImage") {
return "Image";
}
if (viewName == "VirtualText") {
return "Text";
}
if (viewName == "ImageView") {
return "Image";
}
if (viewName == "AndroidHorizontalScrollView") {
return "ScrollView";
}
if (viewName == "RKShimmeringView") {
return "ShimmeringView";
}
if (viewName == "RefreshControl") {
return "PullToRefreshView";
}
// We need this temporarily for testing purposes until we have proper
// implementation of core components.
// iOS-only
if (viewName == "ScrollContentView") {
return "View";
}
// iOS-only
if (viewName == "MultilineTextInputView" ||
viewName == "SinglelineTextInputView") {
return "TextInput";
}
return viewName;
}
} // namespace facebook::react

View File

@@ -0,0 +1,19 @@
/*
* 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 <string>
namespace facebook::react {
/**
* Provides mapping from old view name format to the new format.
*/
std::string componentNameByReactViewName(std::string viewName);
} // namespace facebook::react

View File

@@ -0,0 +1,31 @@
# 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.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fexceptions
-frtti
-std=c++20
-Wall
-Wpedantic
-DLOG_TAG=\"Fabric\")
file(GLOB rrc_native_SRC CONFIGURE_DEPENDS *.cpp)
add_library(rrc_native STATIC ${rrc_native_SRC})
target_include_directories(rrc_native PUBLIC ${REACT_COMMON_DIR})
target_link_libraries(rrc_native
folly_runtime
glog_init
jsi
react_debug
react_render_core
react_render_debug
react_utils
callinvoker
)

View File

@@ -0,0 +1,28 @@
/*
* 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.
*/
#include "NativeComponentRegistryBinding.h"
#include <react/bridging/Bridging.h>
#include <stdexcept>
#include <string>
namespace facebook::react {
/**
* Public API to install the Native Component Registry bindings.
*/
void bindHasComponentProvider(
jsi::Runtime& runtime,
HasComponentProviderFunctionType&& provider) {
runtime.global().setProperty(
runtime,
"__nativeComponentRegistry__hasComponent",
bridging::toJs(runtime, provider, {}));
}
} // namespace facebook::react

View File

@@ -0,0 +1,31 @@
/*
* 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 <string>
#include <jsi/jsi.h>
namespace facebook::react {
/**
* An app/platform-specific provider function to determine if a component
* is registered in the native platform.
*/
using HasComponentProviderFunctionType =
std::function<bool(const std::string& name)>;
/*
* Installs HasComponentProviderFunction into JavaScript runtime.
* Thread synchronization must be enforced externally.
*/
void bindHasComponentProvider(
jsi::Runtime& runtime,
HasComponentProviderFunctionType&& provider);
} // namespace facebook::react