@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,549 @@
1
+ import {
2
+ Alert, Box, Button, Card, CardActions, CardContent, FormControl, FormHelperText, Grid, IconButton, InputLabel,
3
+ Link, MenuItem, Select, SelectChangeEvent, TextField, Tooltip, Typography, darken, useTheme
4
+ } from '@mui/material';
5
+ import { useState, type FC, useEffect, useRef } from 'react';
6
+ import CarFigure from "../../assets/images/car_figure.png";
7
+ import { MovaFormField, MovaVehicleForm } from '../../helpers/Types';
8
+ import Vehicle from '../../models/Vehicle';
9
+ import Document from '../../models/Document';
10
+ import VehicleTire from '../../models/VehicleTire';
11
+ import MovaVehicleTireField from '../../MovaVehicleTireField';
12
+ import ConfirmationDialog from '../../ConfirmationDialog';
13
+ import { DocumentType, DateFormatTypes, MovaAppType } from '../../helpers/Enums';
14
+ import { validateField, formatVehicleTire, formatFrenchVehiclePlate, iAmOwner } from '../../helpers/Tools';
15
+ import MovaDigitalPassport from '../../MovaDigitalPassport';
16
+ import Loader from '../../Loader';
17
+ import { formatDateByCountryCode } from '../../helpers/DateUtils';
18
+ import CancelIcon from '@mui/icons-material/CloseRounded';
19
+ import EditIcon from '@mui/icons-material/EditRounded';
20
+ import CloseIcon from '@mui/icons-material/CloseRounded';
21
+ import Logger from '../../helpers/Logger';
22
+ import { AttachFile } from '@mui/icons-material';
23
+ import { LinkedDocumentDialog } from '../LinkedDocumentDialog';
24
+
25
+ interface VehicleFullCardProps {
26
+ vehicle: Vehicle,
27
+ onError: (message: string) => void,
28
+ onUploadDocument: (data: FormData) => void,
29
+ onDeleteDocument: (documentId: string) => void,
30
+ editMode: boolean,
31
+ appType: MovaAppType;
32
+ fullwidth?: boolean,
33
+ focused?: boolean,
34
+ onUpdate?: (form: MovaVehicleForm) => void,
35
+ onDelete?: () => void;
36
+ currentUpload: boolean;
37
+ }
38
+
39
+ const initialUserFormState = {
40
+ currentMileage: { value: null, isValid: true },
41
+ averageMileagePerYear: { value: null, isValid: true },
42
+ tireSize: { value: null, isValid: true },
43
+ tireWidth: { value: '', isValid: true },
44
+ tireHeight: { value: '', isValid: true },
45
+ tireDiameter: { value: '', isValid: true },
46
+ tireSpeedIndex: { value: '', isValid: true }
47
+ }
48
+
49
+ const VehicleFullCard: FC<VehicleFullCardProps> = ({ vehicle, fullwidth, onError, onUploadDocument, onDeleteDocument, appType, editMode = false, focused = false, onUpdate, onDelete, currentUpload }) => {
50
+
51
+ const theme = useTheme();
52
+ const [localEditMode, setLocalEditMode] = useState(editMode);
53
+ const [openConfirmDocumentDelete, setOpenConfirmDocumentDelete] = useState(false);
54
+ const [openConfirmVehicleDelete, setOpenConfirmVehicleDelete] = useState(false);
55
+ const [documentToDelete, setDocumentToDelete] = useState('');
56
+ const [sizeLimit, setSizeLimit] = useState(false);
57
+ // Formulaire utilisé pour les modifications d'informations sur le véhicule
58
+ const [form, setForm] = useState<MovaVehicleForm>(initialUserFormState);
59
+ // Références aux éventuels documents uploadés depuis la fiche
60
+ const invoiceInputRef = useRef<HTMLInputElement>(null);
61
+ const tirePictureInputRef = useRef(null);
62
+ const [isShowLinkedDocument, setShowLinkedDocument] = useState(false);
63
+ const docTypeCurrent = useRef<DocumentType>();
64
+
65
+ const messageRGPD = appType === MovaAppType.INDIVIDUAL ? <Box></Box> : <Box sx={{ mt: 2 }}><Alert severity='warning'>
66
+ Vous êtes responsable des documents que vous importez, en ajoutant un document vous reconnaissez
67
+ disposer du consentement explicite du client pour le stockage de ses données conformément à la
68
+ réglementation RGPD.
69
+ </Alert></Box>;
70
+
71
+ useEffect(() => {
72
+ setLocalEditMode(editMode);
73
+ }, [editMode]);
74
+
75
+ useEffect(() => {
76
+ initForm();
77
+ }, [vehicle]);
78
+
79
+ const initForm = () => {
80
+ if (vehicle) {
81
+
82
+ setForm(prevForm => (
83
+ { ...prevForm, ['currentMileage']: { ...prevForm['currentMileage'], value: vehicle.currentMileage } }));
84
+ setForm(prevForm => (
85
+ { ...prevForm, ['averageMileagePerYear']: { ...prevForm['averageMileagePerYear'], value: vehicle.averageMileagePerYear } }));
86
+ setForm(prevForm => (
87
+ { ...prevForm, ['tireWidth']: { ...prevForm['tireWidth'], value: vehicle.tireWidth } }));
88
+ setForm(prevForm => (
89
+ { ...prevForm, ['tireHeight']: { ...prevForm['tireHeight'], value: vehicle.tireHeight } }));
90
+ setForm(prevForm => (
91
+ { ...prevForm, ['tireDiameter']: { ...prevForm['tireDiameter'], value: vehicle.tireDiameter } }));
92
+ setForm(prevForm => (
93
+ { ...prevForm, ['tireSpeedIndex']: { ...prevForm['tireSpeedIndex'], value: vehicle.tireSpeedIndex } }));
94
+
95
+ if (isVehicleTireSizeDefined(vehicle)) {
96
+ setForm(prevForm => (
97
+ { ...prevForm, ['tireSize']: { ...prevForm['tireSize'], value: vehicle.tireSize } }));
98
+ }
99
+
100
+ Logger.info(form);
101
+ }
102
+ }
103
+
104
+ const toggleShowLinkedDocument = (docType: DocumentType | null) => {
105
+ setShowLinkedDocument(!isShowLinkedDocument);
106
+ if (docType && invoiceInputRef.current) {
107
+ docTypeCurrent.current = docType;
108
+ invoiceInputRef.current.click();
109
+ } else {
110
+ docTypeCurrent.current = undefined;
111
+ }
112
+ }
113
+
114
+ const isVehicleTireSizeDefined = (vehicle: Vehicle) => {
115
+ return vehicle.tireSize && vehicle.tireSize.diameter && vehicle.tireSize.height && vehicle.tireSize.speedIndex && vehicle.tireSize.width;
116
+ }
117
+
118
+ const validateForm = () => {
119
+ let newForm: MovaVehicleForm = { ...form };
120
+
121
+ // Validator pour les champs obligatoires
122
+ newForm.currentMileage = validateField(form.currentMileage, value => !!value, 'Champ obligatoire');
123
+ newForm.averageMileagePerYear = validateField(form.averageMileagePerYear, value => !!value, 'Champ obligatoire');
124
+
125
+ // La validation de la saisie des pneumatiques se fait dans le composant "MovaVehicleTireField", traitée dans le callback "handleOnChangeVehicleTire"
126
+
127
+ setForm(newForm);
128
+
129
+ return newForm.currentMileage.isValid && newForm.averageMileagePerYear.isValid && newForm.tireSize.isValid;
130
+ }
131
+
132
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
133
+ handleChange(e.target.name, e.target.value);
134
+ }
135
+
136
+ const handleSelectChange = (e: SelectChangeEvent<string>): void => {
137
+ handleChange(e.target.name, e.target.value);
138
+ }
139
+
140
+ const handleChange = (fieldName: string, fieldValue: string): void => {
141
+ const newField: MovaFormField = { [fieldName]: { value: fieldValue, isValid: true } };
142
+
143
+ setForm({ ...form, ...newField });
144
+ }
145
+
146
+ const uploadVehicleDocument = (document: File, documentType: DocumentType) => {
147
+ if (document.size > 10000000) {
148
+ setSizeLimit(true);
149
+ return;
150
+ }
151
+
152
+ if (vehicle && document && documentType) {
153
+
154
+ // Utilisation d'un formData pour permettre le trasnfert de fichier vers l'API
155
+ let formData = new FormData();
156
+ formData.append("documentType", documentType);
157
+ // Ajouter la facture à FormData
158
+ formData.append('file', document);
159
+
160
+ // Appel du callback correspondant
161
+ if (onUploadDocument)
162
+ onUploadDocument(formData);
163
+ }
164
+ }
165
+
166
+ /**
167
+ *
168
+ * @param event L'upload des documents se fait directement lors du téléchargement
169
+ * @param docType
170
+ */
171
+ const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>, docType: DocumentType) => {
172
+ event.preventDefault();
173
+
174
+ if (event && event.target.files && event.target.files.length > 0 && docType) {
175
+ uploadVehicleDocument(event.target.files[0], docType);
176
+ }
177
+
178
+ };
179
+
180
+ const handleOnClickEdit = () => {
181
+
182
+ // On passe la fiche véhicule en mode édition
183
+ setLocalEditMode(true);
184
+ }
185
+
186
+ const handleOnChangeVehicleTire = (vehicleTire: VehicleTire, isValid: boolean) => {
187
+ setForm(prevForm => (
188
+ { ...prevForm, ['tireSize']: { ...prevForm['tireSize'], value: vehicleTire, isValid: isValid } }));
189
+ }
190
+
191
+ const handleOnClickDeleteVehicle = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
192
+ e.preventDefault();
193
+ setOpenConfirmVehicleDelete(true);
194
+ }
195
+
196
+ const handleDeleteDocument = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, documentId: string) => {
197
+ e.preventDefault();
198
+ setDocumentToDelete(documentId);
199
+ setOpenConfirmDocumentDelete(true);
200
+ }
201
+
202
+ const handleOnClickValidate = () => {
203
+
204
+ if (validateForm()) {
205
+
206
+ Logger.info(form.tireSize.value);
207
+
208
+ let query = {
209
+ currentMileage: form.currentMileage.value,
210
+ averageMileagePerYear: form.averageMileagePerYear.value,
211
+ tireWidth: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).width : undefined,
212
+ tireHeight: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).height : undefined,
213
+ tireDiameter: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).diameter : undefined,
214
+ tireSpeedIndex: form.tireSize.isValid && form.tireSize.value ? (form.tireSize.value as VehicleTire).speedIndex : undefined
215
+ }
216
+ Logger.info(query)
217
+
218
+ // Appel du callback correspondant
219
+ if (onUpdate)
220
+ onUpdate(form);
221
+ }
222
+ }
223
+
224
+ const handleOnClickCancel = () => {
225
+ initForm();
226
+ setLocalEditMode(false);
227
+ }
228
+
229
+ const handleCloseConfirmDocumentDelete = () => {
230
+ setOpenConfirmDocumentDelete(false);
231
+ setDocumentToDelete('');
232
+ }
233
+
234
+ const handleCloseConfirmVehicleDelete = () => {
235
+ setOpenConfirmVehicleDelete(false);
236
+ }
237
+
238
+ /**
239
+ *
240
+ */
241
+ const handleConfirmDocumentDelete = () => {
242
+ setOpenConfirmDocumentDelete(false);
243
+
244
+ if (vehicle && documentToDelete) {
245
+
246
+ // Appel du callback correspondant
247
+ if (onDeleteDocument)
248
+ onDeleteDocument(documentToDelete);
249
+ }
250
+ }
251
+
252
+ const handleConfirmVehicleDelete = () => {
253
+ setOpenConfirmVehicleDelete(false);
254
+
255
+ if (vehicle && onDelete) {
256
+
257
+ // Appel du callback correspondant
258
+ onDelete();
259
+ }
260
+ }
261
+
262
+ return (
263
+ <>
264
+ {vehicle &&
265
+ <Card variant='outlined' sx={{
266
+ maxWidth: fullwidth ? '80%' : 345,
267
+ backgroundColor: focused ? theme.palette.primary.light : 'white',
268
+ overflow: 'visible', mt: 4, pb: 1
269
+ }}
270
+ >
271
+ <img src={CarFigure} style={{
272
+ position: 'relative',
273
+ width: '40%',
274
+ top: '-25px',
275
+ left: '-15px',
276
+ zIndex: 200
277
+ }} alt='Icone Voiture'>
278
+ </img>
279
+
280
+ <MovaDigitalPassport digitalPassportIndex={vehicle.digitalPassportIndex} />
281
+
282
+ <CardContent sx={{ pt: 0, pb: 0 }}>
283
+ <Typography variant="h6" component="div" align="center" sx={{ mb: 1 }} color={darken(theme.palette.primary.main, 0.2)}>
284
+ {vehicle.brand && `${vehicle.brand} `}
285
+ {vehicle.model && `${vehicle.model} `}
286
+ {vehicle.version && `${vehicle.version}`}
287
+ </Typography>
288
+ <Grid container justifyContent="space-between">
289
+
290
+ <Grid item xs={12}>
291
+ <Typography variant="body1" color="text.primary">
292
+ <b>{formatFrenchVehiclePlate(vehicle.plate)}</b>
293
+ </Typography>
294
+ </Grid>
295
+
296
+ {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
297
+ <Grid item xs={8} >
298
+ <Typography variant="body1" color="text.secondary">
299
+ Km actuel :
300
+ </Typography>
301
+ </Grid>
302
+ <Grid item xs={4} sx={{ textAlign: 'right' }}>
303
+ <Typography variant="body1" color="text.secondary">
304
+ <b>{vehicle.currentMileage} km</b>
305
+ </Typography>
306
+ </Grid>
307
+ </Grid>}
308
+
309
+ {localEditMode && <Grid item xs={12}>
310
+ <TextField
311
+ label="Kilométrage actuel"
312
+ name="currentMileage"
313
+ variant="outlined"
314
+ type="number"
315
+ required
316
+ value={form.currentMileage.value}
317
+ onChange={(e) => handleInputChange(e)}
318
+ error={(Boolean(form.currentMileage.error))}
319
+ sx={{
320
+ width: '100%',
321
+ mt: 2,
322
+ '& input': { textTransform: 'uppercase' } // CSS pour forcer les majuscules dans l'input
323
+ }}
324
+ helperText={Boolean(form.currentMileage.error && form.currentMileage.value > 0)
325
+ ? form.currentMileage.error : "Sur votre tableau de bord 😉"}
326
+ />
327
+ </Grid>}
328
+
329
+ {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
330
+ <Grid item xs={8} >
331
+ <Typography variant="body1" color="text.secondary">
332
+ Km moyen annuel :
333
+ </Typography>
334
+ </Grid>
335
+ <Grid item xs={4} sx={{ textAlign: 'right' }}>
336
+ <Typography variant="body1" color="text.secondary">
337
+ <b>{vehicle.averageMileagePerYear} km</b>
338
+ </Typography>
339
+ </Grid>
340
+ </Grid>}
341
+
342
+ {localEditMode && <Grid item xs={12}>
343
+ <FormControl fullWidth margin="normal" error={Boolean(form.averageMileagePerYear.error)}>
344
+ <InputLabel id="averageMileagePerYear-label">Kilométrage moyen annuel</InputLabel>
345
+ <Select
346
+ labelId="averageMileagePerYear-label"
347
+ id="averageMileagePerYear"
348
+ name="averageMileagePerYear"
349
+ value={form.averageMileagePerYear.value ?
350
+ String(form.averageMileagePerYear.value) : ''}
351
+ onChange={e => handleSelectChange(e)}
352
+ label="Kilométrage moyen annuel"
353
+ >
354
+ <MenuItem value={5000}>5 000</MenuItem>
355
+ <MenuItem value={10000}>10 000</MenuItem>
356
+ <MenuItem value={15000}>15 000</MenuItem>
357
+ <MenuItem value={20000}>20 000</MenuItem>
358
+ <MenuItem value={25000}>25 000</MenuItem>
359
+ <MenuItem value={30000}>30 000</MenuItem>
360
+ <MenuItem value={50000}>50 000</MenuItem>
361
+ <MenuItem value={75000}>75 000</MenuItem>
362
+ <MenuItem value={100000}>100 000</MenuItem>
363
+ <MenuItem value={999999}>+100 000</MenuItem>
364
+ </Select>
365
+ <FormHelperText>{form.averageMileagePerYear.error}</FormHelperText>
366
+ </FormControl>
367
+ </Grid>}
368
+
369
+ {!localEditMode && <Grid container textAlign='justify' sx={{ pt: 2 }}>
370
+ <Grid item xs={6}>
371
+ <Typography variant="body1" color="text.secondary">
372
+ Pneumatiques :
373
+ </Typography>
374
+ </Grid>
375
+ <Grid item xs={6} sx={{ textAlign: 'right' }}>
376
+ <Typography variant="body1" color="text.secondary">
377
+ {isVehicleTireSizeDefined(vehicle) ? <b>{formatVehicleTire(vehicle.tireSize)}</b> : '-'}
378
+ </Typography>
379
+ </Grid>
380
+ </Grid>}
381
+
382
+ {localEditMode && <Grid item xs={12} sx={{ mt: 1 }}>
383
+ <MovaVehicleTireField
384
+ vehicleTire={form.tireSize.value}
385
+ onChangeVehicleTire={handleOnChangeVehicleTire}
386
+ />
387
+ </Grid>}
388
+
389
+ </Grid>
390
+
391
+ {!localEditMode && <>
392
+
393
+ <Grid item xs={12}>
394
+ <Typography variant="h6" component="div" align="center" sx={{ mt: 3, mb: 1 }} color={darken(theme.palette.primary.main, 0.2)}>
395
+ CARNET DU VÉHICULE
396
+ </Typography>
397
+ </Grid>
398
+
399
+ {vehicle.documents && vehicle.documents?.map((invoice, index) => (
400
+ <Grid container sx={{ justifyContent: 'space-between', alignItems: 'center' }} key={index + 1}>
401
+ <Grid item xs={11} key={(index + 1) * 50} sx={{ textAlign: 'left' }} >
402
+ <Tooltip title={invoice.originalFileName}>
403
+ <Link color={darken('#F29ABA', 0.2)} href={invoice.fileSignedUrl} target="_blank" rel="noopener">
404
+ <Typography variant="body1">
405
+ {invoice.fileName + ' ' + formatDateByCountryCode(invoice.creationDate, 'fr', DateFormatTypes.SHORT_FORMAT_DATE)}
406
+ </Typography>
407
+ </Link>
408
+ </Tooltip>
409
+ </Grid>
410
+ <Grid item xs={1} key={(index + 1) * 100} sx={{ textAlign: 'right' }}>
411
+ <IconButton disabled={!iAmOwner(invoice?.ownerId)} onClick={(e) => handleDeleteDocument(e, invoice?.id)}>
412
+ <CloseIcon />
413
+ </IconButton>
414
+ </Grid>
415
+ </Grid>
416
+ ))}
417
+
418
+ {/* * Les FACTURES du véhicule
419
+ {vehicle.documents && vehicle.documents?.filter(doc => doc.type === DocumentType.VEHICLE_MAINTENANCE_INVOICE)
420
+ .map((invoice, index) => (
421
+ <Grid container sx={{ justifyContent: 'space-between', alignItems: 'center' }} key={index+1}>
422
+ <Grid item xs={11} key={(index+1)*50} sx={{ textAlign: 'left' }} >
423
+ <Link color={darken('#F29ABA', 0.2)} href={invoice.fileSignedUrl} target="_blank" rel="noopener">
424
+ <Typography variant="body1">
425
+ Facture du {formatDateByCountryCode(invoice.creationDate, 'fr', DateFormatTypes.SHORT_FORMAT_DATE)}
426
+ </Typography>
427
+ </Link>
428
+ </Grid>
429
+ <Grid item xs={1} key={(index+1)*100} sx={{ textAlign: 'right' }}>
430
+ <IconButton onClick={(e) => handleDeleteDocument(e, invoice.id)}>
431
+ <CloseIcon />
432
+ </IconButton>
433
+ </Grid>
434
+ </Grid>
435
+ ))}
436
+
437
+ {vehicle.documents && vehicle.documents?.filter(doc => doc.type === DocumentType.VEHICLE_TIRE_PHOTO)
438
+ .map((tirePhoto, index) => (
439
+ <Grid container sx={{ justifyContent: 'space-between', alignItems: 'center' }} key={index+1}>
440
+ <Grid item xs={11} key={(index+1)*50} sx={{ textAlign: 'left' }} >
441
+ <Link color={darken('#F29ABA', 0.2)} href={tirePhoto.fileSignedUrl} target="_blank" rel="noopener">
442
+ <Typography variant="body1">
443
+ Photo pneu du {formatDateByCountryCode(tirePhoto.creationDate, 'fr', DateFormatTypes.SHORT_FORMAT_DATE)}
444
+ </Typography>
445
+ </Link>
446
+ </Grid>
447
+ <Grid item xs={1} key={(index+1)*100} sx={{ textAlign: 'right' }}>
448
+ <IconButton onClick={(e) => handleDeleteDocument(e, tirePhoto.id)}>
449
+ <CloseIcon />
450
+ </IconButton>
451
+ </Grid>
452
+ </Grid>
453
+ ))} */}
454
+
455
+ <Grid container >
456
+ <Grid item xs={12} sx={{ mt: 2, textAlign: 'center' }} >
457
+ <div>
458
+ <input
459
+ accept="image/*, application/pdf"
460
+ type="file"
461
+ style={{ display: 'none' }}
462
+ ref={invoiceInputRef}
463
+ id="raised-button-invoice"
464
+ onChange={(e) => handleFileChange(e, docTypeCurrent.current!)}
465
+ />
466
+ <Button size='large' disabled={currentUpload} onClick={() => setShowLinkedDocument(true)} component="span" variant="outlined" startIcon={<AttachFile />}
467
+ sx={{ alignItems: 'center', width: '90%', mt: 2, mb: 1, height: '50px', p: 1, color: darken(theme.palette.primary.main, 0.2) }}>
468
+
469
+ Ajouter un document
470
+
471
+ </Button>
472
+ {currentUpload && <Typography variant='body2' sx={{ animation: 'blink 1.5s infinite' }}>
473
+ Document en cours d'importation...
474
+ </Typography>}
475
+ {sizeLimit && <Typography
476
+ variant='body1'
477
+ sx={{ animation: 'blink 1.5s infinite' }}
478
+ color={theme.palette.warning.dark}
479
+ >Echec de l'importation car la taille du fichier dépasse 10Mo</Typography>}
480
+ {!sizeLimit && <Typography variant='body2'>
481
+ Taille maximale du fichier : 10Mo
482
+ </Typography>}
483
+ </div>
484
+ </Grid>
485
+ </Grid>
486
+ </>
487
+ }
488
+
489
+ </CardContent>
490
+
491
+ <CardActions sx={{ mt: 3, justifyContent: localEditMode ? 'center' : 'end' }}>
492
+ {!localEditMode &&
493
+ <>
494
+ <Button onClick={handleOnClickEdit} color="inherit" sx={{ width: '45%' }} variant='text'>
495
+ <EditIcon sx={{ mr: 1 }} />MODIFIER
496
+ </Button>
497
+ </>
498
+ }
499
+
500
+ {localEditMode &&
501
+ <>
502
+ <Button onClick={handleOnClickCancel} sx={{ width: '45%', color: theme.palette.text.secondary }} variant='text'>
503
+ <CancelIcon sx={{ mr: 1 }} />ANNULER
504
+ </Button>
505
+
506
+ <Button onClick={handleOnClickValidate} sx={{ width: '45%', color: darken(theme.palette.primary.main, 0.2) }} variant='text'>
507
+ <EditIcon sx={{ mr: 1 }} />VALIDER
508
+ </Button>
509
+ </>
510
+ }
511
+ </CardActions>
512
+
513
+ </Card>
514
+ }
515
+ {isShowLinkedDocument && <LinkedDocumentDialog
516
+ isVehicle={true}
517
+ isShowLinkedDocument={isShowLinkedDocument}
518
+ appType={appType}
519
+ toggleShowLinkedDocument={toggleShowLinkedDocument}
520
+ message={messageRGPD}
521
+ />}
522
+
523
+ {localEditMode && onDelete &&
524
+ <Button onClick={(e) => handleOnClickDeleteVehicle(e)} sx={{
525
+ width: '90', mt: 4, color: theme.palette.error.light,
526
+ borderColor: theme.palette.error.light
527
+ }} variant='outlined'>
528
+ Supprimer le véhicule
529
+ </Button>
530
+ }
531
+
532
+ <ConfirmationDialog
533
+ open={openConfirmDocumentDelete}
534
+ onClose={handleCloseConfirmDocumentDelete}
535
+ onConfirm={handleConfirmDocumentDelete}
536
+ message="Êtes-vous sûr de vouloir supprimer ce document ?"
537
+ />
538
+
539
+ <ConfirmationDialog
540
+ open={openConfirmVehicleDelete}
541
+ onClose={handleCloseConfirmVehicleDelete}
542
+ onConfirm={handleConfirmVehicleDelete}
543
+ message="Êtes-vous sûr de vouloir supprimer ce véhicule ?"
544
+ />
545
+ </>
546
+ );
547
+ }
548
+
549
+ export default VehicleFullCard;