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,9 @@
// @component ./DrawerItem.tsx
export { default as Item } from './DrawerItem';
// @component ./DrawerCollapsedItem.tsx
export { default as CollapsedItem } from './DrawerCollapsedItem';
// @component ./DrawerSection.tsx
export { default as Section } from './DrawerSection';
//# sourceMappingURL=Drawer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["default","Item","CollapsedItem","Section"],"sourceRoot":"../../../../src","sources":["components/Drawer/Drawer.tsx"],"mappings":"AAAA;AACA,SAASA,OAAO,IAAIC,IAAI,QAAQ,cAAc;;AAE9C;AACA,SAASD,OAAO,IAAIE,aAAa,QAAQ,uBAAuB;;AAEhE;AACA,SAASF,OAAO,IAAIG,OAAO,QAAQ,iBAAiB","ignoreList":[]}

View File

@@ -0,0 +1,182 @@
import * as React from 'react';
import { Animated, Platform, Pressable, StyleSheet, View } from 'react-native';
import { useInternalTheme } from '../../core/theming';
import Badge from '../Badge';
import Icon from '../Icon';
import Text from '../Typography/Text';
const badgeSize = 8;
const iconSize = 24;
const itemSize = 56;
const outlineHeight = 32;
/**
* Note: Available in v5.x with theme version 3
*
* Collapsed component used to show an action item with an icon and optionally label in a navigation drawer.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { Drawer } from 'react-native-paper';
*
* const MyComponent = () => (
* <Drawer.CollapsedItem
* focusedIcon="inbox"
* unfocusedIcon="inbox-outline"
* label="Inbox"
* />
* );
*
* export default MyComponent;
* ```
*/
const DrawerCollapsedItem = ({
focusedIcon,
unfocusedIcon,
label,
active,
theme: themeOverrides,
style,
onPress,
disabled,
accessibilityLabel,
badge = false,
testID = 'drawer-collapsed-item',
labelMaxFontSizeMultiplier,
...rest
}) => {
const theme = useInternalTheme(themeOverrides);
const {
isV3
} = theme;
const {
scale
} = theme.animation;
const [numOfLines, setNumOfLines] = React.useState(1);
const {
current: animScale
} = React.useRef(new Animated.Value(active ? 1 : 0.5));
React.useEffect(() => {
if (!active) {
animScale.setValue(0.5);
}
}, [animScale, active]);
if (!isV3) {
return null;
}
const handlePressOut = () => {
Animated.timing(animScale, {
toValue: 1,
duration: 150 * scale,
useNativeDriver: true
}).start();
};
const iconPadding = ((!label ? itemSize : outlineHeight) - iconSize) / 2;
const backgroundColor = active ? theme.colors.secondaryContainer : 'transparent';
const labelColor = active ? theme.colors.onSurface : theme.colors.onSurfaceVariant;
const iconColor = active ? theme.colors.onSecondaryContainer : theme.colors.onSurfaceVariant;
const onTextLayout = ({
nativeEvent
}) => {
setNumOfLines(nativeEvent.lines.length);
};
// Label is cut off on Android, when centered "labelMedium" text
// has more than 4 lines, so there is a need to decrease the letter spacing.
const androidLetterSpacingStyle = Platform.OS === 'android' && numOfLines > 4 && styles.letterSpacing;
const labelTextStyle = {
color: labelColor,
...(isV3 ? theme.fonts.labelMedium : {})
};
const icon = !active && unfocusedIcon !== undefined ? unfocusedIcon : focusedIcon;
return /*#__PURE__*/React.createElement(View, rest, /*#__PURE__*/React.createElement(Pressable, {
onPress: onPress,
onPressOut: onPress ? handlePressOut : undefined,
disabled: disabled
// @ts-expect-error We keep old a11y props for backwards compat with old RN versions
,
accessibilityTraits: active ? ['button', 'selected'] : 'button',
accessibilityComponentType: "button",
accessibilityRole: "button",
accessibilityState: {
selected: active
},
accessibilityLabel: accessibilityLabel,
testID: testID
}, /*#__PURE__*/React.createElement(View, {
style: styles.wrapper
}, /*#__PURE__*/React.createElement(Animated.View, {
style: [styles.outline, !label && styles.roundedOutline, {
transform: [label ? {
scaleX: animScale
} : {
scale: animScale
}],
backgroundColor
}, style],
testID: `${testID}-outline`
}), /*#__PURE__*/React.createElement(View, {
style: [styles.icon, {
top: iconPadding
}],
testID: `${testID}-container`
}, badge !== false && /*#__PURE__*/React.createElement(View, {
style: styles.badgeContainer
}, typeof badge === 'boolean' ? /*#__PURE__*/React.createElement(Badge, {
visible: badge,
size: badgeSize
}) : /*#__PURE__*/React.createElement(Badge, {
visible: badge != null,
size: 2 * badgeSize
}, badge)), /*#__PURE__*/React.createElement(Icon, {
source: icon,
size: iconSize,
color: iconColor
})), label ? /*#__PURE__*/React.createElement(Text, {
variant: "labelMedium",
selectable: false,
numberOfLines: 2,
onTextLayout: onTextLayout,
style: [styles.label, androidLetterSpacingStyle, labelTextStyle],
maxFontSizeMultiplier: labelMaxFontSizeMultiplier
}, label) : null)));
};
DrawerCollapsedItem.displayName = 'Drawer.CollapsedItem';
const styles = StyleSheet.create({
wrapper: {
width: 80,
marginBottom: 12,
minHeight: itemSize,
alignItems: 'center'
},
outline: {
width: itemSize,
height: outlineHeight,
borderRadius: itemSize / 2,
alignItems: 'center',
justifyContent: 'center'
},
roundedOutline: {
height: itemSize
},
icon: {
position: 'absolute'
},
letterSpacing: {
letterSpacing: 0.3,
alignSelf: 'stretch'
},
label: {
marginHorizontal: 12,
marginTop: 4,
textAlign: 'center'
},
badgeContainer: {
position: 'absolute',
left: 20,
bottom: 20,
zIndex: 2
}
});
export default DrawerCollapsedItem;
//# sourceMappingURL=DrawerCollapsedItem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,126 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import color from 'color';
import { useInternalTheme } from '../../core/theming';
import Icon from '../Icon';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
import Text from '../Typography/Text';
/**
* A component used to show an action item with an icon and a label in a navigation drawer.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { Drawer } from 'react-native-paper';
*
* const MyComponent = () => (
* <Drawer.Item
* style={{ backgroundColor: '#64ffda' }}
* icon="star"
* label="First Item"
* />
* );
*
* export default MyComponent;
* ```
*/
const DrawerItem = ({
icon,
label,
active,
disabled,
theme: themeOverrides,
rippleColor: customRippleColor,
style,
onPress,
background,
accessibilityLabel,
right,
labelMaxFontSizeMultiplier,
hitSlop,
...rest
}) => {
const theme = useInternalTheme(themeOverrides);
const {
roundness,
isV3
} = theme;
const backgroundColor = active ? isV3 ? theme.colors.secondaryContainer : color(theme.colors.primary).alpha(0.12).rgb().string() : undefined;
const contentColor = active ? isV3 ? theme.colors.onSecondaryContainer : theme.colors.primary : isV3 ? theme.colors.onSurfaceVariant : color(theme.colors.text).alpha(0.68).rgb().string();
const labelMargin = icon ? isV3 ? 12 : 32 : 0;
const borderRadius = (isV3 ? 7 : 1) * roundness;
const rippleColor = isV3 ? color(contentColor).alpha(0.12).rgb().string() : undefined;
const font = isV3 ? theme.fonts.labelLarge : theme.fonts.medium;
return /*#__PURE__*/React.createElement(View, rest, /*#__PURE__*/React.createElement(TouchableRipple, {
borderless: true,
disabled: disabled,
background: background,
onPress: onPress,
style: [styles.container, {
backgroundColor,
borderRadius
}, isV3 && styles.v3Container, style],
accessibilityRole: "button",
accessibilityState: {
selected: active
},
accessibilityLabel: accessibilityLabel,
rippleColor: customRippleColor || rippleColor,
theme: theme,
hitSlop: hitSlop
}, /*#__PURE__*/React.createElement(View, {
style: [styles.wrapper, isV3 && styles.v3Wrapper]
}, /*#__PURE__*/React.createElement(View, {
style: styles.content
}, icon ? /*#__PURE__*/React.createElement(Icon, {
source: icon,
size: 24,
color: contentColor
}) : null, /*#__PURE__*/React.createElement(Text, {
variant: "labelLarge",
selectable: false,
numberOfLines: 1,
style: [styles.label, {
color: contentColor,
marginLeft: labelMargin,
...font
}],
maxFontSizeMultiplier: labelMaxFontSizeMultiplier
}, label)), right === null || right === void 0 ? void 0 : right({
color: contentColor
}))));
};
DrawerItem.displayName = 'Drawer.Item';
const styles = StyleSheet.create({
container: {
marginHorizontal: 10,
marginVertical: 4
},
v3Container: {
justifyContent: 'center',
height: 56,
marginLeft: 12,
marginRight: 12,
marginVertical: 0
},
wrapper: {
flexDirection: 'row',
alignItems: 'center',
padding: 8
},
v3Wrapper: {
marginLeft: 16,
marginRight: 24,
padding: 0
},
content: {
flex: 1,
flexDirection: 'row',
alignItems: 'center'
},
label: {
marginRight: 32
}
});
export default DrawerItem;
//# sourceMappingURL=DrawerItem.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StyleSheet","View","color","useInternalTheme","Icon","TouchableRipple","Text","DrawerItem","icon","label","active","disabled","theme","themeOverrides","rippleColor","customRippleColor","style","onPress","background","accessibilityLabel","right","labelMaxFontSizeMultiplier","hitSlop","rest","roundness","isV3","backgroundColor","colors","secondaryContainer","primary","alpha","rgb","string","undefined","contentColor","onSecondaryContainer","onSurfaceVariant","text","labelMargin","borderRadius","font","fonts","labelLarge","medium","createElement","borderless","styles","container","v3Container","accessibilityRole","accessibilityState","selected","wrapper","v3Wrapper","content","source","size","variant","selectable","numberOfLines","marginLeft","maxFontSizeMultiplier","displayName","create","marginHorizontal","marginVertical","justifyContent","height","marginRight","flexDirection","alignItems","padding","flex"],"sourceRoot":"../../../../src","sources":["components/Drawer/DrawerItem.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAKEC,UAAU,EACVC,IAAI,QAEC,cAAc;AAErB,OAAOC,KAAK,MAAM,OAAO;AAEzB,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,OAAOC,IAAI,MAAsB,SAAS;AAC1C,OAAOC,eAAe,MAEf,oCAAoC;AAC3C,OAAOC,IAAI,MAAM,oBAAoB;AAuDrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,UAAU,GAAGA,CAAC;EAClBC,IAAI;EACJC,KAAK;EACLC,MAAM;EACNC,QAAQ;EACRC,KAAK,EAAEC,cAAc;EACrBC,WAAW,EAAEC,iBAAiB;EAC9BC,KAAK;EACLC,OAAO;EACPC,UAAU;EACVC,kBAAkB;EAClBC,KAAK;EACLC,0BAA0B;EAC1BC,OAAO;EACP,GAAGC;AACE,CAAC,KAAK;EACX,MAAMX,KAAK,GAAGT,gBAAgB,CAACU,cAAc,CAAC;EAC9C,MAAM;IAAEW,SAAS;IAAEC;EAAK,CAAC,GAAGb,KAAK;EAEjC,MAAMc,eAAe,GAAGhB,MAAM,GAC1Be,IAAI,GACFb,KAAK,CAACe,MAAM,CAACC,kBAAkB,GAC/B1B,KAAK,CAACU,KAAK,CAACe,MAAM,CAACE,OAAO,CAAC,CAACC,KAAK,CAAC,IAAI,CAAC,CAACC,GAAG,CAAC,CAAC,CAACC,MAAM,CAAC,CAAC,GACxDC,SAAS;EACb,MAAMC,YAAY,GAAGxB,MAAM,GACvBe,IAAI,GACFb,KAAK,CAACe,MAAM,CAACQ,oBAAoB,GACjCvB,KAAK,CAACe,MAAM,CAACE,OAAO,GACtBJ,IAAI,GACJb,KAAK,CAACe,MAAM,CAACS,gBAAgB,GAC7BlC,KAAK,CAACU,KAAK,CAACe,MAAM,CAACU,IAAI,CAAC,CAACP,KAAK,CAAC,IAAI,CAAC,CAACC,GAAG,CAAC,CAAC,CAACC,MAAM,CAAC,CAAC;EAEvD,MAAMM,WAAW,GAAG9B,IAAI,GAAIiB,IAAI,GAAG,EAAE,GAAG,EAAE,GAAI,CAAC;EAC/C,MAAMc,YAAY,GAAG,CAACd,IAAI,GAAG,CAAC,GAAG,CAAC,IAAID,SAAS;EAC/C,MAAMV,WAAW,GAAGW,IAAI,GACpBvB,KAAK,CAACgC,YAAY,CAAC,CAACJ,KAAK,CAAC,IAAI,CAAC,CAACC,GAAG,CAAC,CAAC,CAACC,MAAM,CAAC,CAAC,GAC9CC,SAAS;EACb,MAAMO,IAAI,GAAGf,IAAI,GAAGb,KAAK,CAAC6B,KAAK,CAACC,UAAU,GAAG9B,KAAK,CAAC6B,KAAK,CAACE,MAAM;EAE/D,oBACE5C,KAAA,CAAA6C,aAAA,CAAC3C,IAAI,EAAKsB,IAAI,eACZxB,KAAA,CAAA6C,aAAA,CAACvC,eAAe;IACdwC,UAAU;IACVlC,QAAQ,EAAEA,QAAS;IACnBO,UAAU,EAAEA,UAAW;IACvBD,OAAO,EAAEA,OAAQ;IACjBD,KAAK,EAAE,CACL8B,MAAM,CAACC,SAAS,EAChB;MAAErB,eAAe;MAAEa;IAAa,CAAC,EACjCd,IAAI,IAAIqB,MAAM,CAACE,WAAW,EAC1BhC,KAAK,CACL;IACFiC,iBAAiB,EAAC,QAAQ;IAC1BC,kBAAkB,EAAE;MAAEC,QAAQ,EAAEzC;IAAO,CAAE;IACzCS,kBAAkB,EAAEA,kBAAmB;IACvCL,WAAW,EAAEC,iBAAiB,IAAID,WAAY;IAC9CF,KAAK,EAAEA,KAAM;IACbU,OAAO,EAAEA;EAAQ,gBAEjBvB,KAAA,CAAA6C,aAAA,CAAC3C,IAAI;IAACe,KAAK,EAAE,CAAC8B,MAAM,CAACM,OAAO,EAAE3B,IAAI,IAAIqB,MAAM,CAACO,SAAS;EAAE,gBACtDtD,KAAA,CAAA6C,aAAA,CAAC3C,IAAI;IAACe,KAAK,EAAE8B,MAAM,CAACQ;EAAQ,GACzB9C,IAAI,gBACHT,KAAA,CAAA6C,aAAA,CAACxC,IAAI;IAACmD,MAAM,EAAE/C,IAAK;IAACgD,IAAI,EAAE,EAAG;IAACtD,KAAK,EAAEgC;EAAa,CAAE,CAAC,GACnD,IAAI,eACRnC,KAAA,CAAA6C,aAAA,CAACtC,IAAI;IACHmD,OAAO,EAAC,YAAY;IACpBC,UAAU,EAAE,KAAM;IAClBC,aAAa,EAAE,CAAE;IACjB3C,KAAK,EAAE,CACL8B,MAAM,CAACrC,KAAK,EACZ;MACEP,KAAK,EAAEgC,YAAY;MACnB0B,UAAU,EAAEtB,WAAW;MACvB,GAAGE;IACL,CAAC,CACD;IACFqB,qBAAqB,EAAExC;EAA2B,GAEjDZ,KACG,CACF,CAAC,EAENW,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAG;IAAElB,KAAK,EAAEgC;EAAa,CAAC,CAC5B,CACS,CACb,CAAC;AAEX,CAAC;AAED3B,UAAU,CAACuD,WAAW,GAAG,aAAa;AAEtC,MAAMhB,MAAM,GAAG9C,UAAU,CAAC+D,MAAM,CAAC;EAC/BhB,SAAS,EAAE;IACTiB,gBAAgB,EAAE,EAAE;IACpBC,cAAc,EAAE;EAClB,CAAC;EACDjB,WAAW,EAAE;IACXkB,cAAc,EAAE,QAAQ;IACxBC,MAAM,EAAE,EAAE;IACVP,UAAU,EAAE,EAAE;IACdQ,WAAW,EAAE,EAAE;IACfH,cAAc,EAAE;EAClB,CAAC;EACDb,OAAO,EAAE;IACPiB,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,OAAO,EAAE;EACX,CAAC;EACDlB,SAAS,EAAE;IACTO,UAAU,EAAE,EAAE;IACdQ,WAAW,EAAE,EAAE;IACfG,OAAO,EAAE;EACX,CAAC;EACDjB,OAAO,EAAE;IACPkB,IAAI,EAAE,CAAC;IACPH,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE;EACd,CAAC;EACD7D,KAAK,EAAE;IACL2D,WAAW,EAAE;EACf;AACF,CAAC,CAAC;AAEF,eAAe7D,UAAU","ignoreList":[]}

View File

@@ -0,0 +1,96 @@
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import color from 'color';
import { useInternalTheme } from '../../core/theming';
import { MD3Colors } from '../../styles/themes/v3/tokens';
import Divider from '../Divider';
import Text from '../Typography/Text';
/**
* A component to group content inside a navigation drawer.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { Drawer } from 'react-native-paper';
*
* const MyComponent = () => {
* const [active, setActive] = React.useState('');
*
* return (
* <Drawer.Section title="Some title">
* <Drawer.Item
* label="First Item"
* active={active === 'first'}
* onPress={() => setActive('first')}
* />
* <Drawer.Item
* label="Second Item"
* active={active === 'second'}
* onPress={() => setActive('second')}
* />
* </Drawer.Section>
* );
* };
*
* export default MyComponent;
* ```
*/
const DrawerSection = ({
children,
title,
theme: themeOverrides,
style,
showDivider = true,
titleMaxFontSizeMultiplier,
...rest
}) => {
const theme = useInternalTheme(themeOverrides);
const {
isV3
} = theme;
const titleColor = isV3 ? theme.colors.onSurfaceVariant : color(theme.colors.text).alpha(0.54).rgb().string();
const titleMargin = isV3 ? 28 : 16;
const font = isV3 ? theme.fonts.titleSmall : theme.fonts.medium;
return /*#__PURE__*/React.createElement(View, _extends({
style: [styles.container, style]
}, rest), title && /*#__PURE__*/React.createElement(View, {
style: [styles.titleContainer, isV3 && styles.v3TitleContainer]
}, title && /*#__PURE__*/React.createElement(Text, {
variant: "titleSmall",
numberOfLines: 1,
style: [{
color: titleColor,
marginLeft: titleMargin,
...font
}],
maxFontSizeMultiplier: titleMaxFontSizeMultiplier
}, title)), children, showDivider && /*#__PURE__*/React.createElement(Divider, _extends({}, isV3 && {
horizontalInset: true,
bold: true
}, {
style: [styles.divider, isV3 && styles.v3Divider],
theme: theme
})));
};
DrawerSection.displayName = 'Drawer.Section';
const styles = StyleSheet.create({
container: {
marginBottom: 4
},
titleContainer: {
height: 40,
justifyContent: 'center'
},
v3TitleContainer: {
height: 56
},
divider: {
marginTop: 4
},
v3Divider: {
backgroundColor: MD3Colors.neutralVariant50
}
});
export default DrawerSection;
//# sourceMappingURL=DrawerSection.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StyleSheet","View","color","useInternalTheme","MD3Colors","Divider","Text","DrawerSection","children","title","theme","themeOverrides","style","showDivider","titleMaxFontSizeMultiplier","rest","isV3","titleColor","colors","onSurfaceVariant","text","alpha","rgb","string","titleMargin","font","fonts","titleSmall","medium","createElement","_extends","styles","container","titleContainer","v3TitleContainer","variant","numberOfLines","marginLeft","maxFontSizeMultiplier","horizontalInset","bold","divider","v3Divider","displayName","create","marginBottom","height","justifyContent","marginTop","backgroundColor","neutralVariant50"],"sourceRoot":"../../../../src","sources":["components/Drawer/DrawerSection.tsx"],"mappings":"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","ignoreList":[]}