@movalib/movalib-commons 1.62.4 → 1.63.0

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
@@ -35,6 +35,8 @@ const App = () => {
35
35
  // Chargement de données garage de test
36
36
  const [garage, setGarage] = useState<Garage>();
37
37
  const [openAccountValidation, setOpenAccountValidation] = useState<Boolean>(false);
38
+ const [plateCountry, setPlateCountry] = useState<"FR" | "INTL">("FR");
39
+ const [plateModel, setPlateModel] = useState<string>();
38
40
 
39
41
  useEffect(() => {
40
42
  refreshGarageData();
@@ -119,10 +121,19 @@ const App = () => {
119
121
  gender: undefined
120
122
  }} />
121
123
 
122
- <Container style={flexCenter} sx={{ width: '400px', mt: 2}}>
123
- <VehiclePlateField onValidVehiclePlate={function (vehiclePlate: string): void {
124
- alert('plaque valide');
125
- } } />
124
+ <Container sx={{ width: '400px', mt: 2}}>
125
+ <VehiclePlateField
126
+ onCountryChange={(country) => {
127
+ console.log("Changement pays :", country);
128
+ setPlateCountry(country);
129
+ }}
130
+ onValidVehiclePlate={function (vehiclePlate: string, country: string): void {
131
+ console.log('plaque valide, pays :', country);
132
+ }} country={plateCountry} model={plateModel}
133
+ onModelChange={(model) => {
134
+ console.log("Changement modèle :", model);
135
+ setPlateModel(model);
136
+ }}/>
126
137
  </Container>
127
138
  <Container style={flexCenter} sx={{ width: '400px', mt: 2}}>
128
139
  <MovaVehicleTireField onChangeVehicleTire={(vehicleTire) => {
package/dist/devIndex.js CHANGED
@@ -69,6 +69,8 @@ var App = function () {
69
69
  // Chargement de données garage de test
70
70
  var _a = (0, react_1.useState)(), garage = _a[0], setGarage = _a[1];
71
71
  var _b = (0, react_1.useState)(false), openAccountValidation = _b[0], setOpenAccountValidation = _b[1];
72
+ var _c = (0, react_1.useState)("FR"), plateCountry = _c[0], setPlateCountry = _c[1];
73
+ var _d = (0, react_1.useState)(), plateModel = _d[0], setPlateModel = _d[1];
72
74
  (0, react_1.useEffect)(function () {
73
75
  refreshGarageData();
74
76
  }, []);
@@ -130,8 +132,14 @@ var App = function () {
130
132
  return;
131
133
  }, form: {
132
134
  gender: undefined
133
- } }), (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) {
134
- alert('plaque valide');
135
+ } }), (0, jsx_runtime_1.jsx)(material_1.Container, __assign({ sx: { width: '400px', mt: 2 } }, { children: (0, jsx_runtime_1.jsx)(VehiclePlateField_1.default, { onCountryChange: function (country) {
136
+ console.log("Changement pays :", country);
137
+ setPlateCountry(country);
138
+ }, onValidVehiclePlate: function (vehiclePlate, country) {
139
+ console.log('plaque valide, pays :', country);
140
+ }, country: plateCountry, model: plateModel, onModelChange: function (model) {
141
+ console.log("Changement modèle :", model);
142
+ setPlateModel(model);
135
143
  } }) })), (0, jsx_runtime_1.jsx)(material_1.Container, __assign({ style: Tools_1.flexCenter, sx: { width: '400px', mt: 2 } }, { children: (0, jsx_runtime_1.jsx)(MovaVehicleTireField_1.default, { onChangeVehicleTire: function (vehicleTire) {
136
144
  console.log('formatVehicleTire', (0, Tools_1.formatVehicleTire)(vehicleTire));
137
145
  } }) })), (0, jsx_runtime_1.jsx)(MovaLogin_1.default, { darkMode: false, movaAppType: Enums_1.MovaAppType.INDIVIDUAL, version: "0.1.3", onSubmit: function (form) {
package/dist/index.d.ts CHANGED
@@ -52,7 +52,7 @@ export type { APIRequest, APIResponse } from './src/helpers/ApiHelper';
52
52
  export type { DaySchedule, DayInterval } from './src/ScheduleFields';
53
53
  export type { MovaFormField, MovaLoginForm, MovaUserSignUpForm, MovaInterval, MovaVehicleForm, AddressFieldName, } from './src/helpers/Types';
54
54
  export { readCookie, deleteCookie } from './src/helpers/CookieUtils';
55
- export { validateField, formatVehicleTire, formatFrenchVehiclePlate, isEmpty, getApplicationShortLabel, capitalizeFirstLetter, flexLeftRow, formatPhoneNumber, getFormattedSchedule, getFormattedIntervals, findScheduleByDayOfWeek, getDayOfWeekLabel, isSafariOniOS, getApplicationsShortLabels, } from './src/helpers/Tools';
55
+ export { validateField, formatVehicleTire, formatVehiclePlate, isEmpty, getApplicationShortLabel, capitalizeFirstLetter, flexLeftRow, formatPhoneNumber, getFormattedSchedule, getFormattedIntervals, findScheduleByDayOfWeek, getDayOfWeekLabel, isSafariOniOS, getApplicationsShortLabels, } from './src/helpers/Tools';
56
56
  export { validatePhoneNumber, validateText, validateEmail } from './src/helpers/Validator';
57
57
  export { formatDateByTimezone, getLongFormattedDateTime } from './src/helpers/DateUtils';
58
58
  export { request, API_BASE_URL } from './src/helpers/ApiHelper';
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.Schedule = exports.VehicleGarage = 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.Employee = exports.Absence = exports.Subscription = exports.MovaTableBack = exports.MovaTable = exports.LinkedDocumentDialog = exports.PrintSize = exports.PLVComponent = exports.QrCodePLVContainer = exports.ActivateAccount = exports.GenderSelector = exports.ConfirmationDialog = exports.MovaVehicleTireField = exports.MovaCopyright = exports.MovaSignUp = exports.MovaLogin = exports.MovaSnackbar = exports.TestButton = exports.oldRegexPlate = exports.regexPlate = exports.VehiclePlateField = exports.QRCode = exports.MovaDialog = exports.Loader = exports.MovaDigitalPassport = exports.VehicleFullCard = exports.ScheduleFields = exports.AddressFields = exports.AccountValidation = exports.GaragePLV = exports.IbanInput = exports.DialogForgotPassword = exports.UserService = exports.GarageService = exports.AuthenticationService = exports.VehicleService = void 0;
8
- exports.SubscriptionType = exports.SubscriptionState = exports.CountryCode = exports.PrestationState = exports.PrestationType = exports.RegistrationState = exports.SubscriptionPaymentInterval = 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 = exports.MovaAppType = exports.RoleType = exports.CustomerType = exports.API_BASE_URL = exports.request = exports.getLongFormattedDateTime = exports.formatDateByTimezone = exports.validateEmail = exports.validateText = exports.validatePhoneNumber = exports.getApplicationsShortLabels = exports.isSafariOniOS = exports.getDayOfWeekLabel = exports.findScheduleByDayOfWeek = exports.getFormattedIntervals = exports.getFormattedSchedule = exports.formatPhoneNumber = exports.flexLeftRow = exports.capitalizeFirstLetter = exports.getApplicationShortLabel = exports.isEmpty = exports.formatFrenchVehiclePlate = exports.formatVehicleTire = exports.validateField = exports.deleteCookie = exports.readCookie = exports.CategoryPrestation = exports.VehicleTire = exports.Event = void 0;
8
+ exports.SubscriptionType = exports.SubscriptionState = exports.CountryCode = exports.PrestationState = exports.PrestationType = exports.RegistrationState = exports.SubscriptionPaymentInterval = 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 = exports.MovaAppType = exports.RoleType = exports.CustomerType = exports.API_BASE_URL = exports.request = exports.getLongFormattedDateTime = exports.formatDateByTimezone = exports.validateEmail = exports.validateText = exports.validatePhoneNumber = exports.getApplicationsShortLabels = exports.isSafariOniOS = exports.getDayOfWeekLabel = exports.findScheduleByDayOfWeek = exports.getFormattedIntervals = exports.getFormattedSchedule = exports.formatPhoneNumber = exports.flexLeftRow = exports.capitalizeFirstLetter = exports.getApplicationShortLabel = exports.isEmpty = exports.formatVehiclePlate = exports.formatVehicleTire = exports.validateField = exports.deleteCookie = exports.readCookie = exports.CategoryPrestation = exports.VehicleTire = exports.Event = void 0;
9
9
  exports.StyledToggleButtonGroup = exports.StyledToggleButton = exports.openDialogPrint = exports.APIMethod = void 0;
10
10
  // Export des services
11
11
  var VehicleService_1 = require("./src/services/VehicleService");
@@ -120,7 +120,7 @@ Object.defineProperty(exports, "deleteCookie", { enumerable: true, get: function
120
120
  var Tools_1 = require("./src/helpers/Tools");
121
121
  Object.defineProperty(exports, "validateField", { enumerable: true, get: function () { return Tools_1.validateField; } });
122
122
  Object.defineProperty(exports, "formatVehicleTire", { enumerable: true, get: function () { return Tools_1.formatVehicleTire; } });
123
- Object.defineProperty(exports, "formatFrenchVehiclePlate", { enumerable: true, get: function () { return Tools_1.formatFrenchVehiclePlate; } });
123
+ Object.defineProperty(exports, "formatVehiclePlate", { enumerable: true, get: function () { return Tools_1.formatVehiclePlate; } });
124
124
  Object.defineProperty(exports, "isEmpty", { enumerable: true, get: function () { return Tools_1.isEmpty; } });
125
125
  Object.defineProperty(exports, "getApplicationShortLabel", { enumerable: true, get: function () { return Tools_1.getApplicationShortLabel; } });
126
126
  Object.defineProperty(exports, "capitalizeFirstLetter", { enumerable: true, get: function () { return Tools_1.capitalizeFirstLetter; } });
@@ -229,7 +229,7 @@ var VehicleFullCard = function (_a) {
229
229
  overflow: "visible",
230
230
  mt: 4,
231
231
  pb: 1,
232
- } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.CardContent, __assign({ sx: { pt: 0, pb: 0 } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, __assign({ variant: "h6", component: "div", align: "center", sx: { mb: 1 }, color: (0, material_1.darken)(theme.palette.primary.main, 0.2) }, { children: [vehicle.brand && "".concat(vehicle.brand, " "), vehicle.model && "".concat(vehicle.model, " "), vehicle.version && "".concat(vehicle.version)] })), (0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, justifyContent: "space-between" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, sx: { mb: 1, alignItems: "center", justifyContent: "center" } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ item: true, xs: 6, sx: { position: "relative", minWidth: "234px" } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: car_plate_bg_png_1.default, alt: "Plaque d'immatriculation", style: { height: "50px", position: "relative" } }), (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "h6", color: theme.palette.text.primary, sx: { position: "absolute", top: "8px", left: "76px" } }, { children: (0, jsx_runtime_1.jsx)("b", { children: (0, Tools_1.formatFrenchVehiclePlate)(vehicle.plate) }) }))] })), onDelete && ((0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 6, style: {
232
+ } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.CardContent, __assign({ sx: { pt: 0, pb: 0 } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, __assign({ variant: "h6", component: "div", align: "center", sx: { mb: 1 }, color: (0, material_1.darken)(theme.palette.primary.main, 0.2) }, { children: [vehicle.brand && "".concat(vehicle.brand, " "), vehicle.model && "".concat(vehicle.model, " "), vehicle.version && "".concat(vehicle.version)] })), (0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, justifyContent: "space-between" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ container: true, sx: { mb: 1, alignItems: "center", justifyContent: "center" } }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Grid, __assign({ item: true, xs: 6, sx: { position: "relative", minWidth: "234px" } }, { children: [(0, jsx_runtime_1.jsx)("img", { src: car_plate_bg_png_1.default, alt: "Plaque d'immatriculation", style: { height: "50px", position: "relative" } }), (0, jsx_runtime_1.jsx)(material_1.Typography, __assign({ variant: "h6", color: theme.palette.text.primary, sx: { position: "absolute", top: "8px", left: "76px" } }, { children: (0, jsx_runtime_1.jsx)("b", { children: (0, Tools_1.formatVehiclePlate)(vehicle.plate, vehicle.foreignPlate) }) }))] })), onDelete && ((0, jsx_runtime_1.jsx)(material_1.Grid, __assign({ item: true, xs: 6, style: {
233
233
  display: "flex",
234
234
  alignItems: "center",
235
235
  justifyContent: "center",
@@ -1,6 +1,10 @@
1
1
  import { FunctionComponent } from 'react';
2
2
  interface VehiclePlateFieldProps {
3
- onValidVehiclePlate: (vehiclePlate: string) => void;
3
+ onValidVehiclePlate: (vehiclePlate: string, country: 'FR' | 'INTL') => void;
4
+ onCountryChange?: (country: 'FR' | 'INTL') => void;
5
+ country: 'FR' | 'INTL';
6
+ model?: string;
7
+ onModelChange?: (model: string) => void;
4
8
  }
5
9
  export declare const regexPlate: RegExp;
6
10
  export declare const oldRegexPlate: RegExp;
@@ -18,26 +18,34 @@ exports.oldRegexPlate = exports.regexPlate = void 0;
18
18
  var jsx_runtime_1 = require("react/jsx-runtime");
19
19
  var react_1 = require("react");
20
20
  var TextField_1 = __importDefault(require("@mui/material/TextField"));
21
- var material_1 = require("@mui/material");
22
- var SearchRounded_1 = __importDefault(require("@mui/icons-material/SearchRounded"));
23
21
  var Enums_1 = require("../../helpers/Enums");
24
22
  var Logger_1 = __importDefault(require("../../helpers/Logger"));
23
+ var material_1 = require("@mui/material");
24
+ var SearchRounded_1 = __importDefault(require("@mui/icons-material/SearchRounded"));
25
25
  // Regex pour une plaque d'immatriculation française (nouveau format SIV)
26
26
  exports.regexPlate = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
27
27
  // Regex pour une plaque d'immatriculation française (ancien format FNI)
28
28
  exports.oldRegexPlate = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
29
29
  var VehiclePlateField = function (_a) {
30
- var onValidVehiclePlate = _a.onValidVehiclePlate;
30
+ var onValidVehiclePlate = _a.onValidVehiclePlate, onCountryChange = _a.onCountryChange, country = _a.country, onModelChange = _a.onModelChange, model = _a.model;
31
31
  var _b = (0, react_1.useState)(''), value = _b[0], setValue = _b[1];
32
32
  var _c = (0, react_1.useState)(false), error = _c[0], setError = _c[1];
33
33
  var _d = (0, react_1.useState)(0), lastLength = _d[0], setLastLength = _d[1]; // Ajout d'un état pour stocker la longueur précédente
34
34
  var _e = (0, react_1.useState)(''), helperText = _e[0], setHelperText = _e[1];
35
+ var MIN_FOREIGN_PLATE_LENGTH = 6;
35
36
  // Hook de validation de la plaque
36
37
  (0, react_1.useEffect)(function () {
37
- if (!error && value !== '' && value.match(exports.regexPlate)) {
38
- onValidVehiclePlate(value);
38
+ if (country === 'FR') {
39
+ if (!error && value !== '' && value.match(exports.regexPlate)) {
40
+ onValidVehiclePlate(value, country);
41
+ }
39
42
  }
40
- }, [error, value, onValidVehiclePlate]);
43
+ else {
44
+ if (value.length >= MIN_FOREIGN_PLATE_LENGTH) {
45
+ onValidVehiclePlate(value, country);
46
+ }
47
+ }
48
+ }, [error, value, country, onValidVehiclePlate]);
41
49
  var getPlateFormat = function (plate) {
42
50
  if (plate === '') {
43
51
  // Si la saisie est vide, retournez un format par défaut (nouveau format, par exemple)
@@ -58,7 +66,16 @@ var VehiclePlateField = function (_a) {
58
66
  }
59
67
  };
60
68
  var handleChange = function (e) {
61
- var inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
69
+ var inputValue = e.target.value.toUpperCase();
70
+ if (country === 'INTL') {
71
+ setValue(inputValue);
72
+ setHelperText(inputValue.length >= MIN_FOREIGN_PLATE_LENGTH
73
+ ? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {})
74
+ : (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Veuillez saisir au moins ", MIN_FOREIGN_PLATE_LENGTH, " caract\u00E8res"] }));
75
+ setError(inputValue.length > 0 && inputValue.length < MIN_FOREIGN_PLATE_LENGTH);
76
+ return;
77
+ }
78
+ inputValue = inputValue.replace(/[^A-Z0-9]/g, '');
62
79
  // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
63
80
  switch (getPlateFormat(inputValue)) {
64
81
  case Enums_1.VehiclePlateFormat.FRENCH_NEW: {
@@ -78,10 +95,24 @@ var VehiclePlateField = function (_a) {
78
95
  }
79
96
  };
80
97
  var validatePlate = function () {
81
- if (exports.oldRegexPlate.test(value)) {
82
- onValidVehiclePlate(value);
98
+ if (country === 'FR') {
99
+ if (exports.oldRegexPlate.test(value)) {
100
+ onValidVehiclePlate(value, country);
101
+ setError(false);
102
+ }
103
+ else {
104
+ setError(true);
105
+ }
106
+ }
107
+ else {
108
+ if (value.length >= MIN_FOREIGN_PLATE_LENGTH) {
109
+ onValidVehiclePlate(value, country);
110
+ setError(false);
111
+ }
112
+ else {
113
+ setError(true);
114
+ }
83
115
  }
84
- setError(!exports.oldRegexPlate.test(value));
85
116
  };
86
117
  var handleChangeFrenchOld = function (inputValue) {
87
118
  // ON bloque la saisie à 12 caractères max (limite des anciennes plaques)
@@ -112,11 +143,38 @@ var VehiclePlateField = function (_a) {
112
143
  }
113
144
  setLastLength(inputValue.length); // Mettre à jour la longueur précédente
114
145
  };
115
- return ((0, jsx_runtime_1.jsx)(TextField_1.default, { label: "Plaque d'immatriculation", variant: "outlined", value: value, onChange: handleChange, error: error, autoFocus: true, sx: {
116
- width: '100%',
117
- '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
118
- }, helperText: lastLength > 0 ? helperText : '', InputProps: {
119
- 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, {}) })) }))),
120
- } }));
146
+ var handleCountryChange = function (event) {
147
+ var newCountry = event.target.value;
148
+ setValue('');
149
+ setHelperText('');
150
+ setError(false);
151
+ onCountryChange === null || onCountryChange === void 0 ? void 0 : onCountryChange(newCountry); // ✅ callback vers parent
152
+ };
153
+ var handleModelChange = function (event) {
154
+ var newModel = event.target.value.toUpperCase();
155
+ onModelChange === null || onModelChange === void 0 ? void 0 : onModelChange(newModel); // ✅ callback vers parent
156
+ };
157
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ display: "flex", alignItems: "start", gap: 1, width: "100%" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Select, __assign({ value: country, onChange: handleCountryChange, variant: "outlined", sx: {
158
+ minWidth: 70,
159
+ '.MuiSelect-select': {
160
+ display: 'flex',
161
+ alignItems: 'center',
162
+ height: '100%',
163
+ },
164
+ '.MuiOutlinedInput-notchedOutline': {
165
+ height: '100%',
166
+ },
167
+ p: 0,
168
+ pb: '4px'
169
+ } }, { children: [(0, jsx_runtime_1.jsx)(material_1.MenuItem, __assign({ value: "FR" }, { children: "\uD83C\uDDEB\uD83C\uDDF7" })), (0, jsx_runtime_1.jsx)(material_1.MenuItem, __assign({ value: "INTL" }, { children: "\uD83C\uDF10" }))] })), (0, jsx_runtime_1.jsx)(TextField_1.default, { label: country === "INTL" ? "Plaque étrangère / non reconnue" : "Plaque d'immatriculation (FR)", variant: "outlined", value: value, onChange: handleChange, error: error, autoFocus: true, sx: {
170
+ width: '100%',
171
+ '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
172
+ }, helperText: lastLength > 0 || country === 'INTL' ? helperText : '', InputProps: {
173
+ endAdornment: country === 'FR' && getPlateFormat(value) === Enums_1.VehiclePlateFormat.FRENCH_OLD ? ((0, jsx_runtime_1.jsx)(material_1.InputAdornment, __assign({ position: "end", sx: { mr: 1 } }, { children: (0, jsx_runtime_1.jsx)(material_1.IconButton, __assign({ edge: "end", onClick: validatePlate }, { children: (0, jsx_runtime_1.jsx)(SearchRounded_1.default, {}) })) }))) : undefined,
174
+ } })] })), (country === 'INTL') && (0, jsx_runtime_1.jsx)(material_1.Box, { children: (0, jsx_runtime_1.jsx)(TextField_1.default, { label: "Pr\u00E9cisez le mod\u00E8le ...", variant: "outlined", value: model, onChange: handleModelChange, autoFocus: true, sx: {
175
+ width: '100%',
176
+ mt: 1,
177
+ '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
178
+ } }) })] }));
121
179
  };
122
180
  exports.default = VehiclePlateField;
@@ -83,7 +83,8 @@ export declare enum RegistrationState {
83
83
  }
84
84
  export declare enum VehiclePlateFormat {
85
85
  FRENCH_NEW = "FRENCH_NEW",
86
- FRENCH_OLD = "FRENCH_OLD"
86
+ FRENCH_OLD = "FRENCH_OLD",
87
+ FOREIGN = "FOREIGN"
87
88
  }
88
89
  export declare enum SlotAlgorithm {
89
90
  /**
@@ -96,6 +96,7 @@ var VehiclePlateFormat;
96
96
  (function (VehiclePlateFormat) {
97
97
  VehiclePlateFormat["FRENCH_NEW"] = "FRENCH_NEW";
98
98
  VehiclePlateFormat["FRENCH_OLD"] = "FRENCH_OLD";
99
+ VehiclePlateFormat["FOREIGN"] = "FOREIGN";
99
100
  })(VehiclePlateFormat = exports.VehiclePlateFormat || (exports.VehiclePlateFormat = {}));
100
101
  var SlotAlgorithm;
101
102
  (function (SlotAlgorithm) {
@@ -24,7 +24,7 @@ export declare const getApplicationShortLabel: (application: PartsApplicationTyp
24
24
  export declare const flexEnd: CSSProperties;
25
25
  export declare const flexCenter: CSSProperties;
26
26
  export declare const isEmpty: (data: Object) => boolean;
27
- export declare const formatFrenchVehiclePlate: (input: string | undefined) => string;
27
+ export declare const formatVehiclePlate: (input: string | undefined, isForeignPlate: boolean) => string;
28
28
  export declare const formatVehicleTire: (vehicleTire: VehicleTire) => string;
29
29
  export declare const formatVehicleTireStr: (input: string) => string;
30
30
  /**
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
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.isInvalidPhoneNumber = exports.isInvalidMobileNumber = exports.isSafariOniOS = exports.flexStart = exports.getApplicationsShortLabels = void 0;
6
+ exports.validateField = exports.formatVehicleTireStr = exports.formatVehicleTire = exports.formatVehiclePlate = 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.isInvalidPhoneNumber = exports.isInvalidMobileNumber = exports.isSafariOniOS = exports.flexStart = exports.getApplicationsShortLabels = void 0;
7
7
  var max_1 = __importDefault(require("libphonenumber-js/max"));
8
8
  var Enums_1 = require("./Enums");
9
9
  var getApplicationsShortLabels = function (applications) {
@@ -266,22 +266,26 @@ var isEmpty = function (data) {
266
266
  return Object.keys(data).length === 0;
267
267
  };
268
268
  exports.isEmpty = isEmpty;
269
- var formatFrenchVehiclePlate = function (input) {
269
+ var formatVehiclePlate = function (input, isForeignPlate) {
270
270
  if (input) {
271
- // On commence par détecter s'il s'agit d'un ancien ou nouveau format
272
271
  var plateFormat = null;
273
- if (/^[A-Za-z]/.test(input)) {
274
- // Commence par une lettre => nouveau format
272
+ if (isForeignPlate) {
273
+ // Plaque étrangère
274
+ plateFormat = Enums_1.VehiclePlateFormat.FOREIGN;
275
+ }
276
+ else if (/^[A-Za-z]/.test(input)) {
277
+ // Commence par une lettre => nouveau format FR
275
278
  plateFormat = Enums_1.VehiclePlateFormat.FRENCH_NEW;
276
279
  }
277
280
  else if (/^\d/.test(input)) {
278
- // Commence par un chiffre => ancien format
281
+ // Commence par un chiffre => ancien format FR
279
282
  plateFormat = Enums_1.VehiclePlateFormat.FRENCH_OLD;
280
283
  }
281
- // Supprimer tous les caractères non alphanumériques
282
- var cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
284
+ var cleanedInput = input;
283
285
  switch (plateFormat) {
284
286
  case Enums_1.VehiclePlateFormat.FRENCH_NEW: {
287
+ // Supprimer tous les caractères non alphanumériques
288
+ cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
285
289
  // Ajouter des tirets aux positions appropriées
286
290
  if (cleanedInput.length >= 2) {
287
291
  cleanedInput = "".concat(cleanedInput.slice(0, 2), "-").concat(cleanedInput.slice(2));
@@ -292,15 +296,20 @@ var formatFrenchVehiclePlate = function (input) {
292
296
  break;
293
297
  }
294
298
  case Enums_1.VehiclePlateFormat.FRENCH_OLD: {
299
+ // Supprimer tous les caractères non alphanumériques
300
+ cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
295
301
  // Rien de particulier, pas de tiret sur les anciennes plaques
296
302
  break;
297
303
  }
304
+ case Enums_1.VehiclePlateFormat.FOREIGN: {
305
+ // On retourne la plaque telle qu'enregistrée par l'utilisateur, ras
306
+ }
298
307
  }
299
308
  return cleanedInput;
300
309
  }
301
310
  return "";
302
311
  };
303
- exports.formatFrenchVehiclePlate = formatFrenchVehiclePlate;
312
+ exports.formatVehiclePlate = formatVehiclePlate;
304
313
  var formatVehicleTire = function (vehicleTire) {
305
314
  if (vehicleTire) {
306
315
  var concatened = "".concat(vehicleTire.width).concat(vehicleTire.height).concat(vehicleTire.diameter).concat(vehicleTire.speedIndex);
@@ -22,6 +22,7 @@ export default class Vehicle {
22
22
  tireSize: VehicleTire;
23
23
  lastInspectionDate: Date;
24
24
  lastMaintenanceDate: Date;
25
- constructor(id: number, ownerId: number, averageMileagePerYear: number, plate: string, brand: string, model: string, version: string, vin: string, currentMileage: number, digitalPassportIndex: DigitalPassportIndex, firstRegistrationDate: Date, ktype: string, tireDiameter: string, tireHeight: string, tireSpeedIndex: string, tireWidth: string, documents: Document[], tireSize: VehicleTire, lastInspectionDate: Date, lastMaintenanceDate: Date);
25
+ foreignPlate: boolean;
26
+ constructor(id: number, ownerId: number, averageMileagePerYear: number, plate: string, brand: string, model: string, version: string, vin: string, currentMileage: number, digitalPassportIndex: DigitalPassportIndex, firstRegistrationDate: Date, ktype: string, tireDiameter: string, tireHeight: string, tireSpeedIndex: string, tireWidth: string, documents: Document[], tireSize: VehicleTire, lastInspectionDate: Date, lastMaintenanceDate: Date, foreignPlate: boolean);
26
27
  getVehicleLabel(): string;
27
28
  }
@@ -11,7 +11,7 @@ Carburant : Essence
11
11
  Cylindrée : 1984 cm3
12
12
  Puissance : 140 KW (190 HP) */
13
13
  var Vehicle = /** @class */ (function () {
14
- function Vehicle(id, ownerId, averageMileagePerYear, plate, brand, model, version, vin, currentMileage, digitalPassportIndex, firstRegistrationDate, ktype, tireDiameter, tireHeight, tireSpeedIndex, tireWidth, documents, tireSize, lastInspectionDate, lastMaintenanceDate) {
14
+ function Vehicle(id, ownerId, averageMileagePerYear, plate, brand, model, version, vin, currentMileage, digitalPassportIndex, firstRegistrationDate, ktype, tireDiameter, tireHeight, tireSpeedIndex, tireWidth, documents, tireSize, lastInspectionDate, lastMaintenanceDate, foreignPlate) {
15
15
  this.id = id;
16
16
  this.ownerId = ownerId;
17
17
  this.averageMileagePerYear = averageMileagePerYear;
@@ -32,6 +32,7 @@ var Vehicle = /** @class */ (function () {
32
32
  this.tireSize = tireSize;
33
33
  this.lastInspectionDate = lastInspectionDate;
34
34
  this.lastMaintenanceDate = lastMaintenanceDate;
35
+ this.foreignPlate = foreignPlate;
35
36
  }
36
37
  Vehicle.prototype.getVehicleLabel = function () {
37
38
  return "".concat(this.brand, " ").concat(this.model, " ").concat(this.version);
@@ -16,6 +16,8 @@ export type AddCustomerVehicleParams = {
16
16
  tireSpeedIndex?: string;
17
17
  lastMaintenanceDate?: string;
18
18
  lastInspectionDate?: string;
19
+ isForeignPlate?: boolean;
20
+ model?: string;
19
21
  };
20
22
  export type DeleteCustomerVehicleParams = {
21
23
  /** L'identifiant unique du garage */
package/index.ts CHANGED
@@ -72,7 +72,7 @@ export { readCookie, deleteCookie } from './src/helpers/CookieUtils';
72
72
  export {
73
73
  validateField,
74
74
  formatVehicleTire,
75
- formatFrenchVehiclePlate,
75
+ formatVehiclePlate,
76
76
  isEmpty,
77
77
  getApplicationShortLabel,
78
78
  capitalizeFirstLetter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movalib/movalib-commons",
3
- "version": "1.62.4",
3
+ "version": "1.63.0",
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",
@@ -38,7 +38,7 @@ import {
38
38
  } from "../../helpers/Enums";
39
39
  import Logger from "../../helpers/Logger";
40
40
  import {
41
- formatFrenchVehiclePlate,
41
+ formatVehiclePlate,
42
42
  formatVehicleTire,
43
43
  } from "../../helpers/Tools";
44
44
  import { MovaFormField, MovaVehicleForm } from "../../helpers/Types";
@@ -438,7 +438,7 @@ const VehicleFullCard: FC<VehicleFullCardProps> = ({
438
438
  color={theme.palette.text.primary}
439
439
  sx={{ position: "absolute", top: "8px", left: "76px" }}
440
440
  >
441
- <b>{formatFrenchVehiclePlate(vehicle.plate)}</b>
441
+ <b>{formatVehiclePlate(vehicle.plate, vehicle.foreignPlate)}</b>
442
442
  </Typography>
443
443
  </Grid>
444
444
  {onDelete && (
@@ -1,12 +1,16 @@
1
1
  import React, { FunctionComponent, ReactNode, useEffect, useState } from 'react';
2
2
  import TextField from '@mui/material/TextField';
3
- import { IconButton, InputAdornment } from '@mui/material';
4
- import SearchIcon from '@mui/icons-material/SearchRounded';
5
3
  import { VehiclePlateFormat } from '../../helpers/Enums';
6
4
  import Logger from '../../helpers/Logger';
5
+ import { Box, IconButton, InputAdornment, MenuItem, Select, SelectChangeEvent } from '@mui/material';
6
+ import SearchIcon from '@mui/icons-material/SearchRounded';
7
7
 
8
8
  interface VehiclePlateFieldProps {
9
- onValidVehiclePlate: (vehiclePlate: string) => void;
9
+ onValidVehiclePlate: (vehiclePlate: string, country: 'FR' | 'INTL') => void;
10
+ onCountryChange?: (country: 'FR' | 'INTL') => void;
11
+ country: 'FR' | 'INTL';
12
+ model?: string;
13
+ onModelChange?: (model :string) => void;
10
14
  }
11
15
 
12
16
  // Regex pour une plaque d'immatriculation française (nouveau format SIV)
@@ -15,20 +19,26 @@ export const regexPlate = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
15
19
  export const oldRegexPlate = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
16
20
 
17
21
 
18
- const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidVehiclePlate }) => {
22
+ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidVehiclePlate, onCountryChange, country, onModelChange, model }) => {
19
23
 
20
24
  const [value, setValue] = useState<string>('');
21
25
  const [error, setError] = useState<boolean>(false);
22
26
  const [lastLength, setLastLength] = useState<number>(0); // Ajout d'un état pour stocker la longueur précédente
23
27
  const [helperText, setHelperText] = useState<ReactNode>('');
28
+ const MIN_FOREIGN_PLATE_LENGTH = 6;
24
29
 
25
30
  // Hook de validation de la plaque
26
31
  useEffect(() => {
27
- if (!error && value !== '' && value.match(regexPlate)) {
28
- onValidVehiclePlate(value);
32
+ if (country === 'FR') {
33
+ if (!error && value !== '' && value.match(regexPlate)) {
34
+ onValidVehiclePlate(value, country);
35
+ }
36
+ } else {
37
+ if (value.length >= MIN_FOREIGN_PLATE_LENGTH) {
38
+ onValidVehiclePlate(value, country);
39
+ }
29
40
  }
30
-
31
- }, [error, value, onValidVehiclePlate]);
41
+ }, [error, value, country, onValidVehiclePlate]);
32
42
 
33
43
  const getPlateFormat = (plate: string): VehiclePlateFormat | undefined => {
34
44
  if (plate === '') {
@@ -49,9 +59,23 @@ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidV
49
59
  }
50
60
  }
51
61
 
62
+
52
63
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
53
64
 
54
- let inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
65
+ let inputValue = e.target.value.toUpperCase();
66
+
67
+ if (country === 'INTL') {
68
+ setValue(inputValue);
69
+ setHelperText(
70
+ inputValue.length >= MIN_FOREIGN_PLATE_LENGTH
71
+ ? <></>
72
+ : <>Veuillez saisir au moins {MIN_FOREIGN_PLATE_LENGTH} caractères</>
73
+ );
74
+ setError(inputValue.length > 0 && inputValue.length < MIN_FOREIGN_PLATE_LENGTH);
75
+ return;
76
+ }
77
+
78
+ inputValue = inputValue.replace(/[^A-Z0-9]/g, '');
55
79
 
56
80
  // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
57
81
  switch(getPlateFormat(inputValue)){
@@ -83,12 +107,21 @@ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidV
83
107
  };
84
108
 
85
109
  const validatePlate = () => {
86
-
87
- if(oldRegexPlate.test(value)){
88
- onValidVehiclePlate(value);
110
+ if (country === 'FR') {
111
+ if (oldRegexPlate.test(value)) {
112
+ onValidVehiclePlate(value, country);
113
+ setError(false);
114
+ } else {
115
+ setError(true);
116
+ }
117
+ } else {
118
+ if (value.length >= MIN_FOREIGN_PLATE_LENGTH) {
119
+ onValidVehiclePlate(value, country);
120
+ setError(false);
121
+ } else {
122
+ setError(true);
123
+ }
89
124
  }
90
-
91
- setError(!oldRegexPlate.test(value));
92
125
  }
93
126
 
94
127
  const handleChangeFrenchOld = (inputValue: string) => {
@@ -130,9 +163,46 @@ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidV
130
163
  setLastLength(inputValue.length); // Mettre à jour la longueur précédente
131
164
  }
132
165
 
166
+ const handleCountryChange = (event: SelectChangeEvent<'FR' | 'INTL'>) => {
167
+ const newCountry = event.target.value as 'FR' | 'INTL';
168
+ setValue('');
169
+ setHelperText('');
170
+ setError(false);
171
+
172
+ onCountryChange?.(newCountry); // ✅ callback vers parent
173
+ };
174
+
175
+ const handleModelChange = (event: React.ChangeEvent<HTMLInputElement>) => {
176
+ const newModel = event.target.value.toUpperCase() as string;
177
+ onModelChange?.(newModel); // ✅ callback vers parent
178
+ };
179
+
133
180
  return (
181
+ <>
182
+ <Box display="flex" alignItems="start" gap={1} width="100%">
183
+ <Select
184
+ value={country}
185
+ onChange={handleCountryChange}
186
+ variant="outlined"
187
+ sx={{
188
+ minWidth: 70,
189
+ '.MuiSelect-select': {
190
+ display: 'flex',
191
+ alignItems: 'center',
192
+ height: '100%',
193
+ },
194
+ '.MuiOutlinedInput-notchedOutline': {
195
+ height: '100%',
196
+ },
197
+ p: 0,
198
+ pb: '4px'
199
+ }}
200
+ >
201
+ <MenuItem value="FR">🇫🇷</MenuItem>
202
+ <MenuItem value="INTL">🌐</MenuItem>
203
+ </Select>
134
204
  <TextField
135
- label="Plaque d'immatriculation"
205
+ label={country === "INTL" ? "Plaque étrangère / non reconnue" : "Plaque d'immatriculation (FR)"}
136
206
  variant="outlined"
137
207
  value={value}
138
208
  onChange={handleChange}
@@ -142,23 +212,37 @@ const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidV
142
212
  width: '100%',
143
213
  '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
144
214
  }}
145
- helperText={lastLength > 0 ? helperText : ''}
215
+ helperText={lastLength > 0 || country === 'INTL' ? helperText : ''}
146
216
  InputProps={{
147
- endAdornment: (
217
+ endAdornment:
148
218
 
149
- <InputAdornment position="end" sx={{ mr: 1, display: getPlateFormat(value) === VehiclePlateFormat.FRENCH_OLD ? 'inherit' : 'none' }} >
150
- <IconButton
151
- edge="end"
152
- onClick={validatePlate}
153
- >
154
- <SearchIcon />
155
- </IconButton>
156
- </InputAdornment>
219
+ country === 'FR' && getPlateFormat(value) === VehiclePlateFormat.FRENCH_OLD ? (
220
+ <InputAdornment position="end" sx={{ mr: 1 }}>
221
+ <IconButton edge="end" onClick={validatePlate}>
222
+ <SearchIcon />
223
+ </IconButton>
224
+ </InputAdornment>
225
+ ) : undefined,
157
226
 
158
- ),
159
227
  }}
160
- />
228
+ />
229
+ </Box>
230
+ {(country === 'INTL') && <Box>
231
+ <TextField
232
+ label="Précisez le modèle ..."
233
+ variant="outlined"
234
+ value={model}
235
+ onChange={handleModelChange}
236
+ autoFocus
237
+ sx={{
238
+ width: '100%',
239
+ mt: 1,
240
+ '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
241
+ }}
242
+ />
243
+ </Box>}
244
+ </>
161
245
  );
162
246
  };
163
247
 
164
- export default VehiclePlateField;
248
+ export default VehiclePlateField;
@@ -92,6 +92,7 @@ export enum RegistrationState {
92
92
  export enum VehiclePlateFormat {
93
93
  FRENCH_NEW = "FRENCH_NEW",
94
94
  FRENCH_OLD = "FRENCH_OLD",
95
+ FOREIGN = "FOREIGN"
95
96
  }
96
97
 
97
98
  export enum SlotAlgorithm {
@@ -294,24 +294,28 @@ export const isEmpty = (data: Object): boolean => {
294
294
  return Object.keys(data).length === 0;
295
295
  };
296
296
 
297
- export const formatFrenchVehiclePlate = (input: string | undefined): string => {
297
+ export const formatVehiclePlate = (input: string | undefined, isForeignPlate: boolean): string => {
298
298
  if (input) {
299
- // On commence par détecter s'il s'agit d'un ancien ou nouveau format
299
+
300
300
  let plateFormat: VehiclePlateFormat | null = null;
301
301
 
302
- if (/^[A-Za-z]/.test(input)) {
303
- // Commence par une lettre => nouveau format
302
+ if(isForeignPlate) {
303
+ // Plaque étrangère
304
+ plateFormat = VehiclePlateFormat.FOREIGN;
305
+ } else if (/^[A-Za-z]/.test(input)) {
306
+ // Commence par une lettre => nouveau format FR
304
307
  plateFormat = VehiclePlateFormat.FRENCH_NEW;
305
308
  } else if (/^\d/.test(input)) {
306
- // Commence par un chiffre => ancien format
309
+ // Commence par un chiffre => ancien format FR
307
310
  plateFormat = VehiclePlateFormat.FRENCH_OLD;
308
311
  }
309
312
 
310
- // Supprimer tous les caractères non alphanumériques
311
- let cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
313
+ let cleanedInput = input;
312
314
 
313
315
  switch (plateFormat) {
314
316
  case VehiclePlateFormat.FRENCH_NEW: {
317
+ // Supprimer tous les caractères non alphanumériques
318
+ cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
315
319
  // Ajouter des tirets aux positions appropriées
316
320
  if (cleanedInput.length >= 2) {
317
321
  cleanedInput = `${cleanedInput.slice(0, 2)}-${cleanedInput.slice(2)}`;
@@ -326,11 +330,17 @@ export const formatFrenchVehiclePlate = (input: string | undefined): string => {
326
330
  }
327
331
 
328
332
  case VehiclePlateFormat.FRENCH_OLD: {
333
+ // Supprimer tous les caractères non alphanumériques
334
+ cleanedInput = input.replace(/[^A-Z0-9]/gi, "").toUpperCase();
329
335
  // Rien de particulier, pas de tiret sur les anciennes plaques
330
336
  break;
331
337
  }
332
- }
333
338
 
339
+ case VehiclePlateFormat.FOREIGN: {
340
+ // On retourne la plaque telle qu'enregistrée par l'utilisateur, ras
341
+
342
+ }
343
+ }
334
344
  return cleanedInput;
335
345
  }
336
346
 
@@ -36,6 +36,7 @@ export default class Vehicle {
36
36
  tireSize: VehicleTire;
37
37
  lastInspectionDate: Date;
38
38
  lastMaintenanceDate: Date;
39
+ foreignPlate: boolean;
39
40
 
40
41
  constructor(
41
42
  id: number,
@@ -57,7 +58,8 @@ export default class Vehicle {
57
58
  documents: Document[],
58
59
  tireSize: VehicleTire,
59
60
  lastInspectionDate: Date,
60
- lastMaintenanceDate: Date
61
+ lastMaintenanceDate: Date,
62
+ foreignPlate: boolean
61
63
  ) {
62
64
  this.id = id;
63
65
  this.ownerId = ownerId;
@@ -79,6 +81,7 @@ export default class Vehicle {
79
81
  this.tireSize = tireSize;
80
82
  this.lastInspectionDate = lastInspectionDate;
81
83
  this.lastMaintenanceDate = lastMaintenanceDate;
84
+ this.foreignPlate = foreignPlate
82
85
  }
83
86
 
84
87
  getVehicleLabel() {
@@ -17,6 +17,8 @@ export type AddCustomerVehicleParams = {
17
17
  tireSpeedIndex?: string;
18
18
  lastMaintenanceDate?: string;
19
19
  lastInspectionDate?: string;
20
+ isForeignPlate?: boolean;
21
+ model?: string
20
22
  }
21
23
 
22
24
 
@@ -1,8 +0,0 @@
1
- import { FunctionComponent } from 'react';
2
- interface VehiclePlateFieldProps {
3
- onValidVehiclePlate: (vehiclePlate: string) => void;
4
- }
5
- export declare const regexPlate: RegExp;
6
- export declare const oldRegexPlate: RegExp;
7
- declare const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps>;
8
- export default VehiclePlateField;
@@ -1,122 +0,0 @@
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
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.oldRegexPlate = exports.regexPlate = void 0;
18
- var jsx_runtime_1 = require("react/jsx-runtime");
19
- var react_1 = require("react");
20
- var TextField_1 = __importDefault(require("@mui/material/TextField"));
21
- var Enums_1 = require("./helpers/Enums");
22
- var Logger_1 = __importDefault(require("./helpers/Logger"));
23
- var material_1 = require("@mui/material");
24
- var SearchRounded_1 = __importDefault(require("@mui/icons-material/SearchRounded"));
25
- // Regex pour une plaque d'immatriculation française (nouveau format SIV)
26
- exports.regexPlate = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
27
- // Regex pour une plaque d'immatriculation française (ancien format FNI)
28
- exports.oldRegexPlate = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
29
- var VehiclePlateField = function (_a) {
30
- var onValidVehiclePlate = _a.onValidVehiclePlate;
31
- var _b = (0, react_1.useState)(''), value = _b[0], setValue = _b[1];
32
- var _c = (0, react_1.useState)(false), error = _c[0], setError = _c[1];
33
- var _d = (0, react_1.useState)(0), lastLength = _d[0], setLastLength = _d[1]; // Ajout d'un état pour stocker la longueur précédente
34
- var _e = (0, react_1.useState)(''), helperText = _e[0], setHelperText = _e[1];
35
- // Hook de validation de la plaque
36
- (0, react_1.useEffect)(function () {
37
- if (!error && value !== '' && value.match(exports.regexPlate)) {
38
- onValidVehiclePlate(value);
39
- }
40
- }, [error, value, onValidVehiclePlate]);
41
- var getPlateFormat = function (plate) {
42
- if (plate === '') {
43
- // Si la saisie est vide, retournez un format par défaut (nouveau format, par exemple)
44
- return undefined;
45
- }
46
- if (/^[A-Za-z]/.test(plate)) {
47
- // Commence par une lettre => nouveau format
48
- return Enums_1.VehiclePlateFormat.FRENCH_NEW;
49
- }
50
- else if (/^\d/.test(plate)) {
51
- // Commence par un chiffre => ancien format
52
- return Enums_1.VehiclePlateFormat.FRENCH_OLD;
53
- }
54
- else {
55
- Logger_1.default.error("Format de plaque inconnu");
56
- // On retourne le nouveau format par défaut
57
- return Enums_1.VehiclePlateFormat.FRENCH_NEW;
58
- }
59
- };
60
- var handleChange = function (e) {
61
- var inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
62
- // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
63
- switch (getPlateFormat(inputValue)) {
64
- case Enums_1.VehiclePlateFormat.FRENCH_NEW: {
65
- 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" })] }));
66
- handleChangeFrenchNew(inputValue);
67
- break;
68
- }
69
- case Enums_1.VehiclePlateFormat.FRENCH_OLD: {
70
- 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" }), (0, jsx_runtime_1.jsx)("br", {}), "Pour lancer la recherche, cliquez sur ", (0, jsx_runtime_1.jsx)(SearchRounded_1.default, {})] }));
71
- handleChangeFrenchOld(inputValue);
72
- break;
73
- }
74
- case undefined: {
75
- setHelperText('');
76
- setValue('');
77
- }
78
- }
79
- };
80
- var validatePlate = function () {
81
- if (exports.oldRegexPlate.test(value)) {
82
- onValidVehiclePlate(value);
83
- }
84
- setError(!exports.oldRegexPlate.test(value));
85
- };
86
- var handleChangeFrenchOld = function (inputValue) {
87
- // ON bloque la saisie à 12 caractères max (limite des anciennes plaques)
88
- if (!(inputValue.length > 12)) {
89
- setValue(inputValue);
90
- }
91
- setLastLength(inputValue.length); // Mettre à jour la longueur précédente
92
- };
93
- var handleChangeFrenchNew = function (inputValue) {
94
- // Vérifier si l'utilisateur est en train de supprimer un caractère
95
- var isDeleting = inputValue.length < lastLength;
96
- // Supprimer les tirets pour avoir une chaîne propre
97
- var cleanInput = inputValue.replace(/-/g, '');
98
- // Ajouter des tirets aux positions appropriées
99
- if (cleanInput.length > 1 && !(cleanInput.length == 2 && isDeleting)) {
100
- inputValue = "".concat(cleanInput.slice(0, 2), "-").concat(cleanInput.slice(2));
101
- }
102
- if (cleanInput.length > 4 && !(cleanInput.length == 5 && isDeleting)) {
103
- inputValue = "".concat(cleanInput.slice(0, 2), "-").concat(cleanInput.slice(2, 5), "-").concat(cleanInput.slice(5, 7));
104
- }
105
- setValue(inputValue);
106
- // On teste la plaque une fois la saisie terminée
107
- if (inputValue.length == 9) {
108
- setError(!exports.regexPlate.test(inputValue));
109
- }
110
- else {
111
- setError(false);
112
- }
113
- setLastLength(inputValue.length); // Mettre à jour la longueur précédente
114
- };
115
- return ((0, jsx_runtime_1.jsx)(TextField_1.default, { label: "Plaque d'immatriculation", variant: "outlined", value: value, onChange: handleChange, error: error, autoFocus: true, sx: {
116
- width: '100%',
117
- '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
118
- }, helperText: lastLength > 0 ? helperText : '', InputProps: {
119
- 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, {}) })) }))),
120
- } }));
121
- };
122
- exports.default = VehiclePlateField;
@@ -1,165 +0,0 @@
1
- import React, { FunctionComponent, ReactNode, useEffect, useState } from 'react';
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';
7
-
8
- interface VehiclePlateFieldProps {
9
- onValidVehiclePlate: (vehiclePlate: string) => void;
10
- }
11
-
12
- // Regex pour une plaque d'immatriculation française (nouveau format SIV)
13
- export const regexPlate = /^[A-Z]{2}-\d{3}-[A-Z]{2}$/;
14
- // Regex pour une plaque d'immatriculation française (ancien format FNI)
15
- export const oldRegexPlate = /^\d{1,4}[ -]?[A-Z]{1,4}[ -]?\d{1,4}$/;
16
-
17
-
18
- const VehiclePlateField: FunctionComponent<VehiclePlateFieldProps> = ({ onValidVehiclePlate }) => {
19
-
20
- const [value, setValue] = useState<string>('');
21
- const [error, setError] = useState<boolean>(false);
22
- const [lastLength, setLastLength] = useState<number>(0); // Ajout d'un état pour stocker la longueur précédente
23
- const [helperText, setHelperText] = useState<ReactNode>('');
24
-
25
- // Hook de validation de la plaque
26
- useEffect(() => {
27
- if (!error && value !== '' && value.match(regexPlate)) {
28
- onValidVehiclePlate(value);
29
- }
30
-
31
- }, [error, value, onValidVehiclePlate]);
32
-
33
- const getPlateFormat = (plate: string): VehiclePlateFormat | undefined => {
34
- if (plate === '') {
35
- // Si la saisie est vide, retournez un format par défaut (nouveau format, par exemple)
36
- return undefined;
37
- }
38
-
39
- if (/^[A-Za-z]/.test(plate)) {
40
- // Commence par une lettre => nouveau format
41
- return VehiclePlateFormat.FRENCH_NEW;
42
- } else if (/^\d/.test(plate)) {
43
- // Commence par un chiffre => ancien format
44
- return VehiclePlateFormat.FRENCH_OLD;
45
- } else {
46
- Logger.error("Format de plaque inconnu");
47
- // On retourne le nouveau format par défaut
48
- return VehiclePlateFormat.FRENCH_NEW;
49
- }
50
- }
51
-
52
-
53
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
54
-
55
- let inputValue = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, ''); // Convertir en majuscules et supprimer les caractères non valides
56
-
57
- // Si la saisie commence par une lettre, on contrôle l'ancien format, sinon le nouveau
58
- switch(getPlateFormat(inputValue)){
59
-
60
- case VehiclePlateFormat.FRENCH_NEW :{
61
- setHelperText(<>Format détecté : <b>AA-111-AA</b></>);
62
- handleChangeFrenchNew(inputValue);
63
- break;
64
- }
65
-
66
- case VehiclePlateFormat.FRENCH_OLD: {
67
- setHelperText(
68
- <>
69
- Format détecté (ancien) : <b>1111 AAAA 1111</b>
70
- <br />
71
- Pour lancer la recherche, cliquez sur <SearchIcon />
72
- </>
73
- );
74
- handleChangeFrenchOld(inputValue);
75
- break;
76
- }
77
-
78
- case undefined: {
79
- setHelperText('');
80
- setValue('');
81
- }
82
- }
83
-
84
- };
85
-
86
- const validatePlate = () => {
87
-
88
- if(oldRegexPlate.test(value)){
89
- onValidVehiclePlate(value);
90
- }
91
-
92
- setError(!oldRegexPlate.test(value));
93
- }
94
-
95
- const handleChangeFrenchOld = (inputValue: string) => {
96
-
97
- // ON bloque la saisie à 12 caractères max (limite des anciennes plaques)
98
- if(!(inputValue.length > 12)){
99
- setValue(inputValue);
100
- }
101
-
102
- setLastLength(inputValue.length); // Mettre à jour la longueur précédente
103
- }
104
-
105
- const handleChangeFrenchNew = (inputValue: string) => {
106
-
107
- // Vérifier si l'utilisateur est en train de supprimer un caractère
108
- const isDeleting = inputValue.length < lastLength;
109
-
110
- // Supprimer les tirets pour avoir une chaîne propre
111
- const cleanInput = inputValue.replace(/-/g, '');
112
-
113
- // Ajouter des tirets aux positions appropriées
114
- if (cleanInput.length > 1 && !(cleanInput.length == 2 && isDeleting)) {
115
- inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2)}`;
116
- }
117
-
118
- if (cleanInput.length > 4 && !(cleanInput.length == 5 && isDeleting)) {
119
- inputValue = `${cleanInput.slice(0, 2)}-${cleanInput.slice(2, 5)}-${cleanInput.slice(5, 7)}`;
120
- }
121
-
122
- setValue(inputValue);
123
-
124
- // On teste la plaque une fois la saisie terminée
125
- if(inputValue.length == 9){
126
- setError(!regexPlate.test(inputValue));
127
- } else {
128
- setError(false);
129
- }
130
-
131
- setLastLength(inputValue.length); // Mettre à jour la longueur précédente
132
- }
133
-
134
- return (
135
- <TextField
136
- label="Plaque d'immatriculation"
137
- variant="outlined"
138
- value={value}
139
- onChange={handleChange}
140
- error={error}
141
- autoFocus
142
- sx={{
143
- width: '100%',
144
- '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
145
- }}
146
- helperText={lastLength > 0 ? helperText : ''}
147
- InputProps={{
148
- endAdornment: (
149
-
150
- <InputAdornment position="end" sx={{ mr: 1, display: getPlateFormat(value) === VehiclePlateFormat.FRENCH_OLD ? 'inherit' : 'none' }} >
151
- <IconButton
152
- edge="end"
153
- onClick={validatePlate}
154
- >
155
- <SearchIcon />
156
- </IconButton>
157
- </InputAdornment>
158
-
159
- ),
160
- }}
161
- />
162
- );
163
- };
164
-
165
- export default VehiclePlateField;