@movalib/movalib-commons 1.1.15 → 1.1.17

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 CHANGED
@@ -12,7 +12,7 @@ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
12
12
  import DatePicker from '@mui/lab/DatePicker';
13
13
  import frLocale from 'date-fns/locale/fr';
14
14
  import QRCode from './src/QRCode';
15
- import { Box, Button, Typography } from '@mui/material';
15
+ import { Box, Button, Container, Typography } from '@mui/material';
16
16
  import GarageService from './src/services/GarageService';
17
17
  import AuthenticationService from './src/services/AuthenticationService';
18
18
  import Logger from './src/helpers/Logger';
@@ -21,6 +21,7 @@ import ScheduleFields, { DaySchedule } from './src/ScheduleFields';
21
21
  import Schedule from './src/models/Schedule';
22
22
  import { flexCenter } from './src/helpers/Tools';
23
23
  import AccountValidation from './src/AccountValidation';
24
+ import VehiclePlateField from './src/VehiclePlateField';
24
25
 
25
26
  const App = () => {
26
27
 
@@ -106,15 +107,26 @@ const App = () => {
106
107
  <ThemeProvider theme={theme}>
107
108
  <Box sx={{ mb: 4}}>
108
109
 
109
- <MovaLogin movaAppType={MovaAppType.GARAGE}
110
- version="0.1.3"
111
- onSubmit={function (form: MovaLoginForm): void {
112
- alert('Form Submitted !');
113
- } } onSubmitForgotPassword={function (email: string): void {
114
- throw new Error('Function not implemented.');
115
- } } />
116
-
117
- <MovaSignUp movaAppType={MovaAppType.INDIVIDUAL} onSubmit={function (form: MovaLoginForm): void {
110
+ <Container style={flexCenter} sx={{ width: '400px', mt: 2}}>
111
+ <VehiclePlateField onValidVehiclePlate={function (vehiclePlate: string): void {
112
+ alert('plaque valide');
113
+ } } />
114
+ </Container>
115
+
116
+
117
+ <MovaLogin
118
+ darkMode={false}
119
+ movaAppType={MovaAppType.GARAGE}
120
+ version="0.1.3"
121
+ onSubmit={function (form: MovaLoginForm): void {
122
+ alert('Form Submitted !');
123
+ } } onSubmitForgotPassword={function (email: string): void {
124
+ throw new Error('Function not implemented.');
125
+ } } />
126
+
127
+ <MovaSignUp
128
+ darkMode={false}
129
+ movaAppType={MovaAppType.INDIVIDUAL} onSubmit={function (form: MovaLoginForm): void {
118
130
  alert('Form Submitted !');
119
131
  } } />
120
132
 
package/dist/devIndex.js CHANGED
@@ -58,6 +58,7 @@ var ScheduleFields_1 = __importDefault(require("./src/ScheduleFields"));
58
58
  var Schedule_1 = __importDefault(require("./src/models/Schedule"));
59
59
  var Tools_1 = require("./src/helpers/Tools");
60
60
  var AccountValidation_1 = __importDefault(require("./src/AccountValidation"));
61
+ var VehiclePlateField_1 = __importDefault(require("./src/VehiclePlateField"));
61
62
  var App = function () {
62
63
  Logger_1.default.enableLogging();
63
64
  // Chargement de données garage de test
@@ -118,11 +119,13 @@ var App = function () {
118
119
  }
119
120
  }
120
121
  };
121
- return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(LocalizationProvider_1.LocalizationProvider, __assign({ dateAdapter: AdapterDateFns_1.AdapterDateFns, adapterLocale: fr_1.default }, { children: (0, jsx_runtime_1.jsxs)(styles_1.ThemeProvider, __assign({ theme: theme_1.default }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: { mb: 4 } }, { children: [(0, jsx_runtime_1.jsx)(MovaLogin_1.default, { movaAppType: Enums_1.MovaAppType.GARAGE, version: "0.1.3", onSubmit: function (form) {
122
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(LocalizationProvider_1.LocalizationProvider, __assign({ dateAdapter: AdapterDateFns_1.AdapterDateFns, adapterLocale: fr_1.default }, { children: (0, jsx_runtime_1.jsxs)(styles_1.ThemeProvider, __assign({ theme: theme_1.default }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ sx: { mb: 4 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Container, __assign({ style: Tools_1.flexCenter, sx: { width: '400px', mt: 2 } }, { children: (0, jsx_runtime_1.jsx)(VehiclePlateField_1.default, { onValidVehiclePlate: function (vehiclePlate) {
123
+ alert('plaque valide');
124
+ } }) })), (0, jsx_runtime_1.jsx)(MovaLogin_1.default, { darkMode: false, movaAppType: Enums_1.MovaAppType.GARAGE, version: "0.1.3", onSubmit: function (form) {
122
125
  alert('Form Submitted !');
123
126
  }, onSubmitForgotPassword: function (email) {
124
127
  throw new Error('Function not implemented.');
125
- } }), (0, jsx_runtime_1.jsx)(MovaSignUp_1.default, { movaAppType: Enums_1.MovaAppType.INDIVIDUAL, onSubmit: function (form) {
128
+ } }), (0, jsx_runtime_1.jsx)(MovaSignUp_1.default, { darkMode: false, movaAppType: Enums_1.MovaAppType.INDIVIDUAL, onSubmit: function (form) {
126
129
  alert('Form Submitted !');
127
130
  } }), (0, jsx_runtime_1.jsx)(QRCode_1.default, { data: getQRCodeData(), showDownload: true }), (0, jsx_runtime_1.jsx)("div", { style: { marginTop: '40px' } }), (0, jsx_runtime_1.jsx)("div", __assign({ style: Tools_1.flexCenter }, { children: (0, jsx_runtime_1.jsx)(ScheduleFields_1.default, { schedules: garage === null || garage === void 0 ? void 0 : garage.schedules, size: "small", timePickerStep: 30, onChange: handleScheduleChange }) }))] })), (0, jsx_runtime_1.jsx)(material_1.Box, __assign({ style: Tools_1.flexCenter }, { children: (0, jsx_runtime_1.jsx)(material_1.Button, __assign({ onClick: function () { return setOpenAccountValidation(!openAccountValidation); } }, { children: "Validation de compte" })) })), openAccountValidation && (0, jsx_runtime_1.jsx)(AccountValidation_1.default, { movaAppType: Enums_1.MovaAppType.GARAGE, onSubmit: function (success, message) {
128
131
  throw new Error('Function not implemented.');
package/dist/index.d.ts CHANGED
@@ -40,4 +40,4 @@ export { readCookie, deleteCookie } from './src/helpers/CookieUtils';
40
40
  export { validateField, formatVehicleTire, formatFrenchVehiclePlate, isEmpty, getApplicationShortLabel } from './src/helpers/Tools';
41
41
  export { validatePhoneNumber, validateText, validateEmail } from './src/helpers/Validator';
42
42
  export { formatDateByCountryCode, getLongFormattedDateTime, capitalizeFirstLetter } from './src/helpers/DateUtils';
43
- export { RoleType, MovaAppType, DayOfWeek, EventState, EventType, DocumentType, DigitalPassportIndex, DocumentState, Gender, DateFormatTypes, PartsApplicationType, ProductType, OrderPreference, OrderState, SlotAlgorithm } from './src/helpers/Enums';
43
+ export { RoleType, MovaAppType, DayOfWeek, EventState, EventType, DocumentType, DigitalPassportIndex, DocumentState, Gender, DateFormatTypes, PartsApplicationType, ProductType, OrderPreference, OrderState, SlotAlgorithm, VehiclePlateFormat as VehiclePlateType } from './src/helpers/Enums';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.MovaAppType = exports.RoleType = exports.capitalizeFirstLetter = exports.getLongFormattedDateTime = exports.formatDateByCountryCode = exports.validateEmail = exports.validateText = exports.validatePhoneNumber = exports.getApplicationShortLabel = exports.isEmpty = exports.formatFrenchVehiclePlate = exports.formatVehicleTire = exports.validateField = exports.deleteCookie = exports.readCookie = exports.VehicleTire = exports.Event = exports.Schedule = exports.Garage = exports.Document = exports.Vehicle = exports.Address = exports.Role = exports.User = exports.Customer = exports.Logger = exports.Operation = exports.Prestation = exports.Product = exports.Supplier = exports.GenderSelector = exports.ConfirmationDialog = exports.MovaVehicleTireField = exports.MovaCopyright = exports.MovaSignUp = exports.MovaLogin = exports.MovaSnackbar = exports.TestButton = exports.VehiclePlateField = exports.QRCode = exports.MovaDialog = exports.Loader = exports.MovaDigitalPassport = exports.VehicleFullCard = exports.ScheduleFields = exports.AddressFields = exports.AccountValidation = exports.UserService = exports.GarageService = exports.AuthenticationService = void 0;
8
- exports.SlotAlgorithm = exports.OrderState = exports.OrderPreference = exports.ProductType = exports.PartsApplicationType = exports.DateFormatTypes = exports.Gender = exports.DocumentState = exports.DigitalPassportIndex = exports.DocumentType = exports.EventType = exports.EventState = exports.DayOfWeek = void 0;
8
+ exports.VehiclePlateType = exports.SlotAlgorithm = exports.OrderState = exports.OrderPreference = exports.ProductType = exports.PartsApplicationType = exports.DateFormatTypes = exports.Gender = exports.DocumentState = exports.DigitalPassportIndex = exports.DocumentType = exports.EventType = exports.EventState = exports.DayOfWeek = void 0;
9
9
  // Export des services
10
10
  var AuthenticationService_1 = require("./src/services/AuthenticationService");
11
11
  Object.defineProperty(exports, "AuthenticationService", { enumerable: true, get: function () { return __importDefault(AuthenticationService_1).default; } });
@@ -114,3 +114,4 @@ Object.defineProperty(exports, "ProductType", { enumerable: true, get: function
114
114
  Object.defineProperty(exports, "OrderPreference", { enumerable: true, get: function () { return Enums_1.OrderPreference; } });
115
115
  Object.defineProperty(exports, "OrderState", { enumerable: true, get: function () { return Enums_1.OrderState; } });
116
116
  Object.defineProperty(exports, "SlotAlgorithm", { enumerable: true, get: function () { return Enums_1.SlotAlgorithm; } });
117
+ Object.defineProperty(exports, "VehiclePlateType", { enumerable: true, get: function () { return Enums_1.VehiclePlateFormat; } });
@@ -14,6 +14,7 @@ interface MovaLoginProps {
14
14
  movaAppType: MovaAppType;
15
15
  onSubmit: (form: MovaLoginForm) => void;
16
16
  onSubmitForgotPassword: (email: string) => void;
17
+ darkMode: boolean;
17
18
  alertMessage?: string;
18
19
  alertSeverity?: AlertColor;
19
20
  loading?: boolean;
@@ -55,6 +55,8 @@ var react_1 = require("react");
55
55
  var lab_1 = require("@mui/lab");
56
56
  var logo_large_png_1 = __importDefault(require("./assets/images/logo/logo_large.png"));
57
57
  var logo_pro_large_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large.png"));
58
+ var logo_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_large_dm.png"));
59
+ var logo_pro_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large_dm.png"));
58
60
  var leaf_green_large_png_1 = __importDefault(require("./assets/images/leaf_green_large.png"));
59
61
  var leaf_pink_large_png_1 = __importDefault(require("./assets/images/leaf_pink_large.png"));
60
62
  var material_1 = require("@mui/material");
@@ -83,13 +85,13 @@ var initialFormState = {
83
85
  * ATTENTION : la page attendue pour le bouton "Créer mon compte" doit pointer vers "/signup"
84
86
  */
85
87
  var MovaLogin = function (_a) {
86
- var loading = _a.loading, movaAppType = _a.movaAppType, onSubmit = _a.onSubmit, onSubmitForgotPassword = _a.onSubmitForgotPassword, alertMessage = _a.alertMessage, alertSeverity = _a.alertSeverity, version = _a.version;
87
- var _b = (0, react_1.useState)(initialFormState), form = _b[0], setForm = _b[1];
88
- var _c = (0, react_1.useState)(""), message = _c[0], setMessage = _c[1];
88
+ var loading = _a.loading, movaAppType = _a.movaAppType, onSubmit = _a.onSubmit, onSubmitForgotPassword = _a.onSubmitForgotPassword, _b = _a.darkMode, darkMode = _b === void 0 ? false : _b, alertMessage = _a.alertMessage, alertSeverity = _a.alertSeverity, version = _a.version;
89
+ var _c = (0, react_1.useState)(initialFormState), form = _c[0], setForm = _c[1];
90
+ var _d = (0, react_1.useState)(""), message = _d[0], setMessage = _d[1];
89
91
  var theme = (0, material_1.useTheme)();
90
92
  var history = (0, react_router_dom_1.useHistory)();
91
- var _d = (0, react_1.useState)(false), openForgotPassword = _d[0], setOpenForgotPassword = _d[1];
92
- var _e = (0, react_1.useState)(false), showPassword = _e[0], setShowPassword = _e[1];
93
+ var _e = (0, react_1.useState)(false), openForgotPassword = _e[0], setOpenForgotPassword = _e[1];
94
+ var _f = (0, react_1.useState)(false), showPassword = _f[0], setShowPassword = _f[1];
93
95
  var handleInputChange = function (e) {
94
96
  var _a;
95
97
  var fieldName = e.target.name;
@@ -125,9 +127,16 @@ var MovaLogin = function (_a) {
125
127
  return newForm.email.isValid && newForm.password.isValid;
126
128
  };
127
129
  var getMovaLogo = function () {
128
- return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_png_1.default :
129
- movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_png_1.default :
130
- movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_png_1.default : logo_large_png_1.default;
130
+ if (darkMode) {
131
+ return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_dm_png_1.default :
132
+ movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_dm_png_1.default :
133
+ movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_dm_png_1.default : logo_large_dm_png_1.default;
134
+ }
135
+ else {
136
+ return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_png_1.default :
137
+ movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_png_1.default :
138
+ movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_png_1.default : logo_large_png_1.default;
139
+ }
131
140
  };
132
141
  var handleOnClickSignUp = function (e) {
133
142
  e.preventDefault();
@@ -170,9 +179,17 @@ var MovaLogin = function (_a) {
170
179
  display: 'flex',
171
180
  flexDirection: 'column',
172
181
  alignItems: 'center',
173
- } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '80%' } }), (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: [(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", autoFocus: true, onChange: function (e) { return handleInputChange(e); }, value: form.email.value, error: !form.email.isValid, helperText: form.email.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, name: "password", label: "Mot de passe", type: showPassword ? 'text' : 'password', id: "password", autoComplete: "current-password", onChange: function (e) { return handleInputChange(e); }, value: form.password.value, error: !form.password.isValid, helperText: form.password.error, InputProps: {
182
+ } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '80%' } }), (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: [(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", autoFocus: true, onChange: function (e) { return handleInputChange(e); }, value: form.email.value, error: !form.email.isValid, helperText: form.email.error, sx: {
183
+ '& .MuiOutlinedInput-notchedOutline': {
184
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
185
+ }
186
+ } }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, name: "password", label: "Mot de passe", type: showPassword ? 'text' : 'password', id: "password", autoComplete: "current-password", onChange: function (e) { return handleInputChange(e); }, value: form.password.value, error: !form.password.isValid, helperText: form.password.error, InputProps: {
174
187
  endAdornment: ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, __assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ edge: "end", onClick: handleClickShowPassword }, { children: showPassword ? (0, jsx_runtime_1.jsx)(VisibilityOff_1.default, {}) : (0, jsx_runtime_1.jsx)(Visibility_1.default, {}) })) }))),
175
- } }), (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 } }, { children: (0, jsx_runtime_1.jsx)("span", { children: "Se connecter" }) })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (0, jsx_runtime_1.jsxs)(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(e); }, sx: { cursor: 'pointer' } }, { children: "Mot de passe oubli\u00E9 ?" })) })), movaAppType === Enums_1.MovaAppType.INDIVIDUAL && (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ variant: "body2", color: "text.secondary", onClick: function (e) { return handleOnClickSignUp(e); }, sx: { cursor: 'pointer' } }, { children: "Cr\u00E9er mon compte" })) }))] }))] })), (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 && dialogForgotPassword()] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: { position: 'fixed',
188
+ }, sx: {
189
+ '& .MuiOutlinedInput-notchedOutline': {
190
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
191
+ }
192
+ } }), (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" }) })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (0, jsx_runtime_1.jsxs)(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(e); }, sx: { cursor: 'pointer' } }, { children: "Mot de passe oubli\u00E9 ?" })) })), movaAppType === Enums_1.MovaAppType.INDIVIDUAL && (0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ variant: "body2", color: "text.secondary", onClick: function (e) { return handleOnClickSignUp(e); }, sx: { cursor: 'pointer' } }, { children: "Cr\u00E9er mon compte" })) }))] }))] })), (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 && dialogForgotPassword()] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: { position: 'fixed',
176
193
  float: 'right',
177
194
  width: '250px',
178
195
  height: '400px',
@@ -13,6 +13,7 @@ import { MovaAppType } from "./helpers/Enums";
13
13
  interface MovaSignUpProps {
14
14
  movaAppType: MovaAppType;
15
15
  onSubmit: (form: MovaUserSignUpForm) => void;
16
+ darkMode: boolean;
16
17
  alertMessage?: string;
17
18
  alertSeverity?: AlertColor;
18
19
  loading?: boolean;
@@ -56,6 +56,8 @@ var lab_1 = require("@mui/lab");
56
56
  var DatePicker_1 = require("@mui/x-date-pickers/DatePicker");
57
57
  var logo_large_png_1 = __importDefault(require("./assets/images/logo/logo_large.png"));
58
58
  var logo_pro_large_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large.png"));
59
+ var logo_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_large_dm.png"));
60
+ var logo_pro_large_dm_png_1 = __importDefault(require("./assets/images/logo/logo_pro_large_dm.png"));
59
61
  var leaf_green_large_png_1 = __importDefault(require("./assets/images/leaf_green_large.png"));
60
62
  var leaf_pink_large_png_1 = __importDefault(require("./assets/images/leaf_pink_large.png"));
61
63
  var material_1 = require("@mui/material");
@@ -89,11 +91,12 @@ var initialUserFormState = {
89
91
  * ATTENTION : le lien de consultation des CGU doit pointer vers "/terms-and-conditions"
90
92
  */
91
93
  var MovaLogin = function (_a) {
92
- var loading = _a.loading, movaAppType = _a.movaAppType, onSubmit = _a.onSubmit, alertMessage = _a.alertMessage, alertSeverity = _a.alertSeverity;
93
- var _b = (0, react_1.useState)(initialUserFormState), userForm = _b[0], setUserForm = _b[1];
94
+ var loading = _a.loading, movaAppType = _a.movaAppType, onSubmit = _a.onSubmit, _b = _a.darkMode, darkMode = _b === void 0 ? false : _b, alertMessage = _a.alertMessage, alertSeverity = _a.alertSeverity;
95
+ var _c = (0, react_1.useState)(initialUserFormState), userForm = _c[0], setUserForm = _c[1];
94
96
  var history = (0, react_router_dom_1.useHistory)();
95
- var _c = (0, react_1.useState)(""), message = _c[0], setMessage = _c[1];
96
- var _d = (0, react_1.useState)(false), showPassword = _d[0], setShowPassword = _d[1];
97
+ var _d = (0, react_1.useState)(""), message = _d[0], setMessage = _d[1];
98
+ var theme = (0, material_1.useTheme)();
99
+ var _e = (0, react_1.useState)(false), showPassword = _e[0], setShowPassword = _e[1];
97
100
  var handleDateChange = function (name, date) {
98
101
  var _a;
99
102
  console.log(date);
@@ -162,9 +165,16 @@ var MovaLogin = function (_a) {
162
165
  && newForm.gender.isValid && newForm.birthDate.isValid && newForm.acceptsTerms.isValid;
163
166
  };
164
167
  var getMovaLogo = function () {
165
- return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_png_1.default :
166
- movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_png_1.default :
167
- movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_png_1.default : logo_large_png_1.default;
168
+ if (darkMode) {
169
+ return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_dm_png_1.default :
170
+ movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_dm_png_1.default :
171
+ movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_dm_png_1.default : logo_large_dm_png_1.default;
172
+ }
173
+ else {
174
+ return movaAppType === Enums_1.MovaAppType.GARAGE ? logo_pro_large_png_1.default :
175
+ movaAppType === Enums_1.MovaAppType.INDIVIDUAL ? logo_large_png_1.default :
176
+ movaAppType === Enums_1.MovaAppType.ADMIN ? logo_large_png_1.default : logo_large_png_1.default;
177
+ }
168
178
  };
169
179
  var handleOnClickLogin = function (e) {
170
180
  e.preventDefault();
@@ -188,20 +198,43 @@ var MovaLogin = function (_a) {
188
198
  display: 'flex',
189
199
  flexDirection: 'column',
190
200
  alignItems: 'center',
191
- } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '50%' } }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "button", sx: { pt: 2 } }, { children: "Nouveau compte utilisateur" }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ component: "form", onSubmit: handleSubmit, noValidate: true, sx: { mt: 1 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, autoFocus: true, fullWidth: true, id: "firstname", label: "Pr\u00E9nom", name: "firstname", autoComplete: "given-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.firstname.value, error: Boolean(userForm.firstname.error), helperText: userForm.firstname.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "lastname", label: "Nom", name: "lastname", autoComplete: "family-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.lastname.value, error: Boolean(userForm.lastname.error), helperText: userForm.lastname.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", onChange: function (e) { return handleInputChange(e); }, value: userForm.email.value, error: !userForm.email.isValid, helperText: userForm.email.error }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, name: "password", label: "Mot de passe", type: showPassword ? 'text' : 'password', id: "password", autoComplete: "current-password", onChange: function (e) { return handleInputChange(e); }, value: userForm.password.value, error: !userForm.password.isValid, helperText: Boolean(userForm.password.error) ? userForm.password.error : "10 caractères minimum, 1 majuscule, 1 minuscule", InputProps: {
201
+ } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: getMovaLogo(), style: { width: '50%' } }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "button", sx: { pt: 2 } }, { children: "Nouveau compte utilisateur" }))] })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ component: "form", onSubmit: handleSubmit, noValidate: true, sx: { mt: 1 } }, { children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, autoFocus: true, fullWidth: true, id: "firstname", label: "Pr\u00E9nom", name: "firstname", autoComplete: "given-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.firstname.value, error: Boolean(userForm.firstname.error), helperText: userForm.firstname.error, sx: {
202
+ '& .MuiOutlinedInput-notchedOutline': {
203
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
204
+ }
205
+ } }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "lastname", label: "Nom", name: "lastname", autoComplete: "family-name", onChange: function (e) { return handleInputChange(e); }, value: userForm.lastname.value, error: Boolean(userForm.lastname.error), helperText: userForm.lastname.error, sx: {
206
+ '& .MuiOutlinedInput-notchedOutline': {
207
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
208
+ }
209
+ } }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, id: "email", label: "Adresse email", name: "email", autoComplete: "email", onChange: function (e) { return handleInputChange(e); }, value: userForm.email.value, error: !userForm.email.isValid, helperText: userForm.email.error, sx: {
210
+ '& .MuiOutlinedInput-notchedOutline': {
211
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
212
+ }
213
+ } }), (0, jsx_runtime_1.jsx)(material_1.TextField, { margin: "normal", required: true, fullWidth: true, name: "password", label: "Mot de passe", type: showPassword ? 'text' : 'password', id: "password", autoComplete: "current-password", onChange: function (e) { return handleInputChange(e); }, value: userForm.password.value, error: !userForm.password.isValid, helperText: Boolean(userForm.password.error) ? userForm.password.error : "10 caractères minimum, 1 majuscule, 1 minuscule", InputProps: {
192
214
  endAdornment: ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, __assign({ position: "end" }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ edge: "end", onClick: handleClickShowPassword }, { children: showPassword ? (0, jsx_runtime_1.jsx)(VisibilityOff_1.default, {}) : (0, jsx_runtime_1.jsx)(Visibility_1.default, {}) })) }))),
193
- } }), (0, jsx_runtime_1.jsx)(GenderSelector_1.default, { handleSelectChange: handleSelectChange, form: userForm, required: true, sx: { width: '40%', mr: 2 } }), (0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, { label: "Date de naissance", value: userForm.birthDate.value, format: 'dd / MM / yyyy', formatDensity: 'dense',
194
- //views={['day']}
195
- displayWeekNumber: true, onChange: function (newValue) { return handleDateChange('birthDate', newValue); }, slotProps: {
215
+ }, sx: {
216
+ '& .MuiOutlinedInput-notchedOutline': {
217
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
218
+ }
219
+ } }), (0, jsx_runtime_1.jsx)(GenderSelector_1.default, { handleSelectChange: handleSelectChange, form: userForm, required: true, sx: {
220
+ width: '40%',
221
+ mr: 2,
222
+ '& .MuiOutlinedInput-notchedOutline': {
223
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
224
+ }
225
+ } }), (0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, { label: "Date de naissance", value: userForm.birthDate.value, format: 'dd / MM / yyyy', formatDensity: 'dense', openTo: "year", views: ['year', 'month', 'day'], onChange: function (newValue) { return handleDateChange('birthDate', newValue); }, slotProps: {
196
226
  textField: {
197
227
  required: true,
198
228
  error: !userForm.birthDate.isValid,
199
229
  sx: {
200
230
  width: '50%', mt: 2, float: 'right',
201
231
  padding: 0,
232
+ '& .MuiOutlinedInput-notchedOutline': {
233
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
234
+ }
202
235
  },
203
236
  },
204
- } }), (0, jsx_runtime_1.jsxs)(material_1.FormControl, __assign({ error: !userForm.acceptsTerms.isValid }, { children: [(0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { name: "acceptsTerms", color: "primary", checked: userForm.acceptsTerms.value, onChange: function (e, checked) { return handleCheckboxChange(e, checked); } }), label: (0, jsx_runtime_1.jsxs)("span", { children: ["J'accepte les", ' ', (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ href: "/terms-and-conditions", target: "_blank" }, { children: "Conditions G\u00E9n\u00E9rales d'Utilisation" }))] }) }), (0, jsx_runtime_1.jsx)(material_1.FormHelperText, { children: userForm.acceptsTerms.error })] })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (0, jsx_runtime_1.jsx)(lab_1.LoadingButton, __assign({ loading: loading, type: "submit", fullWidth: true, variant: "contained", sx: { mt: 3, mb: 2 } }, { children: (0, jsx_runtime_1.jsx)("span", { children: "Cr\u00E9er mon compte" }) })), (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 handleOnClickLogin(e); }, sx: { cursor: 'pointer' } }, { children: "Se connecter" })) })) }))] })), (0, jsx_runtime_1.jsx)(MovaCopyright_1.default, { sx: { mt: 8, mb: 4 } })] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: { position: 'fixed',
237
+ } }), (0, jsx_runtime_1.jsxs)(material_1.FormControl, __assign({ error: !userForm.acceptsTerms.isValid }, { children: [(0, jsx_runtime_1.jsx)(material_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(material_1.Checkbox, { name: "acceptsTerms", color: "primary", checked: userForm.acceptsTerms.value, onChange: function (e, checked) { return handleCheckboxChange(e, checked); } }), label: (0, jsx_runtime_1.jsxs)("span", { children: ["J'accepte les", ' ', (0, jsx_runtime_1.jsx)(material_1.Link, __assign({ href: "/terms-and-conditions", target: "_blank" }, { children: "Conditions G\u00E9n\u00E9rales d'Utilisation" }))] }) }), (0, jsx_runtime_1.jsx)(material_1.FormHelperText, { children: userForm.acceptsTerms.error })] })), alertMessage && alertSeverity && (0, jsx_runtime_1.jsx)(material_1.Alert, __assign({ severity: alertSeverity, sx: { mb: 2 } }, { children: alertMessage })), (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: "Cr\u00E9er mon compte" }) })), (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 handleOnClickLogin(e); }, sx: { cursor: 'pointer' } }, { children: "Se connecter" })) })) }))] })), (0, jsx_runtime_1.jsx)(MovaCopyright_1.default, { sx: { mt: 8, mb: 4 } })] })), (0, jsx_runtime_1.jsx)("img", { src: leaf_pink_large_png_1.default, style: { position: 'fixed',
205
238
  float: 'right',
206
239
  width: '250px',
207
240
  height: '400px',
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
@@ -6,20 +17,71 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
17
  var jsx_runtime_1 = require("react/jsx-runtime");
7
18
  var react_1 = require("react");
8
19
  var TextField_1 = __importDefault(require("@mui/material/TextField"));
9
- // Regex pour une plaque d'immatriculation française
20
+ var Enums_1 = require("./helpers/Enums");
21
+ var Logger_1 = __importDefault(require("./helpers/Logger"));
22
+ var material_1 = require("@mui/material");
23
+ var SearchRounded_1 = __importDefault(require("@mui/icons-material/SearchRounded"));
24
+ // Regex pour une plaque d'immatriculation française (nouveau format SIV)
10
25
  var regex = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
26
+ // Regex pour une plaque d'immatriculation française (ancien format FNI)
27
+ var oldRegex = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
11
28
  var VehiclePlateField = function (_a) {
12
29
  var onValidVehiclePlate = _a.onValidVehiclePlate;
13
30
  var _b = (0, react_1.useState)(''), value = _b[0], setValue = _b[1];
14
31
  var _c = (0, react_1.useState)(false), error = _c[0], setError = _c[1];
15
32
  var _d = (0, react_1.useState)(0), lastLength = _d[0], setLastLength = _d[1]; // Ajout d'un état pour stocker la longueur précédente
33
+ var _e = (0, react_1.useState)(''), helperText = _e[0], setHelperText = _e[1];
34
+ // Hook de validation de la plaque
16
35
  (0, react_1.useEffect)(function () {
17
36
  if (!error && value !== '' && value.match(regex)) {
18
37
  onValidVehiclePlate(value);
19
38
  }
20
39
  }, [error, value, onValidVehiclePlate]);
40
+ var getPlateFormat = function (plate) {
41
+ if (/^[A-Za-z]/.test(plate)) {
42
+ // Commence par une lettre => nouveau format
43
+ return Enums_1.VehiclePlateFormat.FRENCH_NEW;
44
+ }
45
+ else if (/^\d/.test(plate)) {
46
+ // Commence par un chiffre => ancien format
47
+ return Enums_1.VehiclePlateFormat.FRENCH_OLD;
48
+ }
49
+ else {
50
+ Logger_1.default.error("Format de plaque inconnu");
51
+ // On retourne le nouveau format par défaut
52
+ return Enums_1.VehiclePlateFormat.FRENCH_NEW;
53
+ }
54
+ };
21
55
  var handleChange = function (e) {
22
56
  var inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
57
+ // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
58
+ switch (getPlateFormat(inputValue)) {
59
+ case Enums_1.VehiclePlateFormat.FRENCH_NEW: {
60
+ setHelperText((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Format d\u00E9tect\u00E9 : ", (0, jsx_runtime_1.jsx)("b", { children: "AA-111-AA" })] }));
61
+ handleChangeFrenchNew(inputValue);
62
+ break;
63
+ }
64
+ case Enums_1.VehiclePlateFormat.FRENCH_OLD: {
65
+ setHelperText((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Format d\u00E9tect\u00E9 (ancien) : ", (0, jsx_runtime_1.jsx)("b", { children: "1111 AAAA 1111" })] }));
66
+ handleChangeFrenchOld(inputValue);
67
+ break;
68
+ }
69
+ }
70
+ };
71
+ var validatePlate = function () {
72
+ if (oldRegex.test(value)) {
73
+ onValidVehiclePlate(value);
74
+ }
75
+ setError(!oldRegex.test(value));
76
+ };
77
+ var handleChangeFrenchOld = function (inputValue) {
78
+ // ON bloque la saisie à 12 caractères max (limite des anciennes plaques)
79
+ if (!(inputValue.length > 12)) {
80
+ setValue(inputValue);
81
+ }
82
+ setLastLength(inputValue.length); // Mettre à jour la longueur précédente
83
+ };
84
+ var handleChangeFrenchNew = function (inputValue) {
23
85
  // Vérifier si l'utilisateur est en train de supprimer un caractère
24
86
  var isDeleting = inputValue.length < lastLength;
25
87
  // Supprimer les tirets pour avoir une chaîne propre
@@ -32,12 +94,20 @@ var VehiclePlateField = function (_a) {
32
94
  inputValue = "".concat(cleanInput.slice(0, 2), "-").concat(cleanInput.slice(2, 5), "-").concat(cleanInput.slice(5, 7));
33
95
  }
34
96
  setValue(inputValue);
35
- setError(!regex.test(inputValue));
97
+ // On teste la plaque une fois la saisie terminée
98
+ if (inputValue.length == 9) {
99
+ setError(!regex.test(inputValue));
100
+ }
101
+ else {
102
+ setError(false);
103
+ }
36
104
  setLastLength(inputValue.length); // Mettre à jour la longueur précédente
37
105
  };
38
106
  return ((0, jsx_runtime_1.jsx)(TextField_1.default, { label: "Plaque d'immatriculation", variant: "outlined", value: value, onChange: handleChange, error: error, autoFocus: true, sx: {
39
107
  width: '100%',
40
108
  '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
41
- }, helperText: error ? "Utilisez le format 'XX-123-XX'" : '' }));
109
+ }, helperText: lastLength > 0 ? helperText : '', InputProps: {
110
+ endAdornment: ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, __assign({ position: "end", sx: { mr: 1, display: getPlateFormat(value) === Enums_1.VehiclePlateFormat.FRENCH_OLD ? 'inherit' : 'none' } }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ edge: "end", onClick: validatePlate }, { children: (0, jsx_runtime_1.jsx)(SearchRounded_1.default, {}) })) }))),
111
+ } }));
42
112
  };
43
113
  exports.default = VehiclePlateField;
@@ -1,3 +1,7 @@
1
+ export declare enum VehiclePlateFormat {
2
+ FRENCH_NEW = "FRENCH_NEW",
3
+ FRENCH_OLD = "FRENCH_OLD"
4
+ }
1
5
  export declare enum SlotAlgorithm {
2
6
  /**
3
7
  * Calcul des créneaux à l'heure
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RoleType = exports.MovaAppType = exports.DocumentType = exports.DocumentState = exports.DayOfWeek = exports.EventType = exports.EventState = exports.DigitalPassportIndex = exports.Gender = exports.DateFormatTypes = exports.APIMethod = exports.PartsApplicationType = exports.ProductType = exports.OrderPreference = exports.OrderState = exports.SlotAlgorithm = void 0;
3
+ exports.RoleType = exports.MovaAppType = exports.DocumentType = exports.DocumentState = exports.DayOfWeek = exports.EventType = exports.EventState = exports.DigitalPassportIndex = exports.Gender = exports.DateFormatTypes = exports.APIMethod = exports.PartsApplicationType = exports.ProductType = exports.OrderPreference = exports.OrderState = exports.SlotAlgorithm = exports.VehiclePlateFormat = void 0;
4
+ var VehiclePlateFormat;
5
+ (function (VehiclePlateFormat) {
6
+ VehiclePlateFormat["FRENCH_NEW"] = "FRENCH_NEW";
7
+ VehiclePlateFormat["FRENCH_OLD"] = "FRENCH_OLD";
8
+ })(VehiclePlateFormat = exports.VehiclePlateFormat || (exports.VehiclePlateFormat = {}));
4
9
  var SlotAlgorithm;
5
10
  (function (SlotAlgorithm) {
6
11
  /**
package/index.ts CHANGED
@@ -56,5 +56,5 @@ export { formatDateByCountryCode, getLongFormattedDateTime, capitalizeFirstLette
56
56
  // Export des enums
57
57
  export { RoleType, MovaAppType, DayOfWeek, EventState, EventType, DocumentType,
58
58
  DigitalPassportIndex, DocumentState, Gender, DateFormatTypes, PartsApplicationType,
59
- ProductType, OrderPreference, OrderState, SlotAlgorithm } from './src/helpers/Enums';
59
+ ProductType, OrderPreference, OrderState, SlotAlgorithm, VehiclePlateFormat as VehiclePlateType } from './src/helpers/Enums';
60
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movalib/movalib-commons",
3
- "version": "1.1.15",
3
+ "version": "1.1.17",
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",
package/src/MovaLogin.tsx CHANGED
@@ -2,6 +2,8 @@ import { CSSProperties, FormEvent, FunctionComponent, useState } from "react";
2
2
  import { LoadingButton } from '@mui/lab';
3
3
  import LogoLarge from './assets/images/logo/logo_large.png';
4
4
  import LogoProLarge from './assets/images/logo/logo_pro_large.png';
5
+ import LogoLargeDarkMode from './assets/images/logo/logo_large_dm.png';
6
+ import LogoProLargeDarkMode from './assets/images/logo/logo_pro_large_dm.png';
5
7
  import GreenLeafImage from "./assets/images/leaf_green_large.png";
6
8
  import PinkLeafImage from "./assets/images/leaf_pink_large.png";
7
9
  import { Alert, AlertColor, Box, Button, Checkbox, Container, CssBaseline, Dialog, DialogActions, DialogContent, DialogContentText,
@@ -41,6 +43,7 @@ interface MovaLoginProps {
41
43
  movaAppType: MovaAppType,
42
44
  onSubmit: (form: MovaLoginForm) => void,
43
45
  onSubmitForgotPassword: (email: string) => void,
46
+ darkMode: boolean,
44
47
  alertMessage?: string,
45
48
  alertSeverity?: AlertColor,
46
49
  loading?: boolean,
@@ -52,7 +55,7 @@ interface MovaLoginProps {
52
55
  * ATTENTION : la page attendue pour le bouton "Mot de passe oublié" doit pointer vers "/forgot-password"
53
56
  * ATTENTION : la page attendue pour le bouton "Créer mon compte" doit pointer vers "/signup"
54
57
  */
55
- const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, onSubmit, onSubmitForgotPassword, alertMessage, alertSeverity, version }) => {
58
+ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, onSubmit, onSubmitForgotPassword, darkMode = false, alertMessage, alertSeverity, version }) => {
56
59
 
57
60
  const [form, setForm] = useState<MovaLoginForm>(initialFormState);
58
61
  const [message, setMessage] = useState<string>("");
@@ -104,9 +107,15 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
104
107
 
105
108
  const getMovaLogo = () => {
106
109
 
107
- return movaAppType === MovaAppType.GARAGE ? LogoProLarge :
110
+ if(darkMode){
111
+ return movaAppType === MovaAppType.GARAGE ? LogoProLargeDarkMode :
112
+ movaAppType === MovaAppType.INDIVIDUAL ? LogoLargeDarkMode :
113
+ movaAppType === MovaAppType.ADMIN ? LogoLargeDarkMode : LogoLargeDarkMode;
114
+ } else {
115
+ return movaAppType === MovaAppType.GARAGE ? LogoProLarge :
108
116
  movaAppType === MovaAppType.INDIVIDUAL ? LogoLarge :
109
117
  movaAppType === MovaAppType.ADMIN ? LogoLarge : LogoLarge;
118
+ }
110
119
  }
111
120
 
112
121
  const handleOnClickSignUp = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
@@ -221,6 +230,11 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
221
230
  value={form.email.value}
222
231
  error={!form.email.isValid}
223
232
  helperText={form.email.error}
233
+ sx={{
234
+ '& .MuiOutlinedInput-notchedOutline': {
235
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
236
+ }
237
+ }}
224
238
  />
225
239
  <TextField
226
240
  margin="normal"
@@ -241,12 +255,18 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
241
255
  <IconButton
242
256
  edge="end"
243
257
  onClick={handleClickShowPassword}
258
+
244
259
  >
245
260
  {showPassword ? <VisibilityOff /> : <Visibility />}
246
261
  </IconButton>
247
262
  </InputAdornment>
248
263
  ),
249
- }}
264
+ }}
265
+ sx={{
266
+ '& .MuiOutlinedInput-notchedOutline': {
267
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
268
+ }
269
+ }}
250
270
  />
251
271
  <FormControlLabel control={<Checkbox value="remember" color="primary" />}
252
272
  label="Se souvenir de moi"
@@ -257,7 +277,7 @@ const MovaLogin: FunctionComponent<MovaLoginProps> = ({ loading, movaAppType, on
257
277
  type="submit"
258
278
  fullWidth
259
279
  variant="contained"
260
- sx={{ mt: 3, mb: 2 }}>
280
+ sx={{ mt: 3, mb: 2, backgroundColor: darkMode ? theme.palette.primary.dark : theme.palette.primary.main }}>
261
281
  <span>Se connecter</span>
262
282
  </LoadingButton>
263
283
 
@@ -3,10 +3,12 @@ import { LoadingButton } from '@mui/lab';
3
3
  import { DatePicker } from '@mui/x-date-pickers/DatePicker';
4
4
  import LogoLarge from './assets/images/logo/logo_large.png';
5
5
  import LogoProLarge from './assets/images/logo/logo_pro_large.png';
6
+ import LogoLargeDarkMode from './assets/images/logo/logo_large_dm.png';
7
+ import LogoProLargeDarkMode from './assets/images/logo/logo_pro_large_dm.png';
6
8
  import GreenLeafImage from "./assets/images/leaf_green_large.png";
7
9
  import PinkLeafImage from "./assets/images/leaf_pink_large.png";
8
10
  import { Alert, AlertColor, Box, Checkbox, Container, CssBaseline, FormControl, FormControlLabel, FormHelperText, Grid,
9
- IconButton, Link, SelectChangeEvent, TextField, Typography, TextFieldProps } from "@mui/material";
11
+ IconButton, Link, SelectChangeEvent, TextField, Typography, TextFieldProps, useTheme } from "@mui/material";
10
12
  import MovaCopyright from "./MovaCopyright";
11
13
  import { MovaFormField, MovaUserSignUpForm } from "./helpers/Types";
12
14
  import { MovaAppType } from "./helpers/Enums";
@@ -47,6 +49,7 @@ const initialUserFormState = {
47
49
  interface MovaSignUpProps {
48
50
  movaAppType: MovaAppType,
49
51
  onSubmit: (form: MovaUserSignUpForm) => void,
52
+ darkMode: boolean,
50
53
  alertMessage?: string,
51
54
  alertSeverity?: AlertColor,
52
55
  loading?: boolean
@@ -56,11 +59,12 @@ interface MovaSignUpProps {
56
59
  * Formulaire de création d'un compte Movalib (Garage / Utilisateur)
57
60
  * ATTENTION : le lien de consultation des CGU doit pointer vers "/terms-and-conditions"
58
61
  */
59
- const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, onSubmit, alertMessage, alertSeverity }) => {
62
+ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, onSubmit, darkMode = false, alertMessage, alertSeverity }) => {
60
63
 
61
64
  const [userForm, setUserForm] = useState<MovaUserSignUpForm>(initialUserFormState);
62
65
  const history = useHistory();
63
66
  const [message, setMessage] = useState<string>("");
67
+ const theme = useTheme();
64
68
  const [showPassword, setShowPassword] = useState(false);
65
69
 
66
70
  const handleDateChange = (name: string, date: Date | null) => {
@@ -143,10 +147,15 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
143
147
  }
144
148
 
145
149
  const getMovaLogo = () => {
146
-
147
- return movaAppType === MovaAppType.GARAGE ? LogoProLarge :
150
+ if(darkMode){
151
+ return movaAppType === MovaAppType.GARAGE ? LogoProLargeDarkMode :
152
+ movaAppType === MovaAppType.INDIVIDUAL ? LogoLargeDarkMode :
153
+ movaAppType === MovaAppType.ADMIN ? LogoLargeDarkMode : LogoLargeDarkMode;
154
+ } else {
155
+ return movaAppType === MovaAppType.GARAGE ? LogoProLarge :
148
156
  movaAppType === MovaAppType.INDIVIDUAL ? LogoLarge :
149
157
  movaAppType === MovaAppType.ADMIN ? LogoLarge : LogoLarge;
158
+ }
150
159
  }
151
160
 
152
161
  const handleOnClickLogin = (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
@@ -201,6 +210,11 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
201
210
  value={userForm.firstname.value}
202
211
  error={Boolean(userForm.firstname.error)}
203
212
  helperText={userForm.firstname.error}
213
+ sx={{
214
+ '& .MuiOutlinedInput-notchedOutline': {
215
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
216
+ }
217
+ }}
204
218
  />
205
219
  <TextField
206
220
  margin="normal"
@@ -214,6 +228,11 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
214
228
  value={userForm.lastname.value}
215
229
  error={Boolean(userForm.lastname.error)}
216
230
  helperText={userForm.lastname.error}
231
+ sx={{
232
+ '& .MuiOutlinedInput-notchedOutline': {
233
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
234
+ }
235
+ }}
217
236
  />
218
237
  <TextField
219
238
  margin="normal"
@@ -227,6 +246,11 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
227
246
  value={userForm.email.value}
228
247
  error={!userForm.email.isValid}
229
248
  helperText={userForm.email.error}
249
+ sx={{
250
+ '& .MuiOutlinedInput-notchedOutline': {
251
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
252
+ }
253
+ }}
230
254
  />
231
255
  <TextField
232
256
  margin="normal"
@@ -253,9 +277,20 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
253
277
  </InputAdornment>
254
278
  ),
255
279
  }}
280
+ sx={{
281
+ '& .MuiOutlinedInput-notchedOutline': {
282
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
283
+ }
284
+ }}
256
285
  />
257
286
 
258
- <GenderSelector handleSelectChange={handleSelectChange} form={userForm} required sx={{ width:'40%', mr: 2}} />
287
+ <GenderSelector handleSelectChange={handleSelectChange} form={userForm} required sx={{
288
+ width:'40%',
289
+ mr: 2,
290
+ '& .MuiOutlinedInput-notchedOutline': {
291
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
292
+ }
293
+ }} />
259
294
 
260
295
  {/* <TextField
261
296
  margin="normal"
@@ -279,8 +314,8 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
279
314
  value={userForm.birthDate.value}
280
315
  format='dd / MM / yyyy'
281
316
  formatDensity='dense'
282
- //views={['day']}
283
- displayWeekNumber
317
+ openTo="year"
318
+ views={['year', 'month', 'day']}
284
319
  onChange={(newValue) => handleDateChange('birthDate', newValue)}
285
320
  slotProps={{
286
321
  textField: {
@@ -289,6 +324,9 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
289
324
  sx: {
290
325
  width:'50%', mt: 2, float: 'right',
291
326
  padding: 0,
327
+ '& .MuiOutlinedInput-notchedOutline': {
328
+ borderColor: darkMode ? 'white' : 'default', // Couleur de la bordure
329
+ }
292
330
  },
293
331
  },
294
332
  }}
@@ -323,7 +361,7 @@ const MovaLogin: FunctionComponent<MovaSignUpProps> = ({ loading, movaAppType, o
323
361
  type="submit"
324
362
  fullWidth
325
363
  variant="contained"
326
- sx={{ mt: 3, mb: 2 }}>
364
+ sx={{ mt: 3, mb: 2, backgroundColor: darkMode ? theme.palette.primary.dark : theme.palette.primary.main }}>
327
365
  <span>Créer mon compte</span>
328
366
  </LoadingButton>
329
367
 
@@ -1,48 +1,118 @@
1
- import React, { FunctionComponent, useEffect, useState } from 'react';
1
+ import React, { FunctionComponent, ReactNode, useEffect, useState } from 'react';
2
2
  import TextField from '@mui/material/TextField';
3
+ import { VehiclePlateFormat } from './helpers/Enums';
4
+ import Logger from './helpers/Logger';
5
+ import { IconButton, InputAdornment } from '@mui/material';
6
+ import SearchIcon from '@mui/icons-material/SearchRounded';
3
7
 
4
8
  interface VehiclePlateFieldProps {
5
9
  onValidVehiclePlate: (vehiclePlate: string) => void;
6
10
  }
7
11
 
8
- // Regex pour une plaque d'immatriculation française
12
+ // Regex pour une plaque d'immatriculation française (nouveau format SIV)
9
13
  const regex = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
14
+ // Regex pour une plaque d'immatriculation française (ancien format FNI)
15
+ const oldRegex = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
16
+
10
17
 
11
18
  const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidVehiclePlate }) => {
12
19
 
13
20
  const [value, setValue] = useState<string>('');
14
21
  const [error, setError] = useState<boolean>(false);
15
22
  const [lastLength, setLastLength] = useState<number>(0); // Ajout d'un état pour stocker la longueur précédente
23
+ const [helperText, setHelperText] = useState<ReactNode>('');
16
24
 
25
+ // Hook de validation de la plaque
17
26
  useEffect(() => {
18
27
  if (!error && value !== '' && value.match(regex)) {
19
28
  onValidVehiclePlate(value);
20
29
  }
30
+
21
31
  }, [error, value, onValidVehiclePlate]);
22
32
 
33
+ const getPlateFormat = (plate: string): VehiclePlateFormat => {
34
+ if (/^[A-Za-z]/.test(plate)) {
35
+ // Commence par une lettre => nouveau format
36
+ return VehiclePlateFormat.FRENCH_NEW;
37
+ } else if (/^\d/.test(plate)) {
38
+ // Commence par un chiffre => ancien format
39
+ return VehiclePlateFormat.FRENCH_OLD;
40
+ } else {
41
+ Logger.error("Format de plaque inconnu");
42
+ // On retourne le nouveau format par défaut
43
+ return VehiclePlateFormat.FRENCH_NEW;
44
+ }
45
+ }
46
+
23
47
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
24
48
 
25
49
  let inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
26
50
 
27
- // Vérifier si l'utilisateur est en train de supprimer un caractère
28
- const isDeleting = inputValue.length < lastLength;
51
+ // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
52
+ switch(getPlateFormat(inputValue)){
29
53
 
30
- // Supprimer les tirets pour avoir une chaîne propre
31
- const cleanInput = inputValue.replace(/-/g, '');
54
+ case VehiclePlateFormat.FRENCH_NEW :{
55
+ setHelperText(<>Format détecté : <b>AA-111-AA</b></>);
56
+ handleChangeFrenchNew(inputValue);
57
+ break;
58
+ }
32
59
 
33
- // Ajouter des tirets aux positions appropriées
34
- if (cleanInput.length > 1 && !(cleanInput.length == 2 && isDeleting)) {
35
- inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2)}`;
60
+ case VehiclePlateFormat.FRENCH_OLD: {
61
+ setHelperText(<>Format détecté (ancien) : <b>1111 AAAA 1111</b></>);
62
+ handleChangeFrenchOld(inputValue);
63
+ break;
64
+ }
36
65
  }
37
66
 
38
- if (cleanInput.length > 4 && !(cleanInput.length == 5 && isDeleting)) {
39
- inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2, 5)}-${cleanInput.slice(5, 7)}`;
67
+ };
68
+
69
+ const validatePlate = () => {
70
+
71
+ if(oldRegex.test(value)){
72
+ onValidVehiclePlate(value);
40
73
  }
41
74
 
42
- setValue(inputValue);
43
- setError(!regex.test(inputValue));
44
- setLastLength(inputValue.length); // Mettre à jour la longueur précédente
45
- };
75
+ setError(!oldRegex.test(value));
76
+ }
77
+
78
+ const handleChangeFrenchOld = (inputValue: string) => {
79
+
80
+ // ON bloque la saisie à 12 caractères max (limite des anciennes plaques)
81
+ if(!(inputValue.length > 12)){
82
+ setValue(inputValue);
83
+ }
84
+
85
+ setLastLength(inputValue.length); // Mettre à jour la longueur précédente
86
+ }
87
+
88
+ const handleChangeFrenchNew = (inputValue: string) => {
89
+
90
+ // Vérifier si l'utilisateur est en train de supprimer un caractère
91
+ const isDeleting = inputValue.length < lastLength;
92
+
93
+ // Supprimer les tirets pour avoir une chaîne propre
94
+ const cleanInput = inputValue.replace(/-/g, '');
95
+
96
+ // Ajouter des tirets aux positions appropriées
97
+ if (cleanInput.length > 1 && !(cleanInput.length == 2 && isDeleting)) {
98
+ inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2)}`;
99
+ }
100
+
101
+ if (cleanInput.length > 4 && !(cleanInput.length == 5 && isDeleting)) {
102
+ inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2, 5)}-${cleanInput.slice(5, 7)}`;
103
+ }
104
+
105
+ setValue(inputValue);
106
+
107
+ // On teste la plaque une fois la saisie terminée
108
+ if(inputValue.length == 9){
109
+ setError(!regex.test(inputValue));
110
+ } else {
111
+ setError(false);
112
+ }
113
+
114
+ setLastLength(inputValue.length); // Mettre à jour la longueur précédente
115
+ }
46
116
 
47
117
  return (
48
118
  <TextField
@@ -56,7 +126,21 @@ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidV
56
126
  width: '100%',
57
127
  '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
58
128
  }}
59
- helperText={error ? "Utilisez le format 'XX-123-XX'" : ''}
129
+ helperText={lastLength > 0 ? helperText : ''}
130
+ InputProps={{
131
+ endAdornment: (
132
+
133
+ <InputAdornment position="end" sx={{ mr: 1, display: getPlateFormat(value) === VehiclePlateFormat.FRENCH_OLD ? 'inherit' : 'none' }} >
134
+ <IconButton
135
+ edge="end"
136
+ onClick={validatePlate}
137
+ >
138
+ <SearchIcon />
139
+ </IconButton>
140
+ </InputAdornment>
141
+
142
+ ),
143
+ }}
60
144
  />
61
145
  );
62
146
  };
@@ -1,16 +1,21 @@
1
+ export enum VehiclePlateFormat {
2
+ FRENCH_NEW = "FRENCH_NEW",
3
+ FRENCH_OLD ="FRENCH_OLD"
4
+ }
5
+
1
6
  export enum SlotAlgorithm {
2
7
  /**
3
8
  * Calcul des créneaux à l'heure
4
9
  */
5
- HOUR ="HOUR",
10
+ HOUR = "HOUR",
6
11
  /**
7
12
  * Calcul des créneaux à demi-heure
8
13
  */
9
- HALF_HOUR ="HALF_HOUR",
14
+ HALF_HOUR = "HALF_HOUR",
10
15
  /**
11
16
  * Calcul des créneaux à la période du jour (AM/PM)
12
17
  */
13
- DAY_PERIOD ="DAY_PERIOD"
18
+ DAY_PERIOD = "DAY_PERIOD"
14
19
  }
15
20
 
16
21
  export enum OrderState {