@movalib/movalib-commons 1.59.13 → 1.59.15

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.
Files changed (46) hide show
  1. package/.env.development +2 -0
  2. package/devIndex.tsx +1 -1
  3. package/dist/devIndex.js +1 -1
  4. package/dist/index.d.ts +6 -3
  5. package/dist/index.js +14 -4
  6. package/dist/src/components/LinkedDocumentDialog.d.ts +11 -0
  7. package/dist/src/components/LinkedDocumentDialog.js +55 -0
  8. package/dist/src/{VehicleFullCard.d.ts → components/vehicle/VehicleFullCard.d.ts} +5 -2
  9. package/dist/src/{VehicleFullCard.js → components/vehicle/VehicleFullCard.js} +44 -22
  10. package/dist/src/components/vehicle/VehiclePlateField.d.ts +8 -0
  11. package/dist/src/components/vehicle/VehiclePlateField.js +122 -0
  12. package/dist/src/helpers/CookieUtils.js +2 -1
  13. package/dist/src/helpers/Enums.d.ts +10 -1
  14. package/dist/src/helpers/Enums.js +10 -1
  15. package/dist/src/helpers/Tools.d.ts +1 -0
  16. package/dist/src/helpers/Tools.js +10 -1
  17. package/dist/src/models/Garage.d.ts +2 -0
  18. package/dist/src/services/AuthenticationService.js +2 -0
  19. package/dist/src/services/GarageService.d.ts +8 -4
  20. package/dist/src/services/GarageService.js +75 -45
  21. package/dist/src/services/UserConnected.d.ts +9 -0
  22. package/dist/src/services/UserConnected.js +59 -0
  23. package/dist/src/services/UserService.d.ts +1 -1
  24. package/dist/src/services/VehicleService.d.ts +3 -0
  25. package/dist/src/services/VehicleService.js +22 -0
  26. package/dist/src/style/styled.d.ts +17 -0
  27. package/dist/src/style/styled.js +68 -0
  28. package/dist/src/style/styled.ts +70 -0
  29. package/index.ts +8 -3
  30. package/package.json +3 -2
  31. package/src/VehiclePlateField.tsx +1 -0
  32. package/src/components/LinkedDocumentDialog.tsx +200 -0
  33. package/src/components/vehicle/VehicleFullCard.tsx +549 -0
  34. package/src/components/vehicle/VehiclePlateField.tsx +164 -0
  35. package/src/helpers/CookieUtils.ts +2 -1
  36. package/src/helpers/Enums.ts +12 -1
  37. package/src/helpers/Tools.ts +5 -0
  38. package/src/models/Event.ts +1 -1
  39. package/src/models/Garage.ts +2 -0
  40. package/src/services/AuthenticationService.ts +2 -1
  41. package/src/services/GarageService.ts +557 -390
  42. package/src/services/UserConnected.ts +56 -0
  43. package/src/services/UserService.ts +1 -1
  44. package/src/services/VehicleService.ts +25 -0
  45. package/src/style/styled.ts +70 -0
  46. package/src/VehicleFullCard.tsx +0 -503
@@ -0,0 +1,56 @@
1
+ import User from "../models/User";
2
+ import UserService from "./UserService";
3
+
4
+ export default class UserConnected {
5
+ private static instance: UserConnected;
6
+ private _me: User | null; // Replace 'any' with the appropriate type for the user information
7
+
8
+ private constructor() {
9
+ const storedUser = localStorage.getItem('user');
10
+ this._me = storedUser ? JSON.parse(storedUser) : null;
11
+ }
12
+
13
+ public static getInstance(): UserConnected {
14
+ if (!UserConnected.instance) {
15
+ UserConnected.instance = new UserConnected();
16
+ }
17
+
18
+ return UserConnected.instance;
19
+ }
20
+
21
+ public get me(): any {
22
+ if (!this._me) {
23
+ const storedUser = localStorage.getItem('user');
24
+ if(storedUser === undefined || storedUser === null || storedUser === 'undefined') {
25
+ UserService.getCurrentUser()
26
+ .then((response) => {
27
+ localStorage.setItem('user', JSON.stringify(response.data));
28
+ this._me = response.data as User;
29
+ return this._me;
30
+ })
31
+ } else {
32
+ this._me = JSON.parse(storedUser);
33
+ return this._me;
34
+ }
35
+ } else {
36
+ return this._me;
37
+ }
38
+ }
39
+
40
+
41
+ public set me(user: any) {
42
+ this._me = user;
43
+ if (user) {
44
+ localStorage.setItem('user', JSON.stringify(user));
45
+ } else {
46
+ localStorage.removeItem('user'); // Supprime les données si user est null ou undefined
47
+ }
48
+ }
49
+
50
+ public clearUser() {
51
+ // Méthode pour effacer l'utilisateur
52
+ this._me = null;
53
+ localStorage.removeItem('user');
54
+ }
55
+
56
+ }
@@ -78,7 +78,7 @@ export default class UserService {
78
78
  * @param password
79
79
  * @returns
80
80
  */
81
- static async getCurrentUser(appType: MovaAppType): Promise<APIResponse<User>> {
81
+ static async getCurrentUser(appType?: MovaAppType): Promise<APIResponse<User>> {
82
82
  try {
83
83
  return await request({
84
84
  url: `${API_BASE_URL}/user/me`,
@@ -13,6 +13,31 @@ export default class VehicleService {
13
13
  });
14
14
  }
15
15
 
16
+ static getVehicleDocument(appType: MovaAppType, vehicleId: number): Promise<APIResponse<string>> {
17
+ return request({
18
+ url: `${API_BASE_URL}/vehicle/${vehicleId}/document`,
19
+ method: APIMethod.GET,
20
+ appType: appType,
21
+ });
22
+ }
23
+
24
+ static deleteVehicleDocument(appType: MovaAppType,vehicleId: number, documentId: string): Promise<APIResponse<string>> {
25
+ return request({
26
+ url: `${API_BASE_URL}/vehicle/${vehicleId}/documents/${documentId}`,
27
+ method: APIMethod.DELETE,
28
+ appType: appType,
29
+ });
30
+ }
31
+
32
+ static uploadVehicleDocument(appType: MovaAppType, vehicleId: number, req: FormData): Promise<APIResponse<string>> {
33
+ return request({
34
+ url: `${API_BASE_URL}/vehicle/${vehicleId}/documents`,
35
+ method: APIMethod.POST,
36
+ appType: appType,
37
+ body: req
38
+ });
39
+ }
40
+
16
41
  static editVehicle({vehicleId, appType,...payload}: EditVehicleParams): Promise<APIResponse<string>> {
17
42
  return request({
18
43
  url: `${API_BASE_URL}/vehicle/${vehicleId}`,
@@ -0,0 +1,70 @@
1
+ import { ToggleButtonProps, ToggleButton, styled, ToggleButtonGroup, lighten } from "@mui/material";
2
+
3
+ interface StyledToggleButtonProps extends ToggleButtonProps {
4
+ customSelectedBackgroundColor?: string;
5
+ customBackgroundColor?: string;
6
+ customHoverColor?: string;
7
+ }
8
+
9
+ export const StyledToggleButton = styled(ToggleButton)<StyledToggleButtonProps>(
10
+ ({ theme, customSelectedBackgroundColor, customBackgroundColor, customHoverColor }) => ({
11
+ padding: theme.spacing(1),
12
+ marginBottom: theme.spacing(2),
13
+ borderRadius: theme.shape.borderRadius,
14
+ '&:hover': {
15
+ backgroundColor: customHoverColor || theme.palette.warning.dark,
16
+ },
17
+ '&.Mui-selected': {
18
+ backgroundColor: customSelectedBackgroundColor || theme.palette.warning.main,
19
+ },
20
+ '&.Mui-selected:hover': {
21
+ backgroundColor: customHoverColor || theme.palette.warning.dark,
22
+ },
23
+ '&:not(:first-of-type)': {
24
+ borderRadius: theme.shape.borderRadius,
25
+ border: '1px solid rgba(0, 0, 0, 0.12)',
26
+ },
27
+ '&:first-of-type': {
28
+ borderRadius: theme.shape.borderRadius,
29
+ },
30
+ '&.Mui-disabled': {
31
+ border: 0,
32
+ backgroundColor: theme.palette.grey[100],
33
+ },
34
+ }),
35
+ );
36
+
37
+
38
+ /**
39
+ * Personnalisation du style des Toogle Buttons
40
+ * Note : il n'est posssible de le personnaliser directement au niveau
41
+ * de l'objet "components" du theme.
42
+ */
43
+ export const StyledToggleButtonGroup = styled(ToggleButtonGroup)(({ theme }) => ({
44
+ '& .MuiToggleButtonGroup-grouped': {
45
+ padding: theme.spacing(1),
46
+ marginBottom: theme.spacing(2),
47
+ marginLeft: theme.spacing(1),
48
+ marginRight: theme.spacing(1),
49
+ '&.Mui-disabled': {
50
+ border: 0,
51
+ backgroundColor: theme.palette.grey[100],
52
+ },
53
+ '&.Mui-selected': {
54
+ backgroundColor: theme.palette.primary.light,
55
+ },
56
+ '&:not(:first-of-type)': {
57
+ borderRadius: theme.shape.borderRadius,
58
+ border: '1px solid rgba(0, 0, 0, 0.12)',
59
+ },
60
+ '&:first-of-type': {
61
+ borderRadius: theme.shape.borderRadius,
62
+ },
63
+ '&:hover': {
64
+ backgroundColor: lighten(theme.palette.primary.light, 0.3), // Modifier la couleur de fond au survol
65
+ },
66
+ '&.Mui-selected:hover': {
67
+ backgroundColor: theme.palette.primary.light, // Modifier la couleur de fond au survol
68
+ },
69
+ },
70
+ }));
@@ -1,503 +0,0 @@
1
- import { Button, Card, CardActions, CardContent, FormControl, FormHelperText, Grid, IconButton, InputLabel,
2
- Link, MenuItem, Select, SelectChangeEvent, TextField, Typography, darken, useTheme } from '@mui/material';
3
- import { useState, type FC, useEffect, useRef } from 'react';
4
- import CarFigure from "./assets/images/car_figure.png";
5
- import { MovaFormField, MovaVehicleForm } from './helpers/Types';
6
- import Vehicle from './models/Vehicle';
7
- import Document from './models/Document';
8
- import VehicleTire from './models/VehicleTire';
9
- import MovaVehicleTireField from './MovaVehicleTireField';
10
- import ConfirmationDialog from './ConfirmationDialog';
11
- import { DocumentType, DateFormatTypes } from './helpers/Enums';
12
- import { validateField, formatVehicleTire, formatFrenchVehiclePlate} from './helpers/Tools';
13
- import MovaDigitalPassport from './MovaDigitalPassport';
14
- import Loader from './Loader';
15
- import { formatDateByCountryCode } from './helpers/DateUtils';
16
- import CancelIcon from '@mui/icons-material/CloseRounded';
17
- import EditIcon from '@mui/icons-material/EditRounded';
18
- import CloseIcon from '@mui/icons-material/CloseRounded';
19
- import Logger from './helpers/Logger';
20
-
21
- interface VehicleFullCardProps {
22
- vehicle: Vehicle,
23
- onError: (message: string) => void,
24
- onUploadDocument: (data: FormData) => void,
25
- onDeleteDocument: (documentId: string) => void,
26
- editMode: boolean,
27
- fullwidth?: boolean,
28
- focused?: boolean,
29
- onUpdate?: (form: MovaVehicleForm) => void,
30
- onDelete?: () => void;
31
- }
32
-
33
- const initialUserFormState = {
34
- currentMileage: { value: null, isValid: true },
35
- averageMileagePerYear: { value: null, isValid: true },
36
- tireSize: { value: null, isValid: true },
37
- tireWidth: { value: '', isValid: true },
38
- tireHeight: { value: '', isValid: true },
39
- tireDiameter: { value: '', isValid: true },
40
- tireSpeedIndex: { value: '', isValid: true }
41
- }
42
-
43
- const VehicleFullCard: FC<VehicleFullCardProps> = ({ vehicle, fullwidth, onError, onUploadDocument, onDeleteDocument, editMode = false, focused = false, onUpdate, onDelete }) => {
44
-
45
- const theme = useTheme();
46
- const [localEditMode, setLocalEditMode] = useState(editMode);
47
- const [openConfirmDocumentDelete, setOpenConfirmDocumentDelete] = useState(false);
48
- const [openConfirmVehicleDelete, setOpenConfirmVehicleDelete] = useState(false);
49
- const [documentToDelete, setDocumentToDelete] = useState('');
50
- // Formulaire utilisé pour les modifications d'informations sur le véhicule
51
- const [form, setForm] = useState<MovaVehicleForm>(initialUserFormState);
52
- // Références aux éventuels documents uploadés depuis la fiche
53
- const invoiceInputRef = useRef(null);
54
- const tirePictureInputRef = useRef(null);
55
-
56
- useEffect(() => {
57
- setLocalEditMode(editMode);
58
- }, [editMode]);
59
-
60
- useEffect(() => {
61
- initForm();
62
- }, [vehicle]);
63
-
64
- const initForm = () => {
65
- if(vehicle){
66
-
67
- setForm(prevForm => (
68
- { ...prevForm, ['currentMileage'] : { ...prevForm['currentMileage'], value: vehicle.currentMileage }}));
69
- setForm(prevForm => (
70
- { ...prevForm, ['averageMileagePerYear'] : { ...prevForm['averageMileagePerYear'], value: vehicle.averageMileagePerYear }}));
71
- setForm(prevForm => (
72
- { ...prevForm, ['tireWidth'] : { ...prevForm['tireWidth'], value: vehicle.tireWidth }}));
73
- setForm(prevForm => (
74
- { ...prevForm, ['tireHeight'] : { ...prevForm['tireHeight'], value: vehicle.tireHeight }}));
75
- setForm(prevForm => (
76
- { ...prevForm, ['tireDiameter'] : { ...prevForm['tireDiameter'], value: vehicle.tireDiameter }}));
77
- setForm(prevForm => (
78
- { ...prevForm, ['tireSpeedIndex'] : { ...prevForm['tireSpeedIndex'], value: vehicle.tireSpeedIndex }}));
79
-
80
- if(isVehicleTireSizeDefined(vehicle)){
81
- setForm(prevForm => (
82
- { ...prevForm, ['tireSize'] : { ...prevForm['tireSize'], value: vehicle.tireSize }}));
83
- }
84
-
85
- Logger.info(form);
86
- }
87
- }
88
-
89
- const isVehicleTireSizeDefined = (vehicle:Vehicle) => {
90
- return vehicle.tireSize && vehicle.tireSize.diameter && vehicle.tireSize.height && vehicle.tireSize.speedIndex && vehicle.tireSize.width;
91
- }
92
-
93
- const validateForm = () => {
94
- let newForm: MovaVehicleForm = { ...form };
95
-
96
- // Validator pour les champs obligatoires
97
- newForm.currentMileage = validateField(form.currentMileage, value => !!value, 'Champ obligatoire');
98
- newForm.averageMileagePerYear = validateField(form.averageMileagePerYear, value => !!value, 'Champ obligatoire');
99
-
100
- // La validation de la saisie des pneumatiques se fait dans le composant "MovaVehicleTireField", traitée dans le callback "handleOnChangeVehicleTire"
101
-
102
- setForm(newForm);
103
-
104
- return newForm.currentMileage.isValid && newForm.averageMileagePerYear.isValid && newForm.tireSize.isValid;
105
- }
106
-
107
- const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
108
- handleChange(e.target.name, e.target.value);
109
- }
110
-
111
- const handleSelectChange = (e: SelectChangeEvent<string>): void => {
112
- handleChange(e.target.name, e.target.value);
113
- }
114
-
115
- const handleChange = (fieldName:string, fieldValue:string): void => {
116
- const newField: MovaFormField = { [fieldName]: { value: fieldValue, isValid: true } };
117
-
118
- setForm({ ...form, ...newField});
119
- }
120
-
121
- const uploadVehicleDocument = (document: File, documentType:DocumentType) => {
122
-
123
- if(vehicle && document && documentType){
124
-
125
- // Utilisation d'un formData pour permettre le trasnfert de fichier vers l'API
126
- let formData = new FormData();
127
- formData.append("documentType", documentType);
128
- // Ajouter la facture à FormData
129
- formData.append('file', document);
130
-
131
- // Appel du callback correspondant
132
- if(onUploadDocument)
133
- onUploadDocument(formData);
134
- }
135
- }
136
-
137
- /**
138
- *
139
- * @param event L'upload des documents se fait directement lors du téléchargement
140
- * @param docType
141
- */
142
- const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>, docType:DocumentType) => {
143
- event.preventDefault();
144
-
145
- if(event && event.target.files && event.target.files.length > 0 && docType){
146
- uploadVehicleDocument(event.target.files[0], docType);
147
- }
148
-
149
- };
150
-
151
- const handleOnClickEdit = () => {
152
-
153
- // On passe la fiche véhicule en mode édition
154
- setLocalEditMode(true);
155
- }
156
-
157
- const handleOnChangeVehicleTire = (vehicleTire: VehicleTire, isValid:boolean) => {
158
- setForm(prevForm => (
159
- { ...prevForm, ['tireSize'] : { ...prevForm['tireSize'], value: vehicleTire, isValid: isValid }}));
160
- }
161
-
162
- const handleOnClickDeleteVehicle = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
163
- e.preventDefault();
164
- setOpenConfirmVehicleDelete(true);
165
- }
166
-
167
- const handleDeleteDocument = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, documentId: string) => {
168
- e.preventDefault();
169
- setDocumentToDelete(documentId);
170
- setOpenConfirmDocumentDelete(true);
171
- }
172
-
173
- const handleOnClickValidate = () => {
174
-
175
- if(validateForm()) {
176
-
177
- Logger.info(form.tireSize.value);
178
-
179
- let query = {
180
- currentMileage : form.currentMileage.value,
181
- averageMileagePerYear : form.averageMileagePerYear.value,
182
- tireWidth: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).width : undefined,
183
- tireHeight : form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).height : undefined,
184
- tireDiameter: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).diameter : undefined,
185
- tireSpeedIndex: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).speedIndex : undefined
186
- }
187
- Logger.info(query)
188
-
189
- // Appel du callback correspondant
190
- if(onUpdate)
191
- onUpdate(form);
192
- }
193
- }
194
-
195
- const handleOnClickCancel = () => {
196
- initForm();
197
- setLocalEditMode(false);
198
- }
199
-
200
- const handleCloseConfirmDocumentDelete = () => {
201
- setOpenConfirmDocumentDelete(false);
202
- setDocumentToDelete('');
203
- }
204
-
205
- const handleCloseConfirmVehicleDelete = () => {
206
- setOpenConfirmVehicleDelete(false);
207
- }
208
-
209
- /**
210
- *
211
- */
212
- const handleConfirmDocumentDelete = () => {
213
- setOpenConfirmDocumentDelete(false);
214
-
215
- if(vehicle && documentToDelete){
216
-
217
- // Appel du callback correspondant
218
- if(onDeleteDocument)
219
- onDeleteDocument(documentToDelete);
220
- }
221
- }
222
-
223
- const handleConfirmVehicleDelete = () => {
224
- setOpenConfirmVehicleDelete(false);
225
-
226
- if(vehicle && onDelete){
227
-
228
- // Appel du callback correspondant
229
- onDelete();
230
- }
231
- }
232
-
233
- return (
234
- <>
235
- { vehicle &&
236
- <Card variant='outlined' sx={{ maxWidth: fullwidth ? '80%' : 345,
237
- backgroundColor: focused ? theme.palette.primary.light : 'white',
238
- overflow: 'visible', mt: 4, pb: 1 }}
239
- >
240
- <img src={CarFigure} style={{
241
- position: 'relative',
242
- width: '40%',
243
- top: '-25px',
244
- left: '-15px',
245
- zIndex: 200}} alt='Icone Voiture'>
246
- </img>
247
-
248
- <MovaDigitalPassport digitalPassportIndex={vehicle.digitalPassportIndex} />
249
-
250
- <CardContent sx={{ pt: 0, pb: 0}}>
251
- <Typography variant="h6" component="div" align="center" sx={{ mb:1 }} color={darken(theme.palette.primary.main, 0.2)}>
252
- {vehicle.brand && `${vehicle.brand} `}
253
- {vehicle.model && `${vehicle.model} `}
254
- {vehicle.version && `${vehicle.version}`}
255
- </Typography>
256
- <Grid container justifyContent="space-between">
257
-
258
- <Grid item xs={12}>
259
- <Typography variant="body1" color="text.primary">
260
- <b>{formatFrenchVehiclePlate(vehicle.plate)}</b>
261
- </Typography>
262
- </Grid>
263
-
264
- {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
265
- <Grid item xs={8} >
266
- <Typography variant="body1" color="text.secondary">
267
- Km actuel :
268
- </Typography>
269
- </Grid>
270
- <Grid item xs={4} sx={{ textAlign: 'right' }}>
271
- <Typography variant="body1" color="text.secondary">
272
- <b>{vehicle.currentMileage} km</b>
273
- </Typography>
274
- </Grid>
275
- </Grid> }
276
-
277
- {localEditMode && <Grid item xs={12}>
278
- <TextField
279
- label="Kilométrage actuel"
280
- name="currentMileage"
281
- variant="outlined"
282
- type="number"
283
- required
284
- value={form.currentMileage.value}
285
- onChange={(e) => handleInputChange(e)}
286
- error={(Boolean(form.currentMileage.error))}
287
- sx={{
288
- width: '100%',
289
- mt: 2,
290
- '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
291
- }}
292
- helperText={Boolean(form.currentMileage.error && form.currentMileage.value > 0)
293
- ? form.currentMileage.error : "Sur votre tableau de bord 😉"}
294
- />
295
- </Grid> }
296
-
297
- {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
298
- <Grid item xs={8} >
299
- <Typography variant="body1" color="text.secondary">
300
- Km moyen annuel :
301
- </Typography>
302
- </Grid>
303
- <Grid item xs={4} sx={{ textAlign: 'right' }}>
304
- <Typography variant="body1" color="text.secondary">
305
- <b>{vehicle.averageMileagePerYear} km</b>
306
- </Typography>
307
- </Grid>
308
- </Grid> }
309
-
310
- {localEditMode && <Grid item xs={12}>
311
- <FormControl fullWidth margin="normal" error={Boolean(form.averageMileagePerYear.error)}>
312
- <InputLabel id="averageMileagePerYear-label">Kilométrage moyen annuel</InputLabel>
313
- <Select
314
- labelId="averageMileagePerYear-label"
315
- id="averageMileagePerYear"
316
- name="averageMileagePerYear"
317
- value={form.averageMileagePerYear.value ?
318
- String(form.averageMileagePerYear.value) : ''}
319
- onChange={e => handleSelectChange(e)}
320
- label="Kilométrage moyen annuel"
321
- >
322
- <MenuItem value={5000}>5 000</MenuItem>
323
- <MenuItem value={10000}>10 000</MenuItem>
324
- <MenuItem value={15000}>15 000</MenuItem>
325
- <MenuItem value={20000}>20 000</MenuItem>
326
- <MenuItem value={25000}>25 000</MenuItem>
327
- <MenuItem value={30000}>30 000</MenuItem>
328
- <MenuItem value={50000}>50 000</MenuItem>
329
- <MenuItem value={75000}>75 000</MenuItem>
330
- <MenuItem value={100000}>100 000</MenuItem>
331
- <MenuItem value={999999}>+100 000</MenuItem>
332
- </Select>
333
- <FormHelperText>{form.averageMileagePerYear.error}</FormHelperText>
334
- </FormControl>
335
- </Grid>}
336
-
337
- {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
338
- <Grid item xs={6}>
339
- <Typography variant="body1" color="text.secondary">
340
- Pneumatiques :
341
- </Typography>
342
- </Grid>
343
- <Grid item xs={6} sx={{ textAlign: 'right' }}>
344
- <Typography variant="body1" color="text.secondary">
345
- {isVehicleTireSizeDefined(vehicle) ? <b>{formatVehicleTire(vehicle.tireSize)}</b> : '-' }
346
- </Typography>
347
- </Grid>
348
- </Grid> }
349
-
350
- {localEditMode && <Grid item xs={12} sx={{ mt: 1 }}>
351
- <MovaVehicleTireField
352
- vehicleTire={form.tireSize.value}
353
- onChangeVehicleTire={handleOnChangeVehicleTire}
354
- />
355
- </Grid> }
356
-
357
- </Grid>
358
-
359
- {!localEditMode && <>
360
-
361
- <Grid item xs={12}>
362
- <Typography variant="h6" component="div" align="center" sx={{ mt: 3, mb:1 }} color={darken(theme.palette.primary.main, 0.2)}>
363
- CARNET DU VÉHICULE
364
- </Typography>
365
- </Grid>
366
-
367
- {/** Les FACTURES du véhicule */}
368
- {vehicle.documents && vehicle.documents?.filter(doc => doc.type === DocumentType.VEHICLE_MAINTENANCE_INVOICE)
369
- .map((invoice, index) => (
370
- <Grid container sx={{ justifyContent: 'space-between', alignItems: 'center' }} key={index+1}>
371
- <Grid item xs={11} key={(index+1)*50} sx={{ textAlign: 'left' }} >
372
- <Link color={darken('#F29ABA', 0.2)} href={invoice.fileSignedUrl} target="_blank" rel="noopener">
373
- <Typography variant="body1">
374
- Facture du {formatDateByCountryCode(invoice.creationDate, 'fr', DateFormatTypes.SHORT_FORMAT_DATE)}
375
- </Typography>
376
- </Link>
377
- </Grid>
378
- <Grid item xs={1} key={(index+1)*100} sx={{ textAlign: 'right' }}>
379
- <IconButton onClick={(e) => handleDeleteDocument(e, invoice.id)}>
380
- <CloseIcon />
381
- </IconButton>
382
- </Grid>
383
- </Grid>
384
- ))}
385
-
386
- {/** Les PHOTOS du véhicule */}
387
- {vehicle.documents && vehicle.documents?.filter(doc => doc.type === DocumentType.VEHICLE_TIRE_PHOTO)
388
- .map((tirePhoto, index) => (
389
- <Grid container sx={{ justifyContent: 'space-between', alignItems: 'center' }} key={index+1}>
390
- <Grid item xs={11} key={(index+1)*50} sx={{ textAlign: 'left' }} >
391
- <Link color={darken('#F29ABA', 0.2)} href={tirePhoto.fileSignedUrl} target="_blank" rel="noopener">
392
- <Typography variant="body1">
393
- Photo pneu du {formatDateByCountryCode(tirePhoto.creationDate, 'fr', DateFormatTypes.SHORT_FORMAT_DATE)}
394
- </Typography>
395
- </Link>
396
- </Grid>
397
- <Grid item xs={1} key={(index+1)*100} sx={{ textAlign: 'right' }}>
398
- <IconButton onClick={(e) => handleDeleteDocument(e, tirePhoto.id)}>
399
- <CloseIcon />
400
- </IconButton>
401
- </Grid>
402
- </Grid>
403
- ))}
404
-
405
- <Grid container >
406
- <Grid item xs={6} sx={{ mt: 2, textAlign: 'center' }} >
407
- {/* Input caché de type "file" */}
408
- <div>
409
- <input
410
- accept="image/*, application/pdf"
411
- type="file"
412
- style={{ display: 'none' }}
413
- ref={invoiceInputRef}
414
- id="raised-button-invoice"
415
- onChange={(e) => handleFileChange(e, DocumentType.VEHICLE_MAINTENANCE_INVOICE)}
416
- />
417
- <label htmlFor="raised-button-invoice">
418
- <Button size='large' component="span" variant="outlined"
419
- sx={{ alignItems: 'normal', width:'90%', mt: 2, mb: 1, height: '70px', p:1,
420
- color:darken(theme.palette.primary.main, 0.2) }}>
421
- Ajouter Facture
422
- </Button>
423
- </label>
424
- </div>
425
- </Grid>
426
-
427
- <Grid item xs={6} sx={{ mt: 2, textAlign: 'center' }} >
428
- {/* Input caché de type "file" */}
429
- <div>
430
- <input
431
- accept="image/*"
432
- type="file"
433
- style={{ display: 'none' }}
434
- ref={tirePictureInputRef}
435
- id="raised-button-tire"
436
- onChange={(e) => handleFileChange(e, DocumentType.VEHICLE_TIRE_PHOTO)}
437
- />
438
- <label htmlFor="raised-button-tire">
439
- <Button component="span" variant="outlined"
440
- sx={{ alignItems: 'normal', width:'90%', mt: 2, mb: 1, height: '70px', p:1,
441
- color:darken(theme.palette.primary.main, 0.2) }}>
442
- Ajouter Photo Pneu
443
- </Button>
444
- </label>
445
- </div>
446
- </Grid>
447
- </Grid>
448
-
449
- </>
450
- }
451
-
452
- </CardContent>
453
-
454
- <CardActions sx={{ mt: 3, justifyContent: localEditMode ? 'center' : 'end' }}>
455
- {!localEditMode &&
456
- <>
457
- <Button onClick={handleOnClickEdit} color="inherit" sx={{ width: '45%' }} variant='text'>
458
- <EditIcon sx={{ mr: 1 }} />MODIFIER
459
- </Button>
460
- </>
461
- }
462
-
463
- {localEditMode &&
464
- <>
465
- <Button onClick={handleOnClickCancel} sx={{ width: '45%', color:theme.palette.text.secondary }} variant='text'>
466
- <CancelIcon sx={{ mr: 1 }} />ANNULER
467
- </Button>
468
-
469
- <Button onClick={handleOnClickValidate} sx={{ width: '45%', color: darken(theme.palette.primary.main, 0.2) }} variant='text'>
470
- <EditIcon sx={{ mr: 1 }} />VALIDER
471
- </Button>
472
- </>
473
- }
474
- </CardActions>
475
-
476
- </Card>
477
- }
478
-
479
- {localEditMode && onDelete &&
480
- <Button onClick={(e) => handleOnClickDeleteVehicle(e)} sx={{ width: '90', mt: 4, color:theme.palette.error.light,
481
- borderColor: theme.palette.error.light }} variant='outlined'>
482
- Supprimer le véhicule
483
- </Button>
484
- }
485
-
486
- <ConfirmationDialog
487
- open={openConfirmDocumentDelete}
488
- onClose={handleCloseConfirmDocumentDelete}
489
- onConfirm={handleConfirmDocumentDelete}
490
- message="Êtes-vous sûr de vouloir supprimer ce document ?"
491
- />
492
-
493
- <ConfirmationDialog
494
- open={openConfirmVehicleDelete}
495
- onClose={handleCloseConfirmVehicleDelete}
496
- onConfirm={handleConfirmVehicleDelete}
497
- message="Êtes-vous sûr de vouloir supprimer ce véhicule ?"
498
- />
499
- </>
500
- );
501
- }
502
-
503
- export default VehicleFullCard;