@movalib/movalib-commons 1.59.39 → 1.60.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/devIndex.tsx +0 -1
- package/dist/src/DialogForgotPassword.js +3 -1
- package/dist/src/MovaLogin.d.ts +2 -2
- package/dist/src/MovaLogin.js +40 -19
- package/dist/src/MovaSignUp.js +17 -7
- package/dist/src/helpers/Tools.d.ts +4 -3
- package/dist/src/helpers/Tools.js +120 -50
- package/dist/src/helpers/Validator.js +3 -2
- package/index.ts +1 -1
- package/package.json +6 -2
- package/src/DialogForgotPassword.tsx +5 -1
- package/src/MovaLogin.tsx +28 -3
- package/src/MovaSignUp.tsx +29 -13
- package/src/components/QrCodePLVContainer/QrCodePLVContainer.tsx +1 -1
- package/src/helpers/Tools.ts +214 -124
- package/src/helpers/Validator.ts +28 -26
package/devIndex.tsx
CHANGED
|
@@ -26,7 +26,6 @@ import GaragePLV from './src/GaragePLV';
|
|
|
26
26
|
import AddressFields from './src/AddressFields';
|
|
27
27
|
import IbanInput from './src/IbanInput';
|
|
28
28
|
import GenderSelector from './src/GenderSelector';
|
|
29
|
-
import {VehicleTire} from "./index";
|
|
30
29
|
import MovaVehicleTireField from "./src/MovaVehicleTireField";
|
|
31
30
|
|
|
32
31
|
const App = () => {
|
|
@@ -27,7 +27,9 @@ var DialogForgotPassword = function (_a) {
|
|
|
27
27
|
return ((0, jsx_runtime_1.jsxs)(material_1.Dialog, __assign({ open: openForgotPassword, onClose: handleOnClose, "aria-labelledby": "forgot-password-dialog-title", "aria-describedby": "forgot-password-dialog-description" }, { children: [(0, jsx_runtime_1.jsx)(material_1.DialogTitle, __assign({ id: "forgot-password-title" }, { children: "R\u00E9cup\u00E9ration du mot de passe" })), (0, jsx_runtime_1.jsxs)(material_1.DialogContent, { children: [(0, jsx_runtime_1.jsx)(material_1.DialogContentText, __assign({ id: "forgot-password-dialog-description", sx: { mb: 2 } }, { children: movaAppType === Enums_1.MovaAppType.GARAGE ?
|
|
28
28
|
"Saisissez votre email pour procéder à la réinitialisation de votre mot de passe."
|
|
29
29
|
:
|
|
30
|
-
"Saisissez votre n° de téléphone ou votre email pour procéder à la réinitialisation de votre mot de passe." })), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", autoFocus: true, required: true, fullWidth: true, id: movaAppType === Enums_1.MovaAppType.GARAGE ? "email" : "phoneNumberEmail", label: movaAppType === Enums_1.MovaAppType.GARAGE ? "Adresse email" : "N° de téléphone ou adresse email", name: movaAppType === Enums_1.MovaAppType.GARAGE ? "email" : "phoneNumberEmail", autoComplete: "email", onChange: function (e) { return handleInputChange(e); }, value: movaAppType === Enums_1.MovaAppType.GARAGE ? form.email.value : form.phoneNumberEmail.value, error: movaAppType === Enums_1.MovaAppType.GARAGE ? !form.email.isValid : !form.phoneNumberEmail.isValid, helperText: movaAppType === Enums_1.MovaAppType.GARAGE
|
|
30
|
+
"Saisissez votre n° de téléphone ou votre email pour procéder à la réinitialisation de votre mot de passe." })), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", autoFocus: true, required: true, fullWidth: true, id: movaAppType === Enums_1.MovaAppType.GARAGE ? "email" : "phoneNumberEmail", label: movaAppType === Enums_1.MovaAppType.GARAGE ? "Adresse email" : "N° de téléphone ou adresse email", name: movaAppType === Enums_1.MovaAppType.GARAGE ? "email" : "phoneNumberEmail", autoComplete: "email", onChange: function (e) { return handleInputChange(e); }, value: movaAppType === Enums_1.MovaAppType.GARAGE ? form.email.value : form.phoneNumberEmail.value, error: movaAppType === Enums_1.MovaAppType.GARAGE ? !form.email.isValid : !form.phoneNumberEmail.isValid, helperText: movaAppType === Enums_1.MovaAppType.GARAGE
|
|
31
|
+
? form.email.error
|
|
32
|
+
: form.phoneNumberEmail.error || "Saisir l’indicatif pour un numéro étranger (ex : +32 …)" })] }), (0, jsx_runtime_1.jsx)(material_1.DialogActions, { children: (0, jsx_runtime_1.jsx)(material_1.Button, __assign({ onClick: function (e) { return handleSubmitForgotPassword(e); }, color: "primary", disabled: movaAppType === Enums_1.MovaAppType.GARAGE ? !(form.email.value && (0, Validator_1.validateEmail)(form.email.value))
|
|
31
33
|
: !(form.phoneNumberEmail.value), sx: { ml: 1 } }, { children: "Envoyer ma demande" })) })] })));
|
|
32
34
|
};
|
|
33
35
|
exports.default = DialogForgotPassword;
|
package/dist/src/MovaLogin.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FunctionComponent, ReactNode } from "react";
|
|
2
1
|
import { AlertColor } from "@mui/material";
|
|
3
|
-
import {
|
|
2
|
+
import { FunctionComponent, ReactNode } from "react";
|
|
4
3
|
import { MovaAppType } from "./helpers/Enums";
|
|
4
|
+
import { MovaLoginForm } from "./helpers/Types";
|
|
5
5
|
/**
|
|
6
6
|
* Propriétés du composant
|
|
7
7
|
* movaAppType : type d'application Movalib au sein de laquelle le composant est injectée
|
package/dist/src/MovaLogin.js
CHANGED
|
@@ -51,25 +51,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
51
51
|
};
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
53
|
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
54
|
-
var
|
|
54
|
+
var Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
|
|
55
|
+
var VisibilityOff_1 = __importDefault(require("@mui/icons-material/VisibilityOff"));
|
|
55
56
|
var lab_1 = require("@mui/lab");
|
|
56
|
-
var
|
|
57
|
-
var
|
|
57
|
+
var material_1 = require("@mui/material");
|
|
58
|
+
var InputAdornment_1 = __importDefault(require("@mui/material/InputAdornment"));
|
|
59
|
+
var libphonenumber_js_1 = require("libphonenumber-js");
|
|
60
|
+
var react_1 = require("react");
|
|
61
|
+
var react_router_dom_1 = require("react-router-dom");
|
|
62
|
+
var DialogForgotPassword_1 = __importDefault(require("./DialogForgotPassword"));
|
|
63
|
+
var MovaCopyright_1 = __importDefault(require("./MovaCopyright"));
|
|
64
|
+
var leaf_green_large_png_1 = __importDefault(require("./assets/images/leaf_green_large.png"));
|
|
65
|
+
var leaf_pink_large_png_1 = __importDefault(require("./assets/images/leaf_pink_large.png"));
|
|
58
66
|
var logo_admin_large_png_1 = __importDefault(require("./assets/images/logo/logo_admin_large.png"));
|
|
67
|
+
var logo_large_border_png_1 = __importDefault(require("./assets/images/logo/logo_large_border.png"));
|
|
59
68
|
var logo_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_large_dm.png"));
|
|
69
|
+
var logo_pro_large_border_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large_border.png"));
|
|
60
70
|
var logo_pro_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large_dm.png"));
|
|
61
|
-
var leaf_green_large_png_1 = __importDefault(require("./assets/images/leaf_green_large.png"));
|
|
62
|
-
var leaf_pink_large_png_1 = __importDefault(require("./assets/images/leaf_pink_large.png"));
|
|
63
|
-
var material_1 = require("@mui/material");
|
|
64
|
-
var MovaCopyright_1 = __importDefault(require("./MovaCopyright"));
|
|
65
71
|
var Enums_1 = require("./helpers/Enums");
|
|
66
|
-
var Validator_1 = require("./helpers/Validator");
|
|
67
72
|
var Tools_1 = require("./helpers/Tools");
|
|
68
|
-
var
|
|
69
|
-
var InputAdornment_1 = __importDefault(require("@mui/material/InputAdornment"));
|
|
70
|
-
var Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
|
|
71
|
-
var VisibilityOff_1 = __importDefault(require("@mui/icons-material/VisibilityOff"));
|
|
72
|
-
var DialogForgotPassword_1 = __importDefault(require("./DialogForgotPassword"));
|
|
73
|
+
var Validator_1 = require("./helpers/Validator");
|
|
73
74
|
// Permet de centrer le contenu de l'application
|
|
74
75
|
var styles = {
|
|
75
76
|
display: 'flex',
|
|
@@ -125,8 +126,23 @@ var MovaLogin = function (_a) {
|
|
|
125
126
|
// Validator pour l'email
|
|
126
127
|
newForm.email = (0, Tools_1.validateField)(form.email, Validator_1.validateEmail, 'Adresse email invalide');
|
|
127
128
|
}
|
|
129
|
+
/* if(movaAppType === MovaAppType.INDIVIDUAL){
|
|
130
|
+
newForm.phoneNumberEmail = validateField(form.phoneNumberEmail, value => !!value, 'Champ obligatoire');
|
|
131
|
+
} */
|
|
128
132
|
if (movaAppType === Enums_1.MovaAppType.INDIVIDUAL) {
|
|
129
|
-
newForm.phoneNumberEmail = (0, Tools_1.validateField)(form.phoneNumberEmail, function (value) {
|
|
133
|
+
newForm.phoneNumberEmail = (0, Tools_1.validateField)(form.phoneNumberEmail, function (value) {
|
|
134
|
+
var _a;
|
|
135
|
+
if (!value)
|
|
136
|
+
return false;
|
|
137
|
+
// Si c’est un email valide => OK
|
|
138
|
+
if ((0, Validator_1.validateEmail)(value))
|
|
139
|
+
return true;
|
|
140
|
+
// Remplace 00 par + si le numéro commence par 00 (pour compatibilité avec libphonenumber-js)
|
|
141
|
+
var normalizedValue = value.startsWith('00') ? value.replace(/^00/, '+') : value;
|
|
142
|
+
// Si le numéro commence par + ou 00, tentative de parsing direct. Format local, Pays par défaut : FR
|
|
143
|
+
var phoneNumber = (0, libphonenumber_js_1.parsePhoneNumberFromString)(normalizedValue, normalizedValue.startsWith('+') || normalizedValue.startsWith('00') ? undefined : 'FR');
|
|
144
|
+
return (_a = phoneNumber === null || phoneNumber === void 0 ? void 0 : phoneNumber.isValid()) !== null && _a !== void 0 ? _a : false;
|
|
145
|
+
}, 'Email ou numéro de téléphone invalide');
|
|
130
146
|
}
|
|
131
147
|
newForm.password = (0, Tools_1.validateField)(form.password, function (value) { return !!value; }, 'Champ obligatoire');
|
|
132
148
|
// Validator pour le mot de passe
|
|
@@ -217,20 +233,23 @@ var MovaLogin = function (_a) {
|
|
|
217
233
|
</Dialog>
|
|
218
234
|
);
|
|
219
235
|
} */
|
|
220
|
-
return ((0, jsx_runtime_1.jsxs)("div", __assign({ style: styles }, { children: [(0, jsx_runtime_1.jsx)("img", { src: leaf_green_large_png_1.default, style: {
|
|
236
|
+
return ((0, jsx_runtime_1.jsxs)("div", __assign({ style: styles }, { children: [(0, jsx_runtime_1.jsx)("img", { src: leaf_green_large_png_1.default, style: {
|
|
237
|
+
position: 'fixed',
|
|
221
238
|
float: 'left',
|
|
222
239
|
width: '250px',
|
|
223
240
|
height: '400px',
|
|
224
241
|
top: '-20%',
|
|
225
242
|
left: '0%',
|
|
226
243
|
opacity: '0.3',
|
|
227
|
-
zIndex: -8
|
|
244
|
+
zIndex: -8
|
|
245
|
+
}, alt: 'Feuille Verte Movalib' }), (0, jsx_runtime_1.jsxs)(material_1.Container, __assign({ component: "main", maxWidth: "xs" }, { children: [(0, jsx_runtime_1.jsx)(material_1.CssBaseline, {}), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: {
|
|
228
246
|
marginTop: 6,
|
|
229
247
|
display: 'flex',
|
|
230
248
|
flexDirection: 'column',
|
|
231
249
|
alignItems: 'center',
|
|
232
250
|
} }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '80%' } }), headerText && (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "button", sx: { pt: 3, width: '100%' } }, { children: headerText })), (0, jsx_runtime_1.jsx)("br", {})] })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ component: "form", onSubmit: handleSubmit, noValidate: true, sx: { mt: 1 } }, { children: [movaAppType === Enums_1.MovaAppType.INDIVIDUAL &&
|
|
233
|
-
(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "phoneNumberEmail", label: "N\u00B0 de t\u00E9l\u00E9phone ou adresse email", name: "phoneNumberEmail", autoFocus: true, onChange: function (e) { return handleInputChange(e); }, value: form.phoneNumberEmail.value, error: !form.phoneNumberEmail.isValid, helperText: form.phoneNumberEmail.error
|
|
251
|
+
(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "phoneNumberEmail", label: "N\u00B0 de t\u00E9l\u00E9phone ou adresse email", name: "phoneNumberEmail", autoFocus: true, onChange: function (e) { return handleInputChange(e); }, value: form.phoneNumberEmail.value, error: !form.phoneNumberEmail.isValid, helperText: form.phoneNumberEmail.error ||
|
|
252
|
+
"Saisir l’indicatif pour un numéro étranger (ex : +32 …)", sx: {
|
|
234
253
|
'& .MuiOutlinedInput-notchedOutline': {
|
|
235
254
|
borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
|
|
236
255
|
}
|
|
@@ -246,13 +265,15 @@ var MovaLogin = function (_a) {
|
|
|
246
265
|
borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
|
|
247
266
|
}
|
|
248
267
|
} }), (0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { value: "remember", color: "primary" }), label: "Se souvenir de moi" }), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, __assign({ loading: loading, type: "submit", fullWidth: true, variant: "contained", sx: { mt: 3, mb: 2, backgroundColor: darkMode ? theme.palette.primary.dark : theme.palette.primary.main } }, { children: (0, jsx_runtime_1.jsx)("span", { children: "Se connecter" }) })), movaAppType === Enums_1.MovaAppType.INDIVIDUAL && (0, jsx_runtime_1.jsx)(material_1.Button, __assign({ fullWidth: true, variant: "outlined", onClick: function (e) { return handleOnClickSignUp(); }, sx: { mb: 2, color: theme.palette.primary.dark } }, { children: (0, jsx_runtime_1.jsx)("span", { children: "CR\u00C9ER MON COMPTE" }) })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ container: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ variant: "body2", color: "text.secondary", onClick: function (e) { return handleOnClickForgotPassword(); }, sx: { cursor: 'pointer' } }, { children: "Mot de passe oubli\u00E9 ?" })) })) }))] })), (0, jsx_runtime_1.jsx)(MovaCopyright_1.default, { sx: { mt: 8, mb: 1 } }), version && (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: 'body2', color: theme.palette.grey[200], sx: { textAlign: 'center' } }, { children: version })), openForgotPassword &&
|
|
249
|
-
(0, jsx_runtime_1.jsx)(DialogForgotPassword_1.default, { openForgotPassword: openForgotPassword, setOpenForgotPassword: setOpenForgotPassword, movaAppType: movaAppType, form: form, handleInputChange: handleInputChange, handleSubmitForgotPassword: handleSubmitForgotPassword })] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: {
|
|
268
|
+
(0, jsx_runtime_1.jsx)(DialogForgotPassword_1.default, { openForgotPassword: openForgotPassword, setOpenForgotPassword: setOpenForgotPassword, movaAppType: movaAppType, form: form, handleInputChange: handleInputChange, handleSubmitForgotPassword: handleSubmitForgotPassword })] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: {
|
|
269
|
+
position: 'fixed',
|
|
250
270
|
float: 'right',
|
|
251
271
|
width: '250px',
|
|
252
272
|
height: '400px',
|
|
253
273
|
bottom: '-20%',
|
|
254
274
|
right: '0%',
|
|
255
275
|
opacity: '0.3',
|
|
256
|
-
zIndex: '-10'
|
|
276
|
+
zIndex: '-10'
|
|
277
|
+
}, alt: 'Feuille Rose Movalib' })] })));
|
|
257
278
|
};
|
|
258
279
|
exports.default = MovaLogin;
|
package/dist/src/MovaSignUp.js
CHANGED
|
@@ -70,6 +70,7 @@ var Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
|
|
|
70
70
|
var VisibilityOff_1 = __importDefault(require("@mui/icons-material/VisibilityOff"));
|
|
71
71
|
var Info_1 = __importDefault(require("@mui/icons-material/Info"));
|
|
72
72
|
var UserService_1 = __importDefault(require("./services/UserService"));
|
|
73
|
+
var libphonenumber_js_1 = require("libphonenumber-js");
|
|
73
74
|
// ATTENTION : s'assurer de la présence des documents suivants à la racine du composant porteur (dossier 'public')
|
|
74
75
|
var CGUPath = "https://s3.eu-west-3.amazonaws.com/legal.movalib.com/Movalib_CGU.pdf";
|
|
75
76
|
// Permet de centrer le contenu de l'application
|
|
@@ -119,13 +120,20 @@ var MovaSignUp = function (_a) {
|
|
|
119
120
|
var fieldValue = e.target.value;
|
|
120
121
|
// On autorise uniquement les chiffre pour le n° de téléphone
|
|
121
122
|
if (fieldName == "phoneNumber") {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
// Nettoyage : on autorise chiffres + éventuellement un "+" en début
|
|
124
|
+
var cleaned = fieldValue.trim().replace(/[^\d+]/g, '');
|
|
125
|
+
// Normalisation : 0033... → +33...
|
|
126
|
+
if (cleaned.startsWith('00')) {
|
|
127
|
+
cleaned = cleaned.replace(/^00/, '+');
|
|
126
128
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
// Parsing avec FR par défaut si local
|
|
130
|
+
var parsed = (0, libphonenumber_js_1.parsePhoneNumberFromString)(cleaned, cleaned.startsWith('+') ? undefined : 'FR');
|
|
131
|
+
// Mise à jour du champ
|
|
132
|
+
if (parsed === null || parsed === void 0 ? void 0 : parsed.isValid()) {
|
|
133
|
+
var e164 = parsed.number; // format +33...
|
|
134
|
+
//fieldValue = e164;
|
|
135
|
+
// Vérification de l'existence du compte
|
|
136
|
+
UserService_1.default.existsByPhoneNumber(e164).then(function (response) {
|
|
129
137
|
if (response && response.data) {
|
|
130
138
|
if (response.data.isActive === false) {
|
|
131
139
|
setUserExist(true);
|
|
@@ -143,6 +151,7 @@ var MovaSignUp = function (_a) {
|
|
|
143
151
|
});
|
|
144
152
|
}
|
|
145
153
|
else {
|
|
154
|
+
// Si numéro invalide ou incomplet, on réinitialise les flags
|
|
146
155
|
setUserExist(false);
|
|
147
156
|
setUserIsAlreadyActive(false);
|
|
148
157
|
}
|
|
@@ -254,7 +263,8 @@ var MovaSignUp = function (_a) {
|
|
|
254
263
|
'& .MuiOutlinedInput-notchedOutline': {
|
|
255
264
|
borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
|
|
256
265
|
}
|
|
257
|
-
} }), usePhoneNumber && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { type: "tel", margin: "normal", required: true, fullWidth: true, id: "phoneNumber", label: "N\u00B0 de t\u00E9l\u00E9phone", name: "phoneNumber", autoComplete: "tel", disabled: userToEdit && userToEdit.phoneNumber ? true : false, onChange: function (e) { return handleInputChange(e); }, value: userForm.phoneNumber.value, error: Boolean(userForm.phoneNumber.error), helperText: userForm.phoneNumber.error
|
|
266
|
+
} }), usePhoneNumber && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { type: "tel", margin: "normal", required: true, fullWidth: true, id: "phoneNumber", label: "N\u00B0 de t\u00E9l\u00E9phone", name: "phoneNumber", autoComplete: "tel", disabled: userToEdit && userToEdit.phoneNumber ? true : false, onChange: function (e) { return handleInputChange(e); }, value: userForm.phoneNumber.value, error: Boolean(userForm.phoneNumber.error), helperText: userForm.phoneNumber.error ||
|
|
267
|
+
"Saisir l’indicatif pour un numéro étranger (ex : +32 …)", InputProps: {
|
|
258
268
|
endAdornment: ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, __assign({ position: "end" }, { children: !userExist && (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ edge: "end", onClick: function () { return setOpenPhoneNumberInfo(!openPhoneNumberInfo); } }, { children: (0, jsx_runtime_1.jsx)(Info_1.default, {}) })) }))),
|
|
259
269
|
} }), openPhoneNumberInfo && !userExist && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: "info", variant: 'standard' }, { children: "Entrez le num\u00E9ro de t\u00E9l\u00E9phone que vous avez utilis\u00E9 pour r\u00E9server, afin de suivre facilement vos rendez-vous." })), userExist && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: "success", variant: 'standard' }, { children: "Rendez-vous trouv\u00E9(s) pour ce num\u00E9ro ! Vous pourrez le(s) consulter apr\u00E8s avoir cr\u00E9\u00E9 votre compte." })), userIsAlreadyActive && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: "error", sx: { marginTop: '5px' }, variant: 'standard' }, { children: "Il semble qu\u2019un compte existe d\u00E9j\u00E0 avec ce num\u00E9ro. Connectez-vous ou utilisez \"Mot de passe oubli\u00E9\" pour y acc\u00E9der facilement." }))] }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", disabled: userToEdit && userToEdit.email ? true : false, onChange: function (e) { return handleInputChange(e); }, value: userForm.email.value, error: !userForm.email.isValid, helperText: userForm.email.error, sx: {
|
|
260
270
|
'& .MuiOutlinedInput-notchedOutline': {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import VehicleTire from "../models/VehicleTire";
|
|
2
|
-
import { MovaFormField, MovaInterval } from "./Types";
|
|
3
1
|
import { CSSProperties } from "react";
|
|
4
|
-
import { DayOfWeek, PartsApplicationType } from "./Enums";
|
|
5
2
|
import Schedule from "../models/Schedule";
|
|
3
|
+
import VehicleTire from "../models/VehicleTire";
|
|
4
|
+
import { DayOfWeek, PartsApplicationType } from "./Enums";
|
|
5
|
+
import { MovaFormField, MovaInterval } from "./Types";
|
|
6
6
|
export declare const getApplicationsShortLabels: (applications: PartsApplicationType[] | undefined) => string;
|
|
7
7
|
export declare const flexStart: CSSProperties;
|
|
8
8
|
export declare const isSafariOniOS: () => boolean;
|
|
9
|
+
export declare const isInvalidMobileNumber: (phoneNumber?: string) => boolean;
|
|
9
10
|
export declare const FR_WEEK_DAYS: string[];
|
|
10
11
|
export declare const getDayOfWeekLabel: (day: DayOfWeek) => string | undefined;
|
|
11
12
|
export declare const getDayOfWeekIndex: (day: DayOfWeek) => number;
|
|
@@ -1,28 +1,67 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateField = exports.formatVehicleTireStr = exports.formatVehicleTire = exports.formatFrenchVehiclePlate = exports.isEmpty = exports.flexCenter = exports.flexEnd = exports.getApplicationShortLabel = exports.capitalizeFirstLetter = exports.flexLeftRow = exports.getFrenchDayLabel = exports.getDayOfWeek = exports.findScheduleByDayOfWeek = exports.formatTime = exports.getFormattedIntervals = exports.getFormattedSchedule = exports.formatPhoneNumber = exports.getDayOfWeekIndex = exports.getDayOfWeekLabel = exports.FR_WEEK_DAYS = exports.isSafariOniOS = exports.flexStart = exports.getApplicationsShortLabels = void 0;
|
|
6
|
+
exports.validateField = exports.formatVehicleTireStr = exports.formatVehicleTire = exports.formatFrenchVehiclePlate = exports.isEmpty = exports.flexCenter = exports.flexEnd = exports.getApplicationShortLabel = exports.capitalizeFirstLetter = exports.flexLeftRow = exports.getFrenchDayLabel = exports.getDayOfWeek = exports.findScheduleByDayOfWeek = exports.formatTime = exports.getFormattedIntervals = exports.getFormattedSchedule = exports.formatPhoneNumber = exports.getDayOfWeekIndex = exports.getDayOfWeekLabel = exports.FR_WEEK_DAYS = exports.isInvalidMobileNumber = exports.isSafariOniOS = exports.flexStart = exports.getApplicationsShortLabels = void 0;
|
|
7
|
+
var max_1 = __importDefault(require("libphonenumber-js/max"));
|
|
4
8
|
var Enums_1 = require("./Enums");
|
|
5
9
|
var getApplicationsShortLabels = function (applications) {
|
|
6
10
|
if (!applications) {
|
|
7
|
-
return
|
|
11
|
+
return "";
|
|
8
12
|
}
|
|
9
|
-
return applications.map(exports.getApplicationShortLabel).join(
|
|
13
|
+
return applications.map(exports.getApplicationShortLabel).join(" + ");
|
|
10
14
|
};
|
|
11
15
|
exports.getApplicationsShortLabels = getApplicationsShortLabels;
|
|
12
16
|
exports.flexStart = {
|
|
13
|
-
display:
|
|
14
|
-
justifyContent:
|
|
15
|
-
alignItems:
|
|
17
|
+
display: "flex",
|
|
18
|
+
justifyContent: "start",
|
|
19
|
+
alignItems: "center",
|
|
16
20
|
};
|
|
17
21
|
var isSafariOniOS = function () {
|
|
18
22
|
var userAgent = window.navigator.userAgent;
|
|
19
|
-
var iOS = !!userAgent.match(/iPad/i) ||
|
|
23
|
+
var iOS = !!userAgent.match(/iPad/i) ||
|
|
24
|
+
!!userAgent.match(/iPhone/i) ||
|
|
25
|
+
!!userAgent.match(/iPod/i);
|
|
20
26
|
var webkit = !!userAgent.match(/WebKit/i);
|
|
21
27
|
var criOS = !!userAgent.match(/CriOS/i);
|
|
22
28
|
return iOS && webkit && !criOS;
|
|
23
29
|
};
|
|
24
30
|
exports.isSafariOniOS = isSafariOniOS;
|
|
25
|
-
|
|
31
|
+
var isInvalidMobileNumber = function (phoneNumber) {
|
|
32
|
+
var _a;
|
|
33
|
+
if (phoneNumber === void 0) { phoneNumber = ""; }
|
|
34
|
+
if (!phoneNumber || typeof phoneNumber !== "string")
|
|
35
|
+
return true;
|
|
36
|
+
// Nettoyage : supprime les espaces et convertit "00..." en "+..."
|
|
37
|
+
var cleaned = phoneNumber.replace(/\s+/g, "").replace(/^00/, "+");
|
|
38
|
+
// Si le numéro ne commence pas par +, on assume que c'est un numéro local français
|
|
39
|
+
var cleanedPhoneNumber = cleaned.startsWith("+")
|
|
40
|
+
? cleaned
|
|
41
|
+
: "+33".concat(cleaned.replace(/^0/, ""));
|
|
42
|
+
try {
|
|
43
|
+
var parsed = (0, max_1.default)(cleanedPhoneNumber);
|
|
44
|
+
var type = (_a = parsed === null || parsed === void 0 ? void 0 : parsed.getType) === null || _a === void 0 ? void 0 : _a.call(parsed);
|
|
45
|
+
console.log(type);
|
|
46
|
+
console.log(parsed === null || parsed === void 0 ? void 0 : parsed.isValid());
|
|
47
|
+
console.log(["MOBILE", "MOBILE_OR_FIXED_LINE"].includes(type || ""));
|
|
48
|
+
return !((parsed === null || parsed === void 0 ? void 0 : parsed.isValid()) &&
|
|
49
|
+
["MOBILE", "MOBILE_OR_FIXED_LINE"].includes(type || ""));
|
|
50
|
+
}
|
|
51
|
+
catch (_b) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.isInvalidMobileNumber = isInvalidMobileNumber;
|
|
56
|
+
exports.FR_WEEK_DAYS = [
|
|
57
|
+
"Lundi",
|
|
58
|
+
"Mardi",
|
|
59
|
+
"Mercredi",
|
|
60
|
+
"Jeudi",
|
|
61
|
+
"Vendredi",
|
|
62
|
+
"Samedi",
|
|
63
|
+
"Dimanche",
|
|
64
|
+
];
|
|
26
65
|
var getDayOfWeekLabel = function (day) {
|
|
27
66
|
if (day) {
|
|
28
67
|
return exports.FR_WEEK_DAYS[(0, exports.getDayOfWeekIndex)(day)];
|
|
@@ -84,8 +123,12 @@ var sortMovaIntervals = function (intervals) {
|
|
|
84
123
|
if (intervals) {
|
|
85
124
|
return intervals.sort(function (a, b) {
|
|
86
125
|
// Convertir en Date si nécessaire
|
|
87
|
-
var startTimeA = a.startTime instanceof Date
|
|
88
|
-
|
|
126
|
+
var startTimeA = a.startTime instanceof Date
|
|
127
|
+
? a.startTime
|
|
128
|
+
: new Date(a.startTime);
|
|
129
|
+
var startTimeB = b.startTime instanceof Date
|
|
130
|
+
? b.startTime
|
|
131
|
+
: new Date(b.startTime);
|
|
89
132
|
// Gérer les valeurs nulles
|
|
90
133
|
if (startTimeA === null && startTimeB === null)
|
|
91
134
|
return 0;
|
|
@@ -106,32 +149,46 @@ var findScheduleByDayOfWeek = function (schedules, dayIndex) {
|
|
|
106
149
|
exports.findScheduleByDayOfWeek = findScheduleByDayOfWeek;
|
|
107
150
|
var getDayOfWeek = function (index) {
|
|
108
151
|
switch (index) {
|
|
109
|
-
case 0:
|
|
110
|
-
|
|
111
|
-
case
|
|
112
|
-
|
|
113
|
-
case
|
|
114
|
-
|
|
115
|
-
case
|
|
152
|
+
case 0:
|
|
153
|
+
return Enums_1.DayOfWeek.MONDAY;
|
|
154
|
+
case 1:
|
|
155
|
+
return Enums_1.DayOfWeek.TUESDAY;
|
|
156
|
+
case 2:
|
|
157
|
+
return Enums_1.DayOfWeek.WEDNESDAY;
|
|
158
|
+
case 3:
|
|
159
|
+
return Enums_1.DayOfWeek.THURSDAY;
|
|
160
|
+
case 4:
|
|
161
|
+
return Enums_1.DayOfWeek.FRIDAY;
|
|
162
|
+
case 5:
|
|
163
|
+
return Enums_1.DayOfWeek.SATURDAY;
|
|
164
|
+
case 6:
|
|
165
|
+
return Enums_1.DayOfWeek.SUNDAY;
|
|
116
166
|
}
|
|
117
167
|
};
|
|
118
168
|
exports.getDayOfWeek = getDayOfWeek;
|
|
119
169
|
var getFrenchDayLabel = function (day) {
|
|
120
170
|
switch (day) {
|
|
121
|
-
case Enums_1.DayOfWeek.MONDAY:
|
|
122
|
-
|
|
123
|
-
case Enums_1.DayOfWeek.
|
|
124
|
-
|
|
125
|
-
case Enums_1.DayOfWeek.
|
|
126
|
-
|
|
127
|
-
case Enums_1.DayOfWeek.
|
|
171
|
+
case Enums_1.DayOfWeek.MONDAY:
|
|
172
|
+
return "Lundi";
|
|
173
|
+
case Enums_1.DayOfWeek.TUESDAY:
|
|
174
|
+
return "Mardi";
|
|
175
|
+
case Enums_1.DayOfWeek.WEDNESDAY:
|
|
176
|
+
return "Mercredi";
|
|
177
|
+
case Enums_1.DayOfWeek.THURSDAY:
|
|
178
|
+
return "Jeudi";
|
|
179
|
+
case Enums_1.DayOfWeek.FRIDAY:
|
|
180
|
+
return "Vendredi";
|
|
181
|
+
case Enums_1.DayOfWeek.SATURDAY:
|
|
182
|
+
return "Samedi";
|
|
183
|
+
case Enums_1.DayOfWeek.SUNDAY:
|
|
184
|
+
return "Dimanche";
|
|
128
185
|
}
|
|
129
186
|
};
|
|
130
187
|
exports.getFrenchDayLabel = getFrenchDayLabel;
|
|
131
188
|
exports.flexLeftRow = {
|
|
132
|
-
display:
|
|
133
|
-
justifyContent:
|
|
134
|
-
alignItems:
|
|
189
|
+
display: "flex",
|
|
190
|
+
justifyContent: "start",
|
|
191
|
+
alignItems: "center",
|
|
135
192
|
};
|
|
136
193
|
var capitalizeFirstLetter = function (str) {
|
|
137
194
|
if (str.length === 0) {
|
|
@@ -145,30 +202,40 @@ exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
|
145
202
|
var getApplicationShortLabel = function (application) {
|
|
146
203
|
if (application) {
|
|
147
204
|
switch (application) {
|
|
148
|
-
case Enums_1.PartsApplicationType.FRONT:
|
|
149
|
-
|
|
150
|
-
case Enums_1.PartsApplicationType.
|
|
151
|
-
|
|
152
|
-
case Enums_1.PartsApplicationType.
|
|
153
|
-
|
|
154
|
-
case Enums_1.PartsApplicationType.
|
|
155
|
-
|
|
156
|
-
case Enums_1.PartsApplicationType.
|
|
157
|
-
|
|
205
|
+
case Enums_1.PartsApplicationType.FRONT:
|
|
206
|
+
return "AV";
|
|
207
|
+
case Enums_1.PartsApplicationType.REAR:
|
|
208
|
+
return "AR";
|
|
209
|
+
case Enums_1.PartsApplicationType.FRONT_REAR:
|
|
210
|
+
return "AV + AR";
|
|
211
|
+
case Enums_1.PartsApplicationType.LEFT:
|
|
212
|
+
return "G";
|
|
213
|
+
case Enums_1.PartsApplicationType.RIGHT:
|
|
214
|
+
return "D";
|
|
215
|
+
case Enums_1.PartsApplicationType.LEFT_RIGHT:
|
|
216
|
+
return "G + D";
|
|
217
|
+
case Enums_1.PartsApplicationType.FRONT_LEFT:
|
|
218
|
+
return "AVG";
|
|
219
|
+
case Enums_1.PartsApplicationType.FRONT_RIGHT:
|
|
220
|
+
return "AVD";
|
|
221
|
+
case Enums_1.PartsApplicationType.REAR_LEFT:
|
|
222
|
+
return "ARG";
|
|
223
|
+
case Enums_1.PartsApplicationType.REAR_RIGHT:
|
|
224
|
+
return "ARD";
|
|
158
225
|
}
|
|
159
226
|
}
|
|
160
227
|
return "";
|
|
161
228
|
};
|
|
162
229
|
exports.getApplicationShortLabel = getApplicationShortLabel;
|
|
163
230
|
exports.flexEnd = {
|
|
164
|
-
display:
|
|
165
|
-
justifyContent:
|
|
166
|
-
alignItems:
|
|
231
|
+
display: "flex",
|
|
232
|
+
justifyContent: "end",
|
|
233
|
+
alignItems: "center",
|
|
167
234
|
};
|
|
168
235
|
exports.flexCenter = {
|
|
169
|
-
display:
|
|
170
|
-
justifyContent:
|
|
171
|
-
alignItems:
|
|
236
|
+
display: "flex",
|
|
237
|
+
justifyContent: "center",
|
|
238
|
+
alignItems: "center",
|
|
172
239
|
};
|
|
173
240
|
var isEmpty = function (data) {
|
|
174
241
|
return Object.keys(data).length === 0;
|
|
@@ -187,7 +254,7 @@ var formatFrenchVehiclePlate = function (input) {
|
|
|
187
254
|
plateFormat = Enums_1.VehiclePlateFormat.FRENCH_OLD;
|
|
188
255
|
}
|
|
189
256
|
// Supprimer tous les caractères non alphanumériques
|
|
190
|
-
var cleanedInput = input.replace(/[^A-Z0-9]/gi,
|
|
257
|
+
var cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
|
|
191
258
|
switch (plateFormat) {
|
|
192
259
|
case Enums_1.VehiclePlateFormat.FRENCH_NEW: {
|
|
193
260
|
// Ajouter des tirets aux positions appropriées
|
|
@@ -214,18 +281,21 @@ var formatVehicleTire = function (vehicleTire) {
|
|
|
214
281
|
var concatened = "".concat(vehicleTire.width).concat(vehicleTire.height).concat(vehicleTire.diameter).concat(vehicleTire.speedIndex);
|
|
215
282
|
return (0, exports.formatVehicleTireStr)(concatened);
|
|
216
283
|
}
|
|
217
|
-
return
|
|
284
|
+
return "";
|
|
218
285
|
};
|
|
219
286
|
exports.formatVehicleTire = formatVehicleTire;
|
|
220
287
|
var formatVehicleTireStr = function (input) {
|
|
221
|
-
var formatted = input
|
|
288
|
+
var formatted = input
|
|
289
|
+
.toUpperCase()
|
|
290
|
+
.replace(/[^0-9A-QS-Za-qs-z]/g, "")
|
|
291
|
+
.slice(0, 7);
|
|
222
292
|
if (formatted.length > 3) {
|
|
223
293
|
formatted = "".concat(formatted.substring(0, 3), " / ").concat(formatted.substring(3));
|
|
224
294
|
}
|
|
225
295
|
var indexOfRraw = input.indexOf("R");
|
|
226
|
-
var toAdd = indexOfRraw !== -1 ? input.substring(indexOfRraw + 3) :
|
|
296
|
+
var toAdd = indexOfRraw !== -1 ? input.substring(indexOfRraw + 3) : "";
|
|
227
297
|
if (toAdd.length > 0) {
|
|
228
|
-
toAdd =
|
|
298
|
+
toAdd = " " + toAdd;
|
|
229
299
|
}
|
|
230
300
|
if (formatted.length > 8) {
|
|
231
301
|
formatted = "".concat(formatted.substring(0, 8), " R").concat(formatted.substring(8)).concat(toAdd);
|
|
@@ -246,10 +316,10 @@ var validateField = function (field, validator, errorMsg) {
|
|
|
246
316
|
return { value: field.value, error: errorMsg, isValid: false };
|
|
247
317
|
}
|
|
248
318
|
else if (field) {
|
|
249
|
-
return { value: field.value, error:
|
|
319
|
+
return { value: field.value, error: "", isValid: true };
|
|
250
320
|
}
|
|
251
321
|
else {
|
|
252
|
-
return { value:
|
|
322
|
+
return { value: "", error: "", isValid: true };
|
|
253
323
|
}
|
|
254
324
|
};
|
|
255
325
|
exports.validateField = validateField;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateEmail = exports.validateText = exports.validatePhoneNumber = void 0;
|
|
4
|
+
var Tools_1 = require("./Tools");
|
|
4
5
|
/**
|
|
5
6
|
* Un email valide
|
|
6
7
|
*/
|
|
@@ -31,10 +32,10 @@ var userNameRegex = /^[a-z0-9_-]{3,20}$/;
|
|
|
31
32
|
*/
|
|
32
33
|
var textRegex = /^[a-zA-Z0-9\s.,!?'"()+=-_-éèçà]+$/;
|
|
33
34
|
function validatePhoneNumber(phoneNumber) {
|
|
34
|
-
if (phoneNumber === null || phoneNumber === undefined || phoneNumber ===
|
|
35
|
+
if (phoneNumber === null || phoneNumber === undefined || phoneNumber === "") {
|
|
35
36
|
return false;
|
|
36
37
|
}
|
|
37
|
-
return
|
|
38
|
+
return !(0, Tools_1.isInvalidMobileNumber)(phoneNumber);
|
|
38
39
|
}
|
|
39
40
|
exports.validatePhoneNumber = validatePhoneNumber;
|
|
40
41
|
function validateText(text) {
|
package/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ export { default as ActivateAccount } from './src/components/singup/ActivateAcco
|
|
|
31
31
|
export { QrCodePLVContainer } from './src/components/QrCodePLVContainer/QrCodePLVContainer';
|
|
32
32
|
export { PLVComponent, PrintSize } from './src/components/QrCodePLVContainer/PLVComponent';
|
|
33
33
|
export {LinkedDocumentDialog} from './src/components/LinkedDocumentDialog';
|
|
34
|
-
export { default as MovaTable } from './src/components/MovaTable/MovaTable'
|
|
34
|
+
export { default as MovaTable } from './src/components/MovaTable/MovaTable';
|
|
35
35
|
|
|
36
36
|
// Export des classes
|
|
37
37
|
export { default as Subscription } from './src/models/Subscription';
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@movalib/movalib-commons",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.60.1",
|
|
4
4
|
"description": "Bibliothèque d'objets communs à l'ensemble des projets React de Movalib",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"private": false,
|
|
8
8
|
"scripts": {
|
|
9
|
-
"start": "webpack-dev-server --entry ./devIndex.tsx --open
|
|
9
|
+
"start": "webpack-dev-server --entry ./devIndex.tsx --open",
|
|
10
10
|
"build": "rm -rf dist && tsc && npm run copy-assets",
|
|
11
11
|
"copy-assets": "cp -r src/assets/ dist/src/assets/ && cp -r src/style/. dist/src/style/",
|
|
12
12
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -50,12 +50,16 @@
|
|
|
50
50
|
"react-app"
|
|
51
51
|
]
|
|
52
52
|
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"libphonenumber-js": "1.9.52"
|
|
55
|
+
},
|
|
53
56
|
"devDependencies": {
|
|
54
57
|
"@types/js-cookie": "^3.0.4",
|
|
55
58
|
"@types/lodash": "^4.17.17",
|
|
56
59
|
"@types/pdfjs-dist": "^2.10.377",
|
|
57
60
|
"@types/react-input-mask": "^3.0.5",
|
|
58
61
|
"html-webpack-plugin": "^5.5.3",
|
|
62
|
+
"libphonenumber-js": "1.9.52",
|
|
59
63
|
"ts-loader": "^9.4.4",
|
|
60
64
|
"webpack-cli": "^5.1.4"
|
|
61
65
|
}
|
|
@@ -49,7 +49,11 @@ const DialogForgotPassword: React.FC<{
|
|
|
49
49
|
onChange={e => handleInputChange(e)}
|
|
50
50
|
value={movaAppType === MovaAppType.GARAGE ? form.email.value : form.phoneNumberEmail.value}
|
|
51
51
|
error={movaAppType === MovaAppType.GARAGE ? !form.email.isValid : !form.phoneNumberEmail.isValid}
|
|
52
|
-
helperText={
|
|
52
|
+
helperText={
|
|
53
|
+
movaAppType === MovaAppType.GARAGE
|
|
54
|
+
? form.email.error
|
|
55
|
+
: form.phoneNumberEmail.error || "Saisir l’indicatif pour un numéro étranger (ex : +32 …)"
|
|
56
|
+
}
|
|
53
57
|
/>
|
|
54
58
|
</DialogContent>
|
|
55
59
|
<DialogActions>
|
package/src/MovaLogin.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import InputAdornment from '@mui/material/InputAdornment';
|
|
|
19
19
|
import Visibility from '@mui/icons-material/Visibility';
|
|
20
20
|
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
|
21
21
|
import DialogForgotPassword from "./DialogForgotPassword";
|
|
22
|
+
import { parsePhoneNumberFromString, isValidPhoneNumber } from 'libphonenumber-js';
|
|
22
23
|
|
|
23
24
|
// Permet de centrer le contenu de l'application
|
|
24
25
|
const styles: CSSProperties = {
|
|
@@ -100,9 +101,30 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
|
|
|
100
101
|
newForm.email = validateField(form.email, validateEmail, 'Adresse email invalide');
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
/* if(movaAppType === MovaAppType.INDIVIDUAL){
|
|
104
105
|
newForm.phoneNumberEmail = validateField(form.phoneNumberEmail, value => !!value, 'Champ obligatoire');
|
|
105
|
-
}
|
|
106
|
+
} */
|
|
107
|
+
|
|
108
|
+
if (movaAppType === MovaAppType.INDIVIDUAL) {
|
|
109
|
+
newForm.phoneNumberEmail = validateField(
|
|
110
|
+
form.phoneNumberEmail,
|
|
111
|
+
(value) => {
|
|
112
|
+
if (!value) return false;
|
|
113
|
+
|
|
114
|
+
// Si c’est un email valide => OK
|
|
115
|
+
if (validateEmail(value)) return true;
|
|
116
|
+
|
|
117
|
+
// Remplace 00 par + si le numéro commence par 00 (pour compatibilité avec libphonenumber-js)
|
|
118
|
+
const normalizedValue = value.startsWith('00') ? value.replace(/^00/, '+') : value;
|
|
119
|
+
|
|
120
|
+
// Si le numéro commence par + ou 00, tentative de parsing direct. Format local, Pays par défaut : FR
|
|
121
|
+
const phoneNumber = parsePhoneNumberFromString(normalizedValue, normalizedValue.startsWith('+') || normalizedValue.startsWith('00') ? undefined : 'FR');
|
|
122
|
+
|
|
123
|
+
return phoneNumber?.isValid() ?? false;
|
|
124
|
+
},
|
|
125
|
+
'Email ou numéro de téléphone invalide'
|
|
126
|
+
);
|
|
127
|
+
}
|
|
106
128
|
|
|
107
129
|
newForm.password = validateField(form.password, value => !!value, 'Champ obligatoire');
|
|
108
130
|
|
|
@@ -245,7 +267,10 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
|
|
|
245
267
|
onChange={e => handleInputChange(e)}
|
|
246
268
|
value={form.phoneNumberEmail.value}
|
|
247
269
|
error={!form.phoneNumberEmail.isValid}
|
|
248
|
-
helperText={
|
|
270
|
+
helperText={
|
|
271
|
+
form.phoneNumberEmail.error ||
|
|
272
|
+
"Saisir l’indicatif pour un numéro étranger (ex : +32 …)"
|
|
273
|
+
}
|
|
249
274
|
sx={{
|
|
250
275
|
'& .MuiOutlinedInput-notchedOutline': {
|
|
251
276
|
borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
|
package/src/MovaSignUp.tsx
CHANGED
|
@@ -24,6 +24,7 @@ import isValid from 'date-fns/isValid';
|
|
|
24
24
|
import Logger from "./helpers/Logger";
|
|
25
25
|
import User from "./models/User";
|
|
26
26
|
import UserService from "./services/UserService";
|
|
27
|
+
import { parsePhoneNumberFromString } from 'libphonenumber-js';
|
|
27
28
|
|
|
28
29
|
// ATTENTION : s'assurer de la présence des documents suivants à la racine du composant porteur (dossier 'public')
|
|
29
30
|
const CGUPath:string = "https://s3.eu-west-3.amazonaws.com/legal.movalib.com/Movalib_CGU.pdf";
|
|
@@ -105,18 +106,29 @@ const MovaSignUp: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType,
|
|
|
105
106
|
|
|
106
107
|
// On autorise uniquement les chiffre pour le n° de téléphone
|
|
107
108
|
if (fieldName == "phoneNumber"){
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
// Nettoyage : on autorise chiffres + éventuellement un "+" en début
|
|
110
|
+
let cleaned = fieldValue.trim().replace(/[^\d+]/g, '');
|
|
111
|
+
|
|
112
|
+
// Normalisation : 0033... → +33...
|
|
113
|
+
if (cleaned.startsWith('00')) {
|
|
114
|
+
cleaned = cleaned.replace(/^00/, '+');
|
|
112
115
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
|
|
117
|
+
// Parsing avec FR par défaut si local
|
|
118
|
+
const parsed = parsePhoneNumberFromString(cleaned, cleaned.startsWith('+') ? undefined : 'FR');
|
|
119
|
+
|
|
120
|
+
// Mise à jour du champ
|
|
121
|
+
if (parsed?.isValid()) {
|
|
122
|
+
const e164 = parsed.number; // format +33...
|
|
123
|
+
//fieldValue = e164;
|
|
124
|
+
|
|
125
|
+
// Vérification de l'existence du compte
|
|
126
|
+
UserService.existsByPhoneNumber(e164).then((response) => {
|
|
127
|
+
if (response && response.data) {
|
|
128
|
+
if (response.data.isActive === false) {
|
|
129
|
+
setUserExist(true);
|
|
130
|
+
setUserIsAlreadyActive(false);
|
|
131
|
+
} else if (response.data.isActive === true) {
|
|
120
132
|
setUserIsAlreadyActive(true);
|
|
121
133
|
setUserExist(false);
|
|
122
134
|
} else {
|
|
@@ -124,8 +136,9 @@ const MovaSignUp: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType,
|
|
|
124
136
|
setUserIsAlreadyActive(false);
|
|
125
137
|
}
|
|
126
138
|
}
|
|
127
|
-
})
|
|
139
|
+
});
|
|
128
140
|
} else {
|
|
141
|
+
// Si numéro invalide ou incomplet, on réinitialise les flags
|
|
129
142
|
setUserExist(false);
|
|
130
143
|
setUserIsAlreadyActive(false);
|
|
131
144
|
}
|
|
@@ -313,7 +326,10 @@ const MovaSignUp: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType,
|
|
|
313
326
|
onChange={e => handleInputChange(e)}
|
|
314
327
|
value={userForm.phoneNumber.value}
|
|
315
328
|
error={Boolean(userForm.phoneNumber.error)}
|
|
316
|
-
helperText={
|
|
329
|
+
helperText={
|
|
330
|
+
userForm.phoneNumber.error ||
|
|
331
|
+
"Saisir l’indicatif pour un numéro étranger (ex : +32 …)"
|
|
332
|
+
}
|
|
317
333
|
InputProps={{
|
|
318
334
|
endAdornment: (
|
|
319
335
|
<InputAdornment position="end">
|
|
@@ -109,7 +109,7 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
|
|
|
109
109
|
const qrCodeBlob = await qrCode.getRawData("png");
|
|
110
110
|
|
|
111
111
|
// Convertir l'image QR code en un tableau de bytes
|
|
112
|
-
const qrImageBytes = await qrCodeBlob?.arrayBuffer();
|
|
112
|
+
const qrImageBytes = await (qrCodeBlob as Blob)?.arrayBuffer();
|
|
113
113
|
// Intégrer l'image du QR code dans le PDF
|
|
114
114
|
const qrImage = await pdfDoc.embedPng(qrImageBytes!);
|
|
115
115
|
|
package/src/helpers/Tools.ts
CHANGED
|
@@ -1,56 +1,92 @@
|
|
|
1
|
-
import
|
|
2
|
-
import VehicleTire from "../models/VehicleTire";
|
|
3
|
-
import { MovaFormField, MovaInterval } from "./Types";
|
|
1
|
+
import parsePhoneNumberFromString from "libphonenumber-js/max";
|
|
4
2
|
import { CSSProperties } from "react";
|
|
5
|
-
import { DayOfWeek, PartsApplicationType, VehiclePlateFormat } from "./Enums";
|
|
6
3
|
import Schedule from "../models/Schedule";
|
|
4
|
+
import VehicleTire from "../models/VehicleTire";
|
|
5
|
+
import { DayOfWeek, PartsApplicationType, VehiclePlateFormat } from "./Enums";
|
|
6
|
+
import { MovaFormField, MovaInterval } from "./Types";
|
|
7
7
|
|
|
8
|
-
export const getApplicationsShortLabels = (
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export const getApplicationsShortLabels = (
|
|
9
|
+
applications: PartsApplicationType[] | undefined
|
|
10
|
+
): string => {
|
|
11
|
+
if (!applications) {
|
|
12
|
+
return "";
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
return applications.map(getApplicationShortLabel).join(
|
|
14
|
+
|
|
15
|
+
return applications.map(getApplicationShortLabel).join(" + ");
|
|
14
16
|
};
|
|
15
17
|
|
|
16
|
-
export const flexStart:CSSProperties = {
|
|
17
|
-
display:
|
|
18
|
-
justifyContent:
|
|
19
|
-
alignItems:
|
|
20
|
-
}
|
|
18
|
+
export const flexStart: CSSProperties = {
|
|
19
|
+
display: "flex",
|
|
20
|
+
justifyContent: "start",
|
|
21
|
+
alignItems: "center",
|
|
22
|
+
};
|
|
21
23
|
|
|
22
|
-
export const isSafariOniOS = ():boolean => {
|
|
24
|
+
export const isSafariOniOS = (): boolean => {
|
|
23
25
|
const userAgent = window.navigator.userAgent;
|
|
24
|
-
const iOS =
|
|
26
|
+
const iOS =
|
|
27
|
+
!!userAgent.match(/iPad/i) ||
|
|
28
|
+
!!userAgent.match(/iPhone/i) ||
|
|
29
|
+
!!userAgent.match(/iPod/i);
|
|
25
30
|
const webkit = !!userAgent.match(/WebKit/i);
|
|
26
31
|
const criOS = !!userAgent.match(/CriOS/i);
|
|
27
|
-
|
|
32
|
+
|
|
28
33
|
return iOS && webkit && !criOS;
|
|
29
|
-
}
|
|
34
|
+
};
|
|
30
35
|
|
|
36
|
+
export const isInvalidMobileNumber = (phoneNumber = "") => {
|
|
37
|
+
if (!phoneNumber || typeof phoneNumber !== "string") return true;
|
|
38
|
+
|
|
39
|
+
// Nettoyage : supprime les espaces et convertit "00..." en "+..."
|
|
40
|
+
const cleaned = phoneNumber.replace(/\s+/g, "").replace(/^00/, "+");
|
|
41
|
+
// Si le numéro ne commence pas par +, on assume que c'est un numéro local français
|
|
42
|
+
const cleanedPhoneNumber = cleaned.startsWith("+")
|
|
43
|
+
? cleaned
|
|
44
|
+
: `+33${cleaned.replace(/^0/, "")}`;
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const parsed = parsePhoneNumberFromString(cleanedPhoneNumber);
|
|
48
|
+
const type = parsed?.getType?.();
|
|
49
|
+
console.log(type);
|
|
50
|
+
console.log(parsed?.isValid());
|
|
51
|
+
console.log(["MOBILE", "MOBILE_OR_FIXED_LINE"].includes(type || ""));
|
|
52
|
+
return !(
|
|
53
|
+
parsed?.isValid() &&
|
|
54
|
+
["MOBILE", "MOBILE_OR_FIXED_LINE"].includes(type || "")
|
|
55
|
+
);
|
|
56
|
+
} catch {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
31
60
|
|
|
32
|
-
export const FR_WEEK_DAYS: string[] = [
|
|
61
|
+
export const FR_WEEK_DAYS: string[] = [
|
|
62
|
+
"Lundi",
|
|
63
|
+
"Mardi",
|
|
64
|
+
"Mercredi",
|
|
65
|
+
"Jeudi",
|
|
66
|
+
"Vendredi",
|
|
67
|
+
"Samedi",
|
|
68
|
+
"Dimanche",
|
|
69
|
+
];
|
|
33
70
|
|
|
34
71
|
export const getDayOfWeekLabel = (day: DayOfWeek) => {
|
|
35
|
-
if(day){
|
|
36
|
-
return FR_WEEK_DAYS[getDayOfWeekIndex(day)]
|
|
72
|
+
if (day) {
|
|
73
|
+
return FR_WEEK_DAYS[getDayOfWeekIndex(day)];
|
|
37
74
|
}
|
|
38
|
-
}
|
|
75
|
+
};
|
|
39
76
|
|
|
40
77
|
export const getDayOfWeekIndex = (day: DayOfWeek) => {
|
|
41
|
-
if(day){
|
|
78
|
+
if (day) {
|
|
42
79
|
// Convertir les valeurs de l'énumération en un tableau
|
|
43
80
|
const daysArray = Object.values(DayOfWeek);
|
|
44
81
|
return daysArray.indexOf(day);
|
|
45
82
|
}
|
|
46
83
|
return -1;
|
|
47
|
-
}
|
|
48
|
-
|
|
84
|
+
};
|
|
49
85
|
|
|
50
86
|
export const formatPhoneNumber = (phoneNumber: string): string => {
|
|
51
87
|
let formattedNumber = "";
|
|
52
88
|
|
|
53
|
-
if(phoneNumber){
|
|
89
|
+
if (phoneNumber) {
|
|
54
90
|
for (let i = 0; i < phoneNumber.length; i++) {
|
|
55
91
|
if (i > 0 && i % 2 === 0) {
|
|
56
92
|
formattedNumber += ".";
|
|
@@ -62,87 +98,119 @@ export const formatPhoneNumber = (phoneNumber: string): string => {
|
|
|
62
98
|
return formattedNumber;
|
|
63
99
|
};
|
|
64
100
|
|
|
65
|
-
export const getFormattedSchedule = (
|
|
66
|
-
|
|
67
|
-
|
|
101
|
+
export const getFormattedSchedule = (
|
|
102
|
+
schedule: Schedule | null,
|
|
103
|
+
dayIndex: number
|
|
104
|
+
) => {
|
|
105
|
+
if (schedule) {
|
|
106
|
+
return `${getFrenchDayLabel(
|
|
107
|
+
schedule.dayOfWeek
|
|
108
|
+
)} : ${getFormattedIntervals(schedule.intervals)}`;
|
|
68
109
|
} else {
|
|
69
110
|
return `${getFrenchDayLabel(getDayOfWeek(dayIndex))} : fermé`;
|
|
70
111
|
}
|
|
71
|
-
}
|
|
112
|
+
};
|
|
72
113
|
|
|
73
114
|
export const getFormattedIntervals = (intervals: MovaInterval[]) => {
|
|
74
|
-
if(intervals){
|
|
75
|
-
let times:string = "";
|
|
76
|
-
sortMovaIntervals(intervals).map((interval:MovaInterval, index) => {
|
|
77
|
-
if(index > 0){
|
|
78
|
-
times = `${times} | `;
|
|
115
|
+
if (intervals) {
|
|
116
|
+
let times: string = "";
|
|
117
|
+
sortMovaIntervals(intervals).map((interval: MovaInterval, index) => {
|
|
118
|
+
if (index > 0) {
|
|
119
|
+
times = `${times} | `;
|
|
79
120
|
}
|
|
80
|
-
times = `${times} ${formatTime(interval.startTime)} - ${formatTime(
|
|
81
|
-
|
|
121
|
+
times = `${times} ${formatTime(interval.startTime)} - ${formatTime(
|
|
122
|
+
interval.endTime
|
|
123
|
+
)}`;
|
|
124
|
+
});
|
|
82
125
|
return times;
|
|
83
126
|
}
|
|
84
|
-
}
|
|
127
|
+
};
|
|
85
128
|
|
|
86
129
|
export const formatTime = (date: string | Date | null) => {
|
|
87
|
-
if(date){
|
|
88
|
-
let strDate:string = date.toString();
|
|
130
|
+
if (date) {
|
|
131
|
+
let strDate: string = date.toString();
|
|
89
132
|
return strDate.substring(0, 5);
|
|
90
133
|
}
|
|
91
134
|
};
|
|
92
135
|
|
|
93
136
|
const sortMovaIntervals = (intervals: MovaInterval[]): MovaInterval[] => {
|
|
94
|
-
if(intervals){
|
|
137
|
+
if (intervals) {
|
|
95
138
|
return intervals.sort((a, b) => {
|
|
96
139
|
// Convertir en Date si nécessaire
|
|
97
|
-
const startTimeA =
|
|
98
|
-
|
|
99
|
-
|
|
140
|
+
const startTimeA =
|
|
141
|
+
a.startTime instanceof Date
|
|
142
|
+
? a.startTime
|
|
143
|
+
: new Date(a.startTime as string);
|
|
144
|
+
const startTimeB =
|
|
145
|
+
b.startTime instanceof Date
|
|
146
|
+
? b.startTime
|
|
147
|
+
: new Date(b.startTime as string);
|
|
148
|
+
|
|
100
149
|
// Gérer les valeurs nulles
|
|
101
150
|
if (startTimeA === null && startTimeB === null) return 0;
|
|
102
151
|
if (startTimeA === null) return 1;
|
|
103
152
|
if (startTimeB === null) return -1;
|
|
104
|
-
|
|
153
|
+
|
|
105
154
|
// Comparer les dates
|
|
106
155
|
return startTimeA.getTime() - startTimeB.getTime();
|
|
107
156
|
});
|
|
108
157
|
}
|
|
109
158
|
return [];
|
|
110
|
-
}
|
|
159
|
+
};
|
|
111
160
|
|
|
112
|
-
export const findScheduleByDayOfWeek = (
|
|
113
|
-
|
|
161
|
+
export const findScheduleByDayOfWeek = (
|
|
162
|
+
schedules: Schedule[],
|
|
163
|
+
dayIndex: number
|
|
164
|
+
): Schedule | null => {
|
|
165
|
+
const foundSchedule = schedules.find(
|
|
166
|
+
(schedule) => schedule.dayOfWeek === getDayOfWeek(dayIndex)
|
|
167
|
+
);
|
|
114
168
|
return foundSchedule ? foundSchedule : null;
|
|
115
169
|
};
|
|
116
170
|
|
|
117
|
-
export const getDayOfWeek = (index:number) => {
|
|
171
|
+
export const getDayOfWeek = (index: number) => {
|
|
118
172
|
switch (index) {
|
|
119
|
-
case 0
|
|
120
|
-
|
|
121
|
-
case
|
|
122
|
-
|
|
123
|
-
case
|
|
124
|
-
|
|
125
|
-
case
|
|
173
|
+
case 0:
|
|
174
|
+
return DayOfWeek.MONDAY;
|
|
175
|
+
case 1:
|
|
176
|
+
return DayOfWeek.TUESDAY;
|
|
177
|
+
case 2:
|
|
178
|
+
return DayOfWeek.WEDNESDAY;
|
|
179
|
+
case 3:
|
|
180
|
+
return DayOfWeek.THURSDAY;
|
|
181
|
+
case 4:
|
|
182
|
+
return DayOfWeek.FRIDAY;
|
|
183
|
+
case 5:
|
|
184
|
+
return DayOfWeek.SATURDAY;
|
|
185
|
+
case 6:
|
|
186
|
+
return DayOfWeek.SUNDAY;
|
|
126
187
|
}
|
|
127
|
-
}
|
|
188
|
+
};
|
|
128
189
|
|
|
129
|
-
export const getFrenchDayLabel = (day:DayOfWeek | undefined) => {
|
|
190
|
+
export const getFrenchDayLabel = (day: DayOfWeek | undefined) => {
|
|
130
191
|
switch (day) {
|
|
131
|
-
case DayOfWeek.MONDAY:
|
|
132
|
-
|
|
133
|
-
case DayOfWeek.
|
|
134
|
-
|
|
135
|
-
case DayOfWeek.
|
|
136
|
-
|
|
137
|
-
case DayOfWeek.
|
|
192
|
+
case DayOfWeek.MONDAY:
|
|
193
|
+
return "Lundi";
|
|
194
|
+
case DayOfWeek.TUESDAY:
|
|
195
|
+
return "Mardi";
|
|
196
|
+
case DayOfWeek.WEDNESDAY:
|
|
197
|
+
return "Mercredi";
|
|
198
|
+
case DayOfWeek.THURSDAY:
|
|
199
|
+
return "Jeudi";
|
|
200
|
+
case DayOfWeek.FRIDAY:
|
|
201
|
+
return "Vendredi";
|
|
202
|
+
case DayOfWeek.SATURDAY:
|
|
203
|
+
return "Samedi";
|
|
204
|
+
case DayOfWeek.SUNDAY:
|
|
205
|
+
return "Dimanche";
|
|
138
206
|
}
|
|
139
|
-
}
|
|
207
|
+
};
|
|
140
208
|
|
|
141
|
-
export const flexLeftRow:CSSProperties = {
|
|
142
|
-
display:
|
|
143
|
-
justifyContent:
|
|
144
|
-
alignItems:
|
|
145
|
-
}
|
|
209
|
+
export const flexLeftRow: CSSProperties = {
|
|
210
|
+
display: "flex",
|
|
211
|
+
justifyContent: "start",
|
|
212
|
+
alignItems: "center",
|
|
213
|
+
};
|
|
146
214
|
|
|
147
215
|
export const capitalizeFirstLetter = (str: string): string => {
|
|
148
216
|
if (str.length === 0) {
|
|
@@ -153,45 +221,56 @@ export const capitalizeFirstLetter = (str: string): string => {
|
|
|
153
221
|
const restOfString = str.slice(1);
|
|
154
222
|
|
|
155
223
|
return firstChar + restOfString;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export const getApplicationShortLabel = (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
case PartsApplicationType.
|
|
164
|
-
|
|
165
|
-
case PartsApplicationType.
|
|
166
|
-
|
|
167
|
-
case PartsApplicationType.
|
|
168
|
-
|
|
169
|
-
case PartsApplicationType.
|
|
170
|
-
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
export const getApplicationShortLabel = (
|
|
227
|
+
application: PartsApplicationType | undefined
|
|
228
|
+
) => {
|
|
229
|
+
if (application) {
|
|
230
|
+
switch (application) {
|
|
231
|
+
case PartsApplicationType.FRONT:
|
|
232
|
+
return "AV";
|
|
233
|
+
case PartsApplicationType.REAR:
|
|
234
|
+
return "AR";
|
|
235
|
+
case PartsApplicationType.FRONT_REAR:
|
|
236
|
+
return "AV + AR";
|
|
237
|
+
case PartsApplicationType.LEFT:
|
|
238
|
+
return "G";
|
|
239
|
+
case PartsApplicationType.RIGHT:
|
|
240
|
+
return "D";
|
|
241
|
+
case PartsApplicationType.LEFT_RIGHT:
|
|
242
|
+
return "G + D";
|
|
243
|
+
case PartsApplicationType.FRONT_LEFT:
|
|
244
|
+
return "AVG";
|
|
245
|
+
case PartsApplicationType.FRONT_RIGHT:
|
|
246
|
+
return "AVD";
|
|
247
|
+
case PartsApplicationType.REAR_LEFT:
|
|
248
|
+
return "ARG";
|
|
249
|
+
case PartsApplicationType.REAR_RIGHT:
|
|
250
|
+
return "ARD";
|
|
171
251
|
}
|
|
172
252
|
}
|
|
173
253
|
return "";
|
|
174
|
-
}
|
|
254
|
+
};
|
|
175
255
|
|
|
176
|
-
export const flexEnd:CSSProperties = {
|
|
177
|
-
display:
|
|
178
|
-
justifyContent:
|
|
179
|
-
alignItems:
|
|
180
|
-
}
|
|
256
|
+
export const flexEnd: CSSProperties = {
|
|
257
|
+
display: "flex",
|
|
258
|
+
justifyContent: "end",
|
|
259
|
+
alignItems: "center",
|
|
260
|
+
};
|
|
181
261
|
|
|
182
|
-
export const flexCenter:CSSProperties = {
|
|
183
|
-
display:
|
|
184
|
-
justifyContent:
|
|
185
|
-
alignItems:
|
|
186
|
-
}
|
|
262
|
+
export const flexCenter: CSSProperties = {
|
|
263
|
+
display: "flex",
|
|
264
|
+
justifyContent: "center",
|
|
265
|
+
alignItems: "center",
|
|
266
|
+
};
|
|
187
267
|
|
|
188
268
|
export const isEmpty = (data: Object): boolean => {
|
|
189
269
|
return Object.keys(data).length === 0;
|
|
190
|
-
}
|
|
270
|
+
};
|
|
191
271
|
|
|
192
272
|
export const formatFrenchVehiclePlate = (input: string | undefined): string => {
|
|
193
|
-
if(input){
|
|
194
|
-
|
|
273
|
+
if (input) {
|
|
195
274
|
// On commence par détecter s'il s'agit d'un ancien ou nouveau format
|
|
196
275
|
let plateFormat: VehiclePlateFormat | null = null;
|
|
197
276
|
|
|
@@ -204,21 +283,24 @@ export const formatFrenchVehiclePlate = (input: string | undefined): string => {
|
|
|
204
283
|
}
|
|
205
284
|
|
|
206
285
|
// Supprimer tous les caractères non alphanumériques
|
|
207
|
-
let cleanedInput = input.replace(/[^A-Z0-9]/gi,
|
|
286
|
+
let cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
|
|
208
287
|
|
|
209
|
-
switch(plateFormat){
|
|
210
|
-
case VehiclePlateFormat.FRENCH_NEW
|
|
288
|
+
switch (plateFormat) {
|
|
289
|
+
case VehiclePlateFormat.FRENCH_NEW: {
|
|
211
290
|
// Ajouter des tirets aux positions appropriées
|
|
212
291
|
if (cleanedInput.length >= 2) {
|
|
213
292
|
cleanedInput = `${cleanedInput.slice(0, 2)}-${cleanedInput.slice(2)}`;
|
|
214
293
|
}
|
|
215
294
|
if (cleanedInput.length >= 6) {
|
|
216
|
-
cleanedInput = `${cleanedInput.slice(0, 6)}-${cleanedInput.slice(
|
|
295
|
+
cleanedInput = `${cleanedInput.slice(0, 6)}-${cleanedInput.slice(
|
|
296
|
+
6,
|
|
297
|
+
8
|
|
298
|
+
)}`;
|
|
217
299
|
}
|
|
218
300
|
break;
|
|
219
301
|
}
|
|
220
302
|
|
|
221
|
-
case VehiclePlateFormat.FRENCH_OLD
|
|
303
|
+
case VehiclePlateFormat.FRENCH_OLD: {
|
|
222
304
|
// Rien de particulier, pas de tiret sur les anciennes plaques
|
|
223
305
|
break;
|
|
224
306
|
}
|
|
@@ -231,25 +313,30 @@ export const formatFrenchVehiclePlate = (input: string | undefined): string => {
|
|
|
231
313
|
};
|
|
232
314
|
|
|
233
315
|
export const formatVehicleTire = (vehicleTire: VehicleTire) => {
|
|
234
|
-
if(vehicleTire){
|
|
316
|
+
if (vehicleTire) {
|
|
235
317
|
let concatened = `${vehicleTire.width}${vehicleTire.height}${vehicleTire.diameter}${vehicleTire.speedIndex}`;
|
|
236
318
|
return formatVehicleTireStr(concatened);
|
|
237
319
|
}
|
|
238
|
-
return
|
|
239
|
-
}
|
|
320
|
+
return "";
|
|
321
|
+
};
|
|
240
322
|
|
|
241
323
|
export const formatVehicleTireStr = (input: string) => {
|
|
242
|
-
let formatted = input
|
|
324
|
+
let formatted = input
|
|
325
|
+
.toUpperCase()
|
|
326
|
+
.replace(/[^0-9A-QS-Za-qs-z]/g, "")
|
|
327
|
+
.slice(0, 7);
|
|
243
328
|
if (formatted.length > 3) {
|
|
244
329
|
formatted = `${formatted.substring(0, 3)} / ${formatted.substring(3)}`;
|
|
245
330
|
}
|
|
246
331
|
const indexOfRraw = input.indexOf("R");
|
|
247
|
-
let toAdd = indexOfRraw !== -1 ? input.substring(indexOfRraw + 3) :
|
|
248
|
-
if(toAdd.length > 0) {
|
|
249
|
-
toAdd =
|
|
332
|
+
let toAdd = indexOfRraw !== -1 ? input.substring(indexOfRraw + 3) : "";
|
|
333
|
+
if (toAdd.length > 0) {
|
|
334
|
+
toAdd = " " + toAdd;
|
|
250
335
|
}
|
|
251
|
-
if(formatted.length > 8) {
|
|
252
|
-
formatted = `${formatted.substring(0, 8)} R${formatted.substring(
|
|
336
|
+
if (formatted.length > 8) {
|
|
337
|
+
formatted = `${formatted.substring(0, 8)} R${formatted.substring(
|
|
338
|
+
8
|
|
339
|
+
)}${toAdd}`;
|
|
253
340
|
}
|
|
254
341
|
return formatted;
|
|
255
342
|
};
|
|
@@ -262,13 +349,16 @@ export const formatVehicleTireStr = (input: string) => {
|
|
|
262
349
|
* @param {string} errorMsg - Le message d'erreur à associer au champ si la validation échoue.
|
|
263
350
|
* @returns {MovaFormField} - Le champ de formulaire avec les propriétés `error` et `isValid` mises à jour.
|
|
264
351
|
*/
|
|
265
|
-
export const validateField = (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
352
|
+
export const validateField = (
|
|
353
|
+
field: MovaFormField | undefined,
|
|
354
|
+
validator: (value: string) => boolean,
|
|
355
|
+
errorMsg: string
|
|
356
|
+
): MovaFormField => {
|
|
357
|
+
if (field && !validator(field.value)) {
|
|
358
|
+
return { value: field.value, error: errorMsg, isValid: false };
|
|
359
|
+
} else if (field) {
|
|
360
|
+
return { value: field.value, error: "", isValid: true };
|
|
361
|
+
} else {
|
|
362
|
+
return { value: "", error: "", isValid: true };
|
|
363
|
+
}
|
|
364
|
+
};
|
package/src/helpers/Validator.ts
CHANGED
|
@@ -1,57 +1,59 @@
|
|
|
1
|
+
import { isInvalidMobileNumber } from "./Tools";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Un email valide
|
|
3
5
|
*/
|
|
4
|
-
const emailRegex:RegExp
|
|
6
|
+
const emailRegex: RegExp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
* Un mot de passe qui contient au moins une majuscule, une minuscule, un chiffre
|
|
9
|
+
* Un mot de passe qui contient au moins une majuscule, une minuscule, un chiffre
|
|
8
10
|
* et un caractère spécial. La longueur du mot de passe doit être d'au moins 8 caractères.
|
|
9
11
|
*/
|
|
10
|
-
const passwordRegex:RegExp
|
|
12
|
+
const passwordRegex: RegExp =
|
|
13
|
+
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
|
-
* Un numéro de téléphone (10 chiffres)
|
|
16
|
+
* Un numéro de téléphone (10 chiffres)
|
|
14
17
|
*/
|
|
15
|
-
const phoneNumberRegex:RegExp
|
|
18
|
+
const phoneNumberRegex: RegExp = /^\d{0,10}$/;
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Un code postal (5 chiffres)
|
|
19
22
|
*/
|
|
20
|
-
const postalCodeRegex:RegExp
|
|
23
|
+
const postalCodeRegex: RegExp = /^\d{5}$/;
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Une URL valide
|
|
24
27
|
*/
|
|
25
|
-
const urlRegex:RegExp
|
|
28
|
+
const urlRegex: RegExp = /^(ftp|http|https):\/\/[^ "]+$/;
|
|
26
29
|
|
|
27
30
|
/**
|
|
28
31
|
* Un nom pouvant contenir des lettres, chiffres d'une taille comprise entre 3 et 20 caractères
|
|
29
32
|
*/
|
|
30
|
-
const userNameRegex:RegExp = /^[a-z0-9_-]{3,20}$/;
|
|
33
|
+
const userNameRegex: RegExp = /^[a-z0-9_-]{3,20}$/;
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* Un texte pouvant contenir des lettres, chiffres et quelques caractères spéciaux
|
|
34
37
|
*/
|
|
35
|
-
const textRegex:RegExp = /^[a-zA-Z0-9\s.,!?'"()+=-_-éèçà]+$/;
|
|
36
|
-
|
|
38
|
+
const textRegex: RegExp = /^[a-zA-Z0-9\s.,!?'"()+=-_-éèçà]+$/;
|
|
37
39
|
|
|
38
|
-
export function validatePhoneNumber(phoneNumber: string)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
export function validatePhoneNumber(phoneNumber: string): boolean {
|
|
41
|
+
if (phoneNumber === null || phoneNumber === undefined || phoneNumber === "") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return !isInvalidMobileNumber(phoneNumber);
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
export function validateText(text: string)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
export function validateText(text: string): boolean {
|
|
48
|
+
if (text === null || text === undefined) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return textRegex.test(text);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
export function validateEmail(email: string)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
54
|
+
export function validateEmail(email: string): boolean {
|
|
55
|
+
if (email === null || email === undefined) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return emailRegex.test(email);
|
|
59
|
+
}
|