@movalib/movalib-commons 1.55.4 → 1.55.6

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.
@@ -179,8 +179,35 @@ export class PLVComponent extends React.Component<PLVComponentProps> {
179
179
  }
180
180
  }
181
181
 
182
+
183
+
184
+ export class PLVComponentV2 extends React.Component<PLVComponentProps> {
185
+ render() {
186
+ return (
187
+ <div
188
+ className='printable-content'
189
+ style={{
190
+ width:
191
+ this.props.printSize === PrintSize.A4 ? '210mm' : this.props.printSize === PrintSize.A3 ? '297mm' : '0mm',
192
+ height:
193
+ this.props.printSize === PrintSize.A4 ? '297mm' : this.props.printSize === PrintSize.A3 ? '420mm' : '0mm',
194
+ }}
195
+ >
196
+ <Grid container>
197
+ <Grid item xs={12}>
198
+ <img src={this.props.url} style={{ display: 'block', width: '100%', height: '100%', objectFit: 'cover' }} />
199
+ </Grid>
200
+ </Grid>
201
+ </div>
202
+ );
203
+ }
204
+ }
205
+
182
206
  // CSS pour cacher le contenu à l'écran mais le rendre imprimable
183
207
  const css = `
208
+ body {
209
+ margin: 0;
210
+ }
184
211
  .highlight {
185
212
  background-color: #BCD46C; /* Couleur de surlignage */
186
213
  margin: 4px 4px; /* Espacement autour du texte surligné */
@@ -197,13 +224,21 @@ const css = `
197
224
  }
198
225
 
199
226
  .printable-content {
227
+ margin: 0;
228
+ padding: 0;
200
229
  visibility: hidden;
201
230
  position: absolute;
202
231
  left: -10000px;
203
232
  top: -10000px;
233
+
204
234
  }
205
235
  @media print {
236
+ body {
237
+ margin: 0;
238
+ }
206
239
  .printable-content {
240
+ margin: 0;
241
+ padding: 0;
207
242
  visibility: visible;
208
243
  position: static;
209
244
  }
@@ -20,19 +20,23 @@ import { useReactToPrint } from 'react-to-print';
20
20
  import { DownloadedQRCode } from '../../DownloadedQRCode';
21
21
  import QRCodeImage from '../../assets/images/leaf_yellow_small.png';
22
22
  import { flexCenter } from '../../helpers/Tools';
23
- import { PLVComponent, PrintSize } from './PLVComponent';
23
+ import { PDFDocument } from 'pdf-lib';
24
+ import { PLVComponentV2, PrintSize } from './PLVComponent';
25
+ import * as pdfjsLib from 'pdfjs-dist';
26
+ pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';
24
27
 
25
28
  type SelectChoice = null | 'A3' | 'A4' | 'QR_Headless' | 'QR_Google';
26
-
27
29
  export const QrCodePLVContainer = ({ data }: { data: string }) => {
28
30
  const [selectedChoice, setSelectedChoice] = useState<SelectChoice>(null);
31
+ const [urlA4, setUrlA4] = useState<string>('');
32
+ const [urlA3, setUrlA3] = useState<string>('');
29
33
 
30
34
  const qrCodeRef = useRef<HTMLDivElement>(null);
31
- const PLVrefA4 = useRef<PLVComponent>(null);
32
- const PLVrefA3 = useRef<PLVComponent>(null);
33
-
34
35
  const theme = useTheme();
35
-
36
+ const PLVrefA4 = useRef<PLVComponentV2>(null);
37
+ const PLVrefA3 = useRef<PLVComponentV2>(null);
38
+ //si sur l'impression des PLV en A4 ou A3 le Qrcode est flou,
39
+ //il faut modifier la width et height, imageSize du qrCodeOptions et mettre les mêmes valeurs que dans le optionQrcode de la fonction printPLV
36
40
  const qrCodeOptions: Options = useMemo(
37
41
  () => ({
38
42
  width: 300,
@@ -78,15 +82,95 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
78
82
  }
79
83
  }, [qrCode]);
80
84
 
81
- const printA4PLV = useReactToPrint({
82
- content: () => PLVrefA4.current,
83
- documentTitle: 'Movalib_PLV_A4',
84
- });
85
+ useEffect(() => {
86
+ const urlA4 = printPLV('A4').then((url) => {
87
+ setUrlA4(url);
88
+ });
89
+ const urlA3 = printPLV('A3').then((url) => {
90
+ setUrlA3(url);
91
+ });
92
+ }, [data]);
85
93
 
86
- const printA3PLV = useReactToPrint({
87
- content: () => PLVrefA3.current,
88
- documentTitle: 'Movalib_PLV_A3',
89
- });
94
+ async function printPLV(format: string) {
95
+ // Chemin du fichier PDF
96
+ const pdfUrl = `/Movalib_${format}.pdf`;
97
+ // Récupérer le fichier PDF depuis le serveur
98
+ const response = await fetch(pdfUrl);
99
+ const existingPdfBytes = await response.arrayBuffer();
100
+
101
+ // Charger le document PDF
102
+ const pdfDoc = await PDFDocument.load(existingPdfBytes);
103
+ // Convertir le Qrcode en Blob
104
+ const qrCodeBlob = await qrCode.getRawData("png");
105
+
106
+ // Convertir l'image QR code en un tableau de bytes
107
+ const qrImageBytes = await qrCodeBlob?.arrayBuffer();
108
+ // Intégrer l'image du QR code dans le PDF
109
+ const qrImage = await pdfDoc.embedPng(qrImageBytes!);
110
+
111
+ const pages = pdfDoc.getPages();
112
+ const firstPage = pages[0];
113
+ const { width, height } = firstPage.getSize();
114
+
115
+ let optionQrcode = {};
116
+ if(format === 'A3'){
117
+ optionQrcode = {
118
+ x: width - 427,
119
+ y: 88,
120
+ width: 349,
121
+ height: 349
122
+ }
123
+ } else {
124
+ optionQrcode = {
125
+ x: width - 303,
126
+ y: 54,
127
+ width: 245,
128
+ height: 245,
129
+ }
130
+ }
131
+ // AJouter le QR code à la première page du PDF
132
+ firstPage.drawImage(qrImage, optionQrcode);
133
+
134
+ // Enregistrer le PDF modifié en bytes
135
+ const modifiedPdfBytes = await pdfDoc.save();
136
+
137
+ // Convertir les bytes en Blob puis en URL
138
+ const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
139
+ const url = URL.createObjectURL(blob);
140
+
141
+ // étape nécesssaire pour utiliser reactToPrint pour pouvoir nommer le document
142
+ // reactToPrint fonctionne uniquement avec le HTML
143
+ // donc il faut convertir le PDF en image
144
+ // puis convertir l'image en URL
145
+ // et enfin integrer l'image dans le HTML via la balise <img>
146
+
147
+
148
+ // Convertir le PDF en image
149
+ const loadingTask = pdfjsLib.getDocument(url);
150
+ const pdf = await loadingTask.promise;
151
+
152
+ // Récupérer la première page
153
+ const page = await pdf.getPage(1);
154
+
155
+ // Créer un canvas pour afficher la page
156
+ const canvas = document.createElement('canvas');
157
+ const context = canvas.getContext('2d');
158
+
159
+ const viewport = page.getViewport({ scale: 1.5 });
160
+ canvas.width = viewport.width;
161
+ canvas.height = viewport.height;
162
+
163
+ // Rendu de la page dans le canvas
164
+ const renderContext = {
165
+ canvasContext: context!,
166
+ viewport: viewport,
167
+ };
168
+ await page.render(renderContext).promise;
169
+
170
+ // Convertir le canvas en URL d'image (data URL)
171
+ const imageUrl = canvas.toDataURL('image/png');
172
+ return imageUrl;
173
+ }
90
174
 
91
175
  const downloadQRCodeHeadless = useCallback(() => {
92
176
  qrCode.download({
@@ -134,6 +218,16 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
134
218
  const onChangeSelectedChoice: SelectProps<SelectChoice>['onChange'] = (e) => {
135
219
  setSelectedChoice(e.target.value as SelectChoice);
136
220
  };
221
+
222
+ const printA3PLV = useReactToPrint({
223
+ content: () => PLVrefA3.current,
224
+ documentTitle: 'Movalib_PLV_A3',
225
+ });
226
+
227
+ const printA4PLV = useReactToPrint({
228
+ content: () => PLVrefA4.current,
229
+ documentTitle: 'Movalib_PLV_A4',
230
+ });
137
231
 
138
232
  const onClickDownload = useMemo(() => {
139
233
  switch (selectedChoice) {
@@ -148,11 +242,11 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
148
242
  default:
149
243
  return () => {};
150
244
  }
151
- }, [selectedChoice, printA3PLV, printA4PLV, downloadQRCodeHeadless, downloadQrCodeWithCTA]);
245
+ }, [selectedChoice, downloadQRCodeHeadless, downloadQrCodeWithCTA, printA3PLV, printA4PLV]);
152
246
  return (
153
247
  <Box display='flex' flexDirection='column' alignItems='center' gap='24px'>
154
- <PLVComponent ref={PLVrefA4} url={data} printSize={PrintSize.A4} />
155
- <PLVComponent ref={PLVrefA3} url={data} printSize={PrintSize.A3} />
248
+ {urlA4 && <PLVComponentV2 ref={PLVrefA4} url={urlA4} printSize={PrintSize.A4} />}
249
+ {urlA3 &&<PLVComponentV2 ref={PLVrefA3} url={urlA3} printSize={PrintSize.A3} />}
156
250
 
157
251
  <Grid container justifyContent='center' alignItems='center'>
158
252
  <Grid item xs={7}>
@@ -165,8 +259,8 @@ export const QrCodePLVContainer = ({ data }: { data: string }) => {
165
259
  onChange={onChangeSelectedChoice}
166
260
  value={selectedChoice}
167
261
  >
168
- <MenuItem value={'A3'}>🧾&nbsp;&nbsp;PLV format A4</MenuItem>
169
- <MenuItem value={'A4'}>🧾&nbsp;&nbsp;PLV format A3</MenuItem>
262
+ <MenuItem value={'A4'}>🧾&nbsp;&nbsp;PLV format A4</MenuItem>
263
+ <MenuItem value={'A3'}>🧾&nbsp;&nbsp;PLV format A3</MenuItem>
170
264
  <MenuItem value={'QR_Google'}>QR Code format GoogleMyBusiness</MenuItem>
171
265
  <MenuItem value={'QR_Headless'}>QR Code seul</MenuItem>
172
266
  </Select>
@@ -7,7 +7,6 @@ export const API_BASE_URL = process.env.REACT_APP_API_URL || 'https://localhost:
7
7
  type APISuccess<T> = {
8
8
  success: true;
9
9
  data: T;
10
- location: string
11
10
  };
12
11
 
13
12
  type APIError = {
@@ -45,7 +44,6 @@ function handleResponse(response: Response): Promise<APIResponse<any>> {
45
44
  const contentType = response.headers.get("content-type");
46
45
  const isJson = contentType && contentType.includes("application/json");
47
46
  const dataPromise = isJson ? response.json() : response.text();
48
- const location = response.headers.get('location');
49
47
 
50
48
  return dataPromise.then(data => {
51
49
 
@@ -69,7 +67,7 @@ function handleResponse(response: Response): Promise<APIResponse<any>> {
69
67
  return { success: false, error: errorMsg };
70
68
  }
71
69
 
72
- return { success: true, data, location };
70
+ return { success: true, data };
73
71
  });
74
72
  }
75
73
 
@@ -0,0 +1,19 @@
1
+ export function openDialogPrint(url: string) {
2
+ // Créer un iframe pour charger le document Blob => url
3
+ const iframe = document.createElement('iframe');
4
+ iframe.style.position = 'absolute';
5
+ iframe.style.width = '0px';
6
+ iframe.style.height = '0px';
7
+ iframe.src = url;
8
+ document.body.appendChild(iframe);
9
+
10
+ // Ouvrir la boîte de dialogue d'impression lorsque l'iframe est chargée
11
+ iframe.onload = () => {
12
+ iframe?.contentWindow?.print();
13
+ };
14
+ // Supprimer l'iframe une fois lque la dialog est fermer
15
+ iframe.onclose = () => {
16
+ document.body.removeChild(iframe);
17
+ URL.revokeObjectURL(url);
18
+ }
19
+ }