@movalib/movalib-commons 1.59.14 → 1.59.16

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