@movalib/movalib-commons 1.62.4 → 1.63.3
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 +15 -4
- package/dist/devIndex.js +10 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/src/components/vehicle/VehicleFullCard.js +1 -1
- package/dist/src/components/vehicle/VehiclePlateField.d.ts +5 -1
- package/dist/src/components/vehicle/VehiclePlateField.js +74 -16
- package/dist/src/helpers/Enums.d.ts +2 -1
- package/dist/src/helpers/Enums.js +1 -0
- package/dist/src/helpers/Tools.d.ts +1 -1
- package/dist/src/helpers/Tools.js +18 -9
- package/dist/src/models/Customer.d.ts +2 -1
- package/dist/src/models/Customer.js +3 -1
- package/dist/src/models/Vehicle.d.ts +2 -1
- package/dist/src/models/Vehicle.js +2 -1
- package/dist/src/services/GarageService.types.d.ts +2 -0
- package/index.ts +1 -1
- package/package.json +1 -1
- package/src/components/vehicle/VehicleFullCard.tsx +2 -2
- package/src/components/vehicle/VehiclePlateField.tsx +112 -28
- package/src/helpers/Enums.ts +1 -0
- package/src/helpers/Tools.ts +18 -8
- package/src/models/Customer.ts +4 -1
- package/src/models/Vehicle.ts +4 -1
- package/src/services/GarageService.types.ts +2 -0
- package/dist/src/VehiclePlateField.d.ts +0 -8
- package/dist/src/VehiclePlateField.js +0 -122
- package/src/VehiclePlateField.tsx +0 -165
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
|
|
123
|
-
<VehiclePlateField
|
|
124
|
-
|
|
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({
|
|
134
|
-
|
|
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,
|
|
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.
|
|
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, "
|
|
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.
|
|
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 (
|
|
38
|
-
|
|
38
|
+
if (country === 'FR') {
|
|
39
|
+
if (!error && value !== '' && value.match(exports.regexPlate)) {
|
|
40
|
+
onValidVehiclePlate(value, country);
|
|
41
|
+
}
|
|
39
42
|
}
|
|
40
|
-
|
|
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()
|
|
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 (
|
|
82
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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;
|
|
@@ -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
|
|
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.
|
|
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
|
|
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 (
|
|
274
|
-
//
|
|
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
|
-
|
|
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.
|
|
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);
|
|
@@ -27,8 +27,9 @@ export default class Customer extends User {
|
|
|
27
27
|
notes: string;
|
|
28
28
|
billingAddress?: Address;
|
|
29
29
|
siren?: string;
|
|
30
|
+
vatId?: string;
|
|
30
31
|
constructor(id: string, roles: Role[] | undefined, firstname: string | undefined, lastname: string | undefined, avatar: string | undefined, addresses: Address[] | undefined, vehicles: Vehicle[], email: string | undefined, turnover: {
|
|
31
32
|
key: string;
|
|
32
33
|
value: number;
|
|
33
|
-
}[], type: CustomerType, companyName: string, companyPhoneNumber: string, billingAddress: Address | undefined, notes: string, siren?: string);
|
|
34
|
+
}[], type: CustomerType, companyName: string, companyPhoneNumber: string, billingAddress: Address | undefined, notes: string, siren?: string, vatId?: string);
|
|
34
35
|
}
|
|
@@ -21,7 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
var User_1 = __importDefault(require("./User"));
|
|
22
22
|
var Customer = /** @class */ (function (_super) {
|
|
23
23
|
__extends(Customer, _super);
|
|
24
|
-
function Customer(id, roles, firstname, lastname, avatar, addresses, vehicles, email, turnover, type, companyName, companyPhoneNumber, billingAddress, notes, siren) {
|
|
24
|
+
function Customer(id, roles, firstname, lastname, avatar, addresses, vehicles, email, turnover, type, companyName, companyPhoneNumber, billingAddress, notes, siren, vatId) {
|
|
25
25
|
if (roles === void 0) { roles = []; }
|
|
26
26
|
if (firstname === void 0) { firstname = ""; }
|
|
27
27
|
if (lastname === void 0) { lastname = ""; }
|
|
@@ -30,6 +30,7 @@ var Customer = /** @class */ (function (_super) {
|
|
|
30
30
|
if (email === void 0) { email = ""; }
|
|
31
31
|
if (billingAddress === void 0) { billingAddress = undefined; }
|
|
32
32
|
if (siren === void 0) { siren = ""; }
|
|
33
|
+
if (vatId === void 0) { vatId = ""; }
|
|
33
34
|
var _this = _super.call(this, id, roles, firstname, lastname, avatar, email) || this;
|
|
34
35
|
_this.vehicles = vehicles;
|
|
35
36
|
_this.turnover = turnover;
|
|
@@ -39,6 +40,7 @@ var Customer = /** @class */ (function (_super) {
|
|
|
39
40
|
_this.notes = notes;
|
|
40
41
|
_this.billingAddress = billingAddress;
|
|
41
42
|
_this.siren = siren;
|
|
43
|
+
_this.vatId = vatId;
|
|
42
44
|
return _this;
|
|
43
45
|
}
|
|
44
46
|
return Customer;
|
|
@@ -22,6 +22,7 @@ export default class Vehicle {
|
|
|
22
22
|
tireSize: VehicleTire;
|
|
23
23
|
lastInspectionDate: Date;
|
|
24
24
|
lastMaintenanceDate: Date;
|
|
25
|
-
|
|
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
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from "../../helpers/Enums";
|
|
39
39
|
import Logger from "../../helpers/Logger";
|
|
40
40
|
import {
|
|
41
|
-
|
|
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>{
|
|
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 (
|
|
28
|
-
|
|
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()
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
150
|
-
<
|
|
151
|
-
edge="end"
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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;
|
package/src/helpers/Enums.ts
CHANGED
package/src/helpers/Tools.ts
CHANGED
|
@@ -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
|
|
297
|
+
export const formatVehiclePlate = (input: string | undefined, isForeignPlate: boolean): string => {
|
|
298
298
|
if (input) {
|
|
299
|
-
|
|
299
|
+
|
|
300
300
|
let plateFormat: VehiclePlateFormat | null = null;
|
|
301
301
|
|
|
302
|
-
if
|
|
303
|
-
//
|
|
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
|
-
|
|
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
|
|
package/src/models/Customer.ts
CHANGED
|
@@ -29,6 +29,7 @@ export default class Customer extends User {
|
|
|
29
29
|
notes: string;
|
|
30
30
|
billingAddress?: Address;
|
|
31
31
|
siren?: string;
|
|
32
|
+
vatId?: string;
|
|
32
33
|
|
|
33
34
|
constructor(
|
|
34
35
|
id: string,
|
|
@@ -45,7 +46,8 @@ export default class Customer extends User {
|
|
|
45
46
|
companyPhoneNumber: string,
|
|
46
47
|
billingAddress: Address | undefined = undefined,
|
|
47
48
|
notes: string,
|
|
48
|
-
siren: string = ""
|
|
49
|
+
siren: string = "",
|
|
50
|
+
vatId: string = ""
|
|
49
51
|
) {
|
|
50
52
|
super(id, roles, firstname, lastname, avatar, email);
|
|
51
53
|
|
|
@@ -57,5 +59,6 @@ export default class Customer extends User {
|
|
|
57
59
|
this.notes = notes;
|
|
58
60
|
this.billingAddress = billingAddress;
|
|
59
61
|
this.siren = siren;
|
|
62
|
+
this.vatId = vatId;
|
|
60
63
|
}
|
|
61
64
|
}
|
package/src/models/Vehicle.ts
CHANGED
|
@@ -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() {
|
|
@@ -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;
|