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,53 @@
module Pod
class PodTarget
private
_original_module_map_path = instance_method(:module_map_path)
public
# CocoaPods's default modulemap did not generate submodules correctly
# `ios/Pods/Headers/Public/React/React-Core.modulemap`
# ```
# module React {
# umbrella header "React-Core-umbrella.h"
#
# export *
# module * { export * }
# }
# ```
# clang will generate submodules for headers relative to the umbrella header directory.
# https://github.com/llvm/llvm-project/blob/2782cb8da0b3c180fa7c8627cb255a026f3d25a2/clang/lib/Lex/ModuleMap.cpp#L1133
# In this case, it is `ios/Pods/Headers/Public/React`.
# But the React public headers are placed in `ios/Pods/Headers/Public/React-Core/React`, so clang cannot find the headers and generate submodules.
#
# This case happens when a pod's name different to its module name, e.g. the pod name is `React-Core` but the module name is `React` since it defines header_dir as `React`.
# To fix the issue, we rewrite the `module_map_path` and `umbrella_header_path` to be with the public headers,
# i.e. `ios/Pods/Headers/Public/React-Core/React/React-Core.modulemap` and `ios/Pods/Headers/Public/React-Core/React/React-Core-umbrella.h`
#
def rewrite_module_dir
# strip expo go versioning prefix
normalized_name = name.gsub(/^ABI\d+_\d+_\d+/, '')
if ['React-Core', 'React-RCTFabric'].include?(normalized_name) && product_module_name != name
return sandbox.public_headers.root + name + product_module_name
end
return nil
end
def umbrella_header_path
if dir = self.rewrite_module_dir
return dir + "#{label}-umbrella.h"
end
super
end
define_method(:module_map_path) do
if dir = self.rewrite_module_dir
return dir + "#{label}.modulemap"
end
_original_module_map_path.bind(self).()
end
end # class PodTarget
end # module Pod

View File

@@ -0,0 +1,68 @@
# Overrides CocoaPods `Sandbox` class to patch podspecs on the fly
# See: https://github.com/CocoaPods/CocoaPods/blob/master/lib/cocoapods/sandbox.rb
require 'json'
REACT_DEFINE_MODULES_LIST = [
'ReactCommon',
'React-RCTAppDelegate',
'React-hermes',
'React-jsc',
'React-Fabric',
'React-graphics',
'React-utils',
'React-debug',
]
module Pod
class Sandbox
private
_original_store_podspec = instance_method(:store_podspec)
public
define_method(:store_podspec) do |name, podspec, _external_source, json|
spec = _original_store_podspec.bind(self).(name, podspec, _external_source, json)
patched_spec = nil
# Patch `React-Core.podspec` for clang to generate correct submodules for swift integration
if name == 'React-Core'
spec_json = JSON.parse(spec.to_pretty_json)
# clang module does not support objc++.
# We should put Hermes headers inside private headers directory.
# Otherwise, clang will throw errors in building module.
hermes_subspec_index = spec_json['subspecs'].index { |subspec| subspec['name'] == 'Hermes' }
if hermes_subspec_index
spec_json['subspecs'][hermes_subspec_index]['private_header_files'] ||= [
'ReactCommon/hermes/executor/*.h',
'ReactCommon/hermes/inspector/*.h',
'ReactCommon/hermes/inspector/chrome/*.h',
'ReactCommon/hermes/inspector/detail/*.h',
]
end
patched_spec = Specification.from_json(spec_json.to_json)
# Patch podspecs to define module
elsif REACT_DEFINE_MODULES_LIST.include? name
spec_json = JSON.parse(podspec.to_pretty_json)
spec_json['pod_target_xcconfig'] ||= {}
spec_json['pod_target_xcconfig']['DEFINES_MODULE'] = 'YES'
patched_spec = Specification.from_json(spec_json.to_json)
end
if patched_spec != nil
# Store the patched spec with original checksum and local saved file path
patched_spec.defined_in_file = spec.defined_in_file
patched_spec.instance_variable_set(:@checksum, spec.checksum)
@stored_podspecs[spec.name] = patched_spec
return patched_spec
end
return spec
end # define_method(:store_podspec)
end # class Sandbox
end # module Pod

View File

@@ -0,0 +1,22 @@
# Overrides CocoaPods class as the AutolinkingManager is in fact part of
# the target definitions and we need to refer to it at later steps.
# See: https://github.com/CocoaPods/Core/blob/master/lib/cocoapods-core/podfile/target_definition.rb
module Pod
class Podfile
class TargetDefinition
public
attr_writer :autolinking_manager
def autolinking_manager
if @autolinking_manager.present? || root?
@autolinking_manager
else
parent.autolinking_manager
end
end
end
end
end

View File

@@ -0,0 +1,22 @@
module Pod
module Generator
class UmbrellaHeader
private
_original_generate = instance_method(:generate)
public
define_method (:generate) do
if self.target.is_a?(Pod::PodTarget) && self.target.rewrite_module_dir
# If we write the `umbrella_header_path`, the import headers are in the same directory,
# e.g. `#import "React/RCTBridge.h"` -> `#import "RCTBridge.h"`
self.imports = self.imports.map { |import| import.basename }
end
_original_generate.bind(self).()
end
end # class UmbrellaHeader
end # module Generator
end # module Pod

View File

@@ -0,0 +1,62 @@
require_relative '../project_integrator'
# Unfortunately there is no good and official place that we could use to generate module providers
# and integrate them with user targets by operating on the PBXProj kept and saved by CocoaPods.
# So we have to hook into the private method called `integrate_user_targets`
# where we have public access to everything that we need.
# Original implementation: https://github.com/CocoaPods/CocoaPods/blob/master/lib/cocoapods/installer/user_project_integrator.rb
module Pod
class Installer
class UserProjectIntegrator
include Expo::ProjectIntegrator
private
_original_integrate_user_targets = instance_method(:integrate_user_targets)
# Integrates the targets of the user projects with the libraries
# generated from the {Podfile}.
#
# @note {TargetDefinition} without dependencies are skipped to prevent
# creating empty libraries for target definitions which are only
# wrappers for others.
#
# @return [void]
#
define_method(:integrate_user_targets) do
# Call original method first
results = _original_integrate_user_targets.bind(self).()
UI.message '- Integrating Expo modules providers' do
# All user targets mapped to user projects.
all_projects = targets.map { |target| target.user_project }.uniq
# Array of projects to integrate is usually a subset of `all_projects`,
# and it might be empty subsequent installs after the first install.
# CocoaPods integrates only these ones.
projects_to_integrate = user_projects_to_integrate()
# However, we need to make sure that all projects are integrated,
# regardless of the CocoaPods cache.
all_projects.each do |project|
project_targets = targets.select { |target| target.user_project.equal?(project) }
Expo::ProjectIntegrator::integrate_targets_in_project(project_targets, project)
Expo::ProjectIntegrator::remove_nils_from_source_files(project)
Expo::ProjectIntegrator::set_autolinking_configuration(project)
# CocoaPods saves the projects to integrate at the next step,
# but in some cases we're modifying other projects as well.
# Below we make sure the project will be saved and no more than once!
if project.dirty? && !projects_to_integrate.include?(project)
save_projects([project])
end
end
end
results
end
end # class UserProjectIntegrator
end # class Installer
end # module Pod