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,21 @@
Copyright (c) Julian Viereck and Contributors, All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,47 @@
# RegJSParser
Parsing the JavaScript's RegExp in JavaScript.
## Installation
```bash
npm install regjsparser
```
## Usage
```js
var parse = require('regjsparser').parse;
var parseTree = parse('^a'); // /^a/
console.log(parseTree);
// Toggle on/off additional features:
var parseTree = parse('^a', '', {
// SEE: https://github.com/jviereck/regjsparser/pull/78
unicodePropertyEscape: true,
// SEE: https://github.com/jviereck/regjsparser/pull/83
namedGroups: true,
// SEE: https://github.com/jviereck/regjsparser/pull/89
lookbehind: true
});
console.log(parseTree);
```
## Testing
To run the tests, run the following command:
```bash
npm test
```
To create a new reference file, execute…
```bash
node test/update-fixtures.js
```
…from the repo top directory.

63
smart-app-city/frontend/node_modules/regjsparser/bin/parser generated vendored Executable file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env node
(function() {
var fs = require('fs');
var path = require('path');
var parse = require('../parser').parse;
var jsesc = require('jsesc');
var regexes = process.argv.splice(2);
var first = regexes[0];
var data;
var log = console.log;
var flags = '';
var main = function() {
if (/^(?:-h|--help|undefined)$/.test(first)) {
log([
'\nUsage:\n',
'\tregjsparser [regex ...]',
'\tregjsparser [-f | --flags] u [regex ...]',
'\tregjsparser [-v | --version]',
'\tregjsparser [-h | --help]',
'\nExamples:\n',
'\tregjsparser \'^foo.bar$\'',
'\tregjsparser \'[a-zA-Z0-9]\''
].join('\n'));
return process.exit(1);
}
if (/^(?:-v|--version)$/.test(first)) {
log('v%s', require(path.resolve(__dirname, '../package.json')).version);
return process.exit(1);
}
if (/^(?:-f|--flags)$/.test(first)) {
flags = regexes[1];
regexes = regexes.slice(2);
}
regexes.forEach(function(snippet) {
try {
result = parse(snippet, flags);
log(jsesc(result, {
'json': true,
'compact': false,
'indent': '\t'
}));
} catch(error) {
log(error.message + '\n');
log('Error: failed to parse. Make sure the regular expression is valid.');
log('If you think this is a bug in regjsparser, please report it:');
log('\thttps://github.com/jviereck/regjsparser/issues/new');
log('\nStack trace:\n');
log(error.stack);
return process.exit(1);
}
});
// Return with exit status 0 outside of the `forEach` loop, in case
// multiple regular expressions were passed in.
return process.exit(0);
};
main();
}());

View File

@@ -0,0 +1,47 @@
{
"name": "regjsparser",
"version": "0.13.1",
"author": "'Julian Viereck' <julian.viereck@gmail.com>",
"license": "BSD-2-Clause",
"main": "./parser",
"types": "./parser.d.ts",
"bin": {
"regjsparser": "bin/parser"
},
"homepage": "https://github.com/jviereck/regjsparser",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/jviereck/regjsparser.git"
},
"scripts": {
"lint": "eslint --max-warnings 0 .",
"test": "run-p test:* lint",
"test:src": "node test/index.js",
"test:types": "tsc test/types.ts --noEmit",
"bench:baseline": "node ./tools/bench/index.mjs baseline",
"bench:current": "node ./tools/bench/index.mjs current",
"bench": "run-s bench:*"
},
"files": [
"bin/",
"LICENSE.BSD",
"parser.js",
"parser.d.ts",
"README.md"
],
"dependencies": {
"jsesc": "~3.1.0"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@unicode/unicode-17.0.0": "^1.6.12",
"eslint": "^10.0.2",
"eslint-plugin-regexp": "^3.0.0",
"globals": "^17.3.0",
"npm-run-all": "^4.1.5",
"regenerate": "^1.4.2",
"regjsparser": "^0.11.2",
"tinybench": "^5.0.1",
"typescript": "~5.9.2"
}
}

View File

@@ -0,0 +1,182 @@
type _If<Test, Then, Else> = Test extends true ? Then : Else;
export type Features = {
lookbehind?: boolean;
namedGroups?: boolean;
unicodePropertyEscape?: boolean;
unicodeSet?: boolean;
modifiers?: boolean;
};
export type AstNodeType =
| "alternative"
| "anchor"
| "characterClass"
| "characterClassEscape"
| "characterClassRange"
| "disjunction"
| "dot"
| "group"
| "quantifier"
| "reference"
| "unicodePropertyEscape"
| "value";
export type Base<T extends AstNodeType> = {
range: [number, number];
raw: string;
type: T;
};
export type AstNode<F extends Features = {}> =
| Alternative<F>
| Anchor
| CharacterClass<F>
| CharacterClassEscape
| CharacterClassRange
| Disjunction<F>
| Dot
| Group<F>
| Quantifier<F>
| Reference<F>
| _If<F["unicodePropertyEscape"], UnicodePropertyEscape, never>
| Value;
export type RootNode<F extends Features = {}> = Exclude<
AstNode<F>,
CharacterClassRange
>;
export type Anchor = Base<"anchor"> & {
kind: "boundary" | "end" | "not-boundary" | "start";
};
export type CharacterClassEscape = Base<"characterClassEscape"> & {
value: 'd' | 'D' | 'w' | 'W' | 's' | 'S';
};
export type Value = Base<"value"> & {
codePoint: number;
kind:
| "controlLetter"
| "hexadecimalEscape"
| "identifier"
| "null"
| "octal"
| "singleEscape"
| "symbol"
| "unicodeCodePointEscape"
| "unicodeEscape";
};
export type Identifier = Base<"value"> & {
value: string;
};
export type Alternative<F extends Features = {}> = Base<"alternative"> & {
body: RootNode<F>[];
};
export type CharacterClassRange = Base<"characterClassRange"> & {
max: Value;
min: Value;
};
export type UnicodePropertyEscape = Base<"unicodePropertyEscape"> & {
negative: boolean;
value: string;
};
export type CharacterClassBody =
| CharacterClassEscape
| CharacterClassRange
| UnicodePropertyEscape
| Value;
export type CharacterClass<F extends Features = {}> = Base<"characterClass"> & {
body: CharacterClassBody[];
negative: boolean;
kind: "union" | _If<F["unicodeSet"], "intersection" | "subtraction", never>;
};
export type ModifierFlags = {
enabling: string;
disabling: string;
};
export type NonCapturingGroup<F extends Features = {}> = Base<"group"> &
(
| {
behavior:
| "lookahead"
| "lookbehind"
| "negativeLookahead"
| "negativeLookbehind";
body: RootNode<F>[];
}
| ({
behavior: "ignore";
body: RootNode<F>[];
} & _If<
F["modifiers"],
{
modifierFlags?: ModifierFlags;
},
{
modifierFlags: undefined;
}
>)
);
export type CapturingGroup<F extends Features = {}> = Base<"group"> & {
behavior: "normal";
body: RootNode<F>[];
} & _If<
F["namedGroups"],
{
name?: Identifier;
},
{
name: undefined;
}
>;
export type Group<F extends Features = {}> =
| CapturingGroup<F>
| NonCapturingGroup<F>;
export type Quantifier<F extends Features = {}> = Base<"quantifier"> & {
body: [RootNode<F>];
greedy: boolean;
max?: number;
min: number;
symbol?: "?" | "*" | "+";
};
export type Disjunction<F extends Features = {}> = Base<"disjunction"> & {
body: [RootNode<F>, RootNode<F>, ...RootNode<F>[]];
};
export type Dot = Base<"dot">;
export type NamedReference = Base<"reference"> & {
matchIndex: undefined;
name: Identifier;
};
export type IndexReference = Base<"reference"> & {
matchIndex: number;
name: undefined;
};
export type Reference<F extends Features = {}> = _If<
F["namedGroups"],
IndexReference | NamedReference,
IndexReference
>;
export function parse<F extends Features = {}>(
str: string,
flags: string,
features?: F
): RootNode<F>;

File diff suppressed because one or more lines are too long