@medicus.ai/medicus-report-pdf-generator 1.0.247 → 1.0.249

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.
@@ -0,0 +1,692 @@
1
+ @font-face {
2
+ font-family: 'Roboto';
3
+ font-style: normal;
4
+ font-weight: 100;
5
+ src: url('../fonts/Roboto-Light.ttf');
6
+ }
7
+
8
+ @font-face {
9
+ font-family: 'Roboto';
10
+ font-style: normal;
11
+ font-weight: 400;
12
+ src: url('../fonts/Roboto-Regular.ttf');
13
+ }
14
+
15
+ @font-face {
16
+ font-family: 'Roboto';
17
+ font-style: normal;
18
+ font-weight: bold;
19
+ src: url('../fonts/Roboto-Bold.ttf');
20
+ }
21
+
22
+
23
+ @font-face {
24
+ font-family: 'FrankRuhlLibre';
25
+ font-style: normal;
26
+ font-weight: 100;
27
+ src: url('../fonts/FrankRuhlLibre-Regular.ttf')
28
+ }
29
+
30
+ @font-face {
31
+ font-family: 'FrankRuhlLibre';
32
+ font-style: normal;
33
+ font-weight: 300;
34
+ src: url('../fonts/FrankRuhlLibre-Regular.ttf')
35
+ }
36
+
37
+ @font-face {
38
+ font-family: 'Frank Ruhl Libre';
39
+ font-style: normal;
40
+ font-weight: 600;
41
+ src: url('../fonts/FrankRuhlLibre-Bold.ttf')
42
+ }
43
+
44
+ @font-face {
45
+ font-family: 'Frank Ruhl Libre';
46
+ font-style: normal;
47
+ font-weight: bold;
48
+ src: url('../fonts/FrankRuhlLibre-Bold.ttf')
49
+ }
50
+
51
+ body {
52
+ margin: 0;
53
+ padding: 0;
54
+ /* background: url('../images/A4.png');*/
55
+ background-repeat: no-repeat;
56
+ background-size: 211mm;
57
+ background-position: center top;
58
+ box-sizing: border-box;
59
+ width: 210mm;
60
+ height: 297mm;
61
+ MARGIN: AUTO;
62
+ font-family: 'Open Sans', sans-serif;
63
+ background-color: #f8f8f3;
64
+ }
65
+
66
+ html {
67
+ background: unset;
68
+ height: 100%;
69
+ scroll-behavior: smooth;
70
+ }
71
+
72
+ body {
73
+ position: relative;
74
+ font-family: 'Open Sans', sans-serif;
75
+ }
76
+
77
+ header {
78
+ min-height: 38px;
79
+ padding: 3.143em 3.571em 0;
80
+ }
81
+
82
+ .content {
83
+ width: 100%;
84
+ float: left;
85
+ margin-top: 29px;
86
+ padding: 0px 36px 0 27px;
87
+ box-sizing: border-box;
88
+ direction: ltr;
89
+ }
90
+
91
+ img {
92
+ width: 100%
93
+ }
94
+
95
+ /*Header*/
96
+ .report-header {
97
+ color: rgba(51, 51, 51, 1);
98
+ font-size: 23.5px;
99
+ margin-bottom: 20px;
100
+ letter-spacing: -0.9px;
101
+ display: inline-block;
102
+ margin-top: 0;
103
+ font-family: Open Sans;
104
+ line-height: 34px;
105
+ letter-spacing: -0.9px;
106
+ }
107
+
108
+ .report-logo {
109
+ display: inline-block;
110
+ float: left;
111
+ margin-right: 6px;
112
+ }
113
+
114
+ .report-logo img {
115
+ width: 84px;
116
+ display: inline-block;
117
+ margin-left: 6px;
118
+ }
119
+
120
+ .avatar-img {
121
+ width: 113px;
122
+ display: inline-block;
123
+ float: left;
124
+ margin-right: 10px;
125
+ }
126
+
127
+ .avata-info {
128
+ float: left;
129
+ margin-top: 30px;
130
+ }
131
+
132
+ .avatar-title {
133
+ font-family: 'Roboto';
134
+ font-size: 17.5px;
135
+ }
136
+
137
+ .hero-title {
138
+ color: #005651;
139
+ font-family: 'Frank Ruhl Libre';
140
+ font-size: 22px;
141
+ }
142
+
143
+ .avatar-main-info {
144
+ float: left;
145
+ width: 39%;
146
+ }
147
+
148
+ .avatar-desc {
149
+ width: 61%;
150
+ float: left;
151
+ font-family: 'Roboto';
152
+ font-size: 12px;
153
+ line-height: 14px;
154
+ margin-top: -5px;
155
+ color: rgba(2, 84, 80, 1);
156
+ padding-left: 1%;
157
+ box-sizing: border-box;
158
+ }
159
+
160
+ .avatar-desc p:first-child {
161
+ margin-bottom: 27px;
162
+ display: block
163
+ }
164
+
165
+ .super-power-section {
166
+ float: left;
167
+ width: 100%;
168
+ margin-top: 12px;
169
+ }
170
+
171
+ .single-super-power {
172
+ float: left;
173
+ width: 28.5%;
174
+ }
175
+
176
+ .avatar-td-1 {
177
+ font-size: 12px;
178
+ float: left;
179
+ width: 63%;
180
+ color: #3B3B3B;
181
+ }
182
+
183
+ .avarat-td-img {
184
+ float: left;
185
+ margin-right: 14px;
186
+ width: 30px;
187
+ }
188
+
189
+ .avarat-td-img img {
190
+ margin-top: 11px;
191
+ }
192
+
193
+ .super-power-section .single-super-power:nth-child(2) {
194
+ width: 37%;
195
+ }
196
+
197
+ .super-power-section .single-super-power:nth-child(3) .avatar-td-1 {
198
+ width: 78%
199
+ }
200
+
201
+ .avatar-td-1 strong {
202
+ font-size: 15px;
203
+ display: inline-block;
204
+ padding-bottom: 3px;
205
+ color: #025450;
206
+ }
207
+
208
+ /*personal details*/
209
+ .first-section-scores {
210
+ margin-top: 33px;
211
+ float: left;
212
+ }
213
+
214
+ .pdf-container {
215
+ margin-left: auto !important;
216
+ margin-right: auto !important;
217
+ }
218
+
219
+ .closer-look-container {
220
+ padding: 0px;
221
+ }
222
+
223
+ .closer-look-body {
224
+ overflow: hidden;
225
+ padding: 0px;
226
+ }
227
+
228
+ .closer-look-left {
229
+ width: 28%;
230
+ }
231
+
232
+ .closer-look-left .closer-loook-part:nth-child(2) .closer-look-table-img,
233
+ .closer-look-left .closer-loook-part:last-child .closer-look-table-img{
234
+ vertical-align: top;
235
+ }
236
+ .closer-look-right {
237
+ width: 53.3%;
238
+ }
239
+
240
+ .closer-look-middle {
241
+ width: 18.7%;
242
+ margin-top: 18px;
243
+ background: url(../images/middle_arrows_image.png);
244
+ background-repeat: no-repeat;
245
+ background-size: cover;
246
+ box-sizing: border-box;
247
+ height: 229px;
248
+ border-right: 8px solid #f8f8f3;
249
+ }
250
+
251
+ .closer-look-middle img {
252
+ width: 100%;
253
+ display: none;
254
+ }
255
+
256
+ .closer-look-title {
257
+ font-family: 'Frank Ruhl Libre';
258
+ font-style: normal;
259
+ font-weight: 700;
260
+ font-size: 18.3px;
261
+ line-height: 25px;
262
+ color: #025450;
263
+ margin-bottom: 20px;
264
+ }
265
+
266
+ .closer-look-table-img, .closer-look-details {
267
+ display: inline-block;
268
+ }
269
+
270
+ .closer-look-details h2 {
271
+ font-family: 'Frank Ruhl Libre';
272
+ font-style: normal;
273
+ font-weight: 700;
274
+ font-size: 15px;
275
+ color: #000000;
276
+ margin: 0;
277
+ }
278
+
279
+ .closer-look-example {
280
+ font-family: 'Roboto';
281
+ font-style: normal;
282
+ font-weight: 400;
283
+ font-size: 11px;
284
+ line-height: 17px;
285
+ color: #676767;
286
+ }
287
+ .de .closer-look-example{
288
+ font-size: 10px;
289
+ }
290
+
291
+ .closer-look-table-img {
292
+ width: 59px;
293
+ margin-right: 16px;
294
+ vertical-align: middle;
295
+ }
296
+
297
+ .closer-look-table-img img {
298
+ width: 100%
299
+ }
300
+
301
+ .closer-loook-part {
302
+ margin-bottom: 18px;
303
+ }
304
+
305
+ .closer-look-left, .closer-look-middle, .closer-look-right {
306
+ float: left;
307
+ }
308
+
309
+ .sanusx-score-section .meter-body {
310
+ overflow: hidden;
311
+ padding: 17px 15px 10px 15px;
312
+ background: #FFFFFF;
313
+ box-shadow: 0px 1px 2px 1px rgb(0 0 0 / 4%);
314
+ border-radius: 8px;
315
+ margin: 19px 0px 0px 0px;
316
+ box-sizing: border-box
317
+ }
318
+
319
+ .sanusx-score-section .meter-body:last-child {
320
+ margin-top: 11px;
321
+ }
322
+
323
+ .speedometer-container svg {
324
+ width: 118%;
325
+ margin-top: -22px;
326
+ overflow: visible;
327
+ }
328
+
329
+ .speedometer-container img {
330
+ width: 100%;
331
+ }
332
+
333
+ .score-circle {
334
+ width: 23%;
335
+ float: left;
336
+ box-sizing: border-box;
337
+ margin-right: 5%;
338
+ }
339
+
340
+ .speedometer-circle {
341
+ position: relative
342
+ }
343
+
344
+ .speedometer-container {
345
+ text-align: center;
346
+ display: inline-block;
347
+ width: 100%;
348
+ position: relative;
349
+ }
350
+
351
+ .needle-container {
352
+ position: absolute;
353
+ right: 0;
354
+ top: 18px;
355
+ left: 0;
356
+ height: 60px;
357
+ width: 70px;
358
+ margin-left: 10px;
359
+ margin-right: 10px;
360
+ margin-top: 0;
361
+ }
362
+
363
+ .needle-container img {
364
+ width: 18px;
365
+ position: absolute;
366
+ bottom: 0;
367
+ display: block;
368
+ vertical-align: middle;
369
+ max-width: 100%;
370
+ background-color: transparent;
371
+ }
372
+
373
+ .speedometer-value {
374
+ z-index: 5;
375
+ top: 24px;
376
+ position: absolute;
377
+ margin-left: auto;
378
+ margin-right: auto;
379
+ left: 0;
380
+ right: 0px;
381
+ text-align: center;
382
+ }
383
+
384
+ span.speedometer-value-down {
385
+ color: #D8D8D8;
386
+ font-size: 11px;
387
+ font-weight: 300;
388
+ font-stretch: normal;
389
+ font-style: normal;
390
+ line-height: normal;
391
+ letter-spacing: -0.34px;
392
+ text-align: center;
393
+ margin-top: -1px;
394
+ display: block;
395
+ }
396
+
397
+ .meter-needle.ui.image {
398
+ width: 12px !important;
399
+ position: absolute;
400
+ bottom: 0;
401
+ height: auto !important;
402
+ }
403
+
404
+ .score-details {
405
+ width: 70%;
406
+ float: left;
407
+ }
408
+
409
+ .score-description {
410
+ font-family: 'Roboto';
411
+ font-style: normal;
412
+ font-weight: 400;
413
+ font-size: 11.5px;
414
+ line-height: 16px;
415
+ color: #676767;
416
+ }
417
+
418
+ .score-header {
419
+ font-family: 'Frank Ruhl Libre';
420
+ font-style: normal;
421
+ font-weight: 700;
422
+ font-size: 14px;
423
+ line-height: 115%;
424
+ color: #333333;
425
+ margin-bottom: 7px
426
+ }
427
+
428
+ .closer-look-details {
429
+ width: 53%;
430
+ }
431
+
432
+ /*predictions-section*/
433
+ .predictions-section {
434
+ float: left;
435
+ width: 100%;
436
+ }
437
+
438
+ .predictions-title {
439
+ font-family: 'Frank Ruhl Libre';
440
+ font-weight: bold;
441
+ font-size: 18.5px;
442
+ color: #025450;
443
+ margin-bottom: 7px;
444
+ }
445
+
446
+ .predictions-desc {
447
+ font-family: 'Roboto';
448
+ font-size: 13.3px;
449
+ margin-bottom: 15px;
450
+ }
451
+
452
+ .predictions-body {
453
+ float: left;
454
+ width: 100%;
455
+ position: relative;
456
+ }
457
+
458
+ .prediction-component {
459
+ width: 32.66%;
460
+ float: left;
461
+ margin-right: 1%;
462
+ background: #fff;
463
+ border-radius: 7px;
464
+ box-shadow: 0px 1px 1px 1px rgb(0 0 0 / 4%);
465
+ border-top: 6px solid rgba(36, 187, 96, 1);
466
+ min-height: 106px;
467
+ }
468
+
469
+ .de .prediction-component {
470
+ min-height: 116px;
471
+ }
472
+
473
+ .predictions-body .prediction-component.prediction-wrong {
474
+ border-color: grey
475
+ }
476
+
477
+
478
+ .predictions-body .prediction-component:last-child {
479
+ margin-right: 0;
480
+ }
481
+
482
+ .prediction-sub-image {
483
+ width: 20.7%;
484
+ text-align: center;
485
+ float: left;
486
+ margin-right: 14px;
487
+ }
488
+
489
+ .prediction-des-container {
490
+ width: 72%;
491
+ float: left;
492
+ }
493
+
494
+ .prediction-sub-result {
495
+ padding: 8px 6px;
496
+ box-sizing: border-box;
497
+ font-family: 'Roboto';
498
+ font-size: 10px;
499
+ color: #025450;
500
+ background: #CBE3BF;
501
+ float: left;
502
+ border-radius: 4px;
503
+ }
504
+
505
+ .prediction-component.prediction-wrong .prediction-sub-result {
506
+ background: #E9E8D8
507
+ }
508
+
509
+ .prediction-component.prediction-wrong .prediction-sub-result img {
510
+ opacity: 0;
511
+ }
512
+
513
+ .prediction-sub-result img {
514
+ width: 10px;
515
+ margin-right: 6px;
516
+ float: left;
517
+ margin-top: 8px;
518
+ }
519
+
520
+ .prediction-sub-result div {
521
+ float: left;
522
+ width: 88%;
523
+ }
524
+
525
+ .prediction-container {
526
+ padding: 12px 6px 9px 10px;
527
+ width: 100%;
528
+ box-sizing: border-box;
529
+ float: left;
530
+ }
531
+
532
+ .prediction-sub-title {
533
+ font-family: 'Roboto';
534
+ color: #676767;
535
+ font-size: 9.2px;
536
+ margin-bottom: 3px;
537
+ }
538
+
539
+ .prediction-sub-desc {
540
+ color: #025450;
541
+ font-family: 'Frank Ruhl Libre';
542
+ font-weight: bold;
543
+ line-height: 1;
544
+ font-size: 14px;
545
+ margin-bottom: 4px;
546
+ }
547
+
548
+ /* Recommendations */
549
+ .recommendations-section {
550
+ float: left;
551
+ width: 100%
552
+ }
553
+
554
+ .recommendations-title {
555
+ color: rgba(2, 84, 80, 1);
556
+ font-family: 'Frank Ruhl Libre';
557
+ margin-top: 22px;
558
+ font-weight: bold;
559
+ font-size: 18.4px;
560
+ margin-bottom: 10px;
561
+ }
562
+
563
+ .insight-container {
564
+ width: 32.66%;
565
+ float: left;
566
+ margin-right: 1%;
567
+ padding: 12px 11px;
568
+ box-sizing: border-box;
569
+ box-shadow: 0px 1px 2px 1px rgb(0 0 0 / 4%);
570
+ background: #fff;
571
+ min-height: 172px;
572
+ border-radius: 5px
573
+ }
574
+
575
+ .de .insight-container {
576
+ min-height: 156px;
577
+ }
578
+
579
+ .tips-section .insight-container:last-child {
580
+ margin-right: 0
581
+ }
582
+
583
+ .chunk-image {
584
+ float: left;
585
+ }
586
+
587
+ .insight-container img {
588
+ width: 46px
589
+ }
590
+
591
+ .tip-score-section {
592
+ float: left;
593
+ width: 72%;
594
+ padding-left: 0%;
595
+ box-sizing: border-box;
596
+ }
597
+
598
+ .top-tip-section {
599
+ float: left;
600
+ width: 100%;
601
+ margin-bottom: 2px;
602
+ }
603
+
604
+ .tips-text {
605
+ color: #676767;
606
+ font-size: 10.5px;
607
+ font-family: 'Roboto';
608
+ width: 100%;
609
+ float: left;
610
+ line-height: 14px;
611
+ }
612
+
613
+ .tip-title {
614
+ color: #025450;
615
+ font-family: 'Frank Ruhl Libre';
616
+ font-size: 15px;
617
+ font-weight: bold;
618
+ margin-bottom: 8px;
619
+ }
620
+
621
+ .score-lines {
622
+ width: 88%;
623
+ float: left;
624
+ clear: both;
625
+ margin-bottom: 2px;
626
+ }
627
+
628
+ .score-line {
629
+ width: 17%;
630
+ height: 4px;
631
+ float: left;
632
+ margin-right: 5px;
633
+ background: rgba(248, 248, 243, 1);
634
+ border-radius: 18px;
635
+ }
636
+
637
+ .score-lines .score-line:last-child {
638
+ margin-right: 0
639
+ }
640
+
641
+ .score-sum {
642
+ color: #025450;
643
+ font-family: 'Roboto';
644
+ font-size: 9px;
645
+ display: block;
646
+ float: left;
647
+ }
648
+
649
+ .score-lines .score-line.highlighted {
650
+ background: rgba(204, 221, 220, 1)
651
+ }
652
+
653
+ .insight-container.body .score-lines .score-line.highlighted {
654
+ background: #F58F90
655
+ }
656
+
657
+ .insight-container.mind .score-lines .score-line.highlighted {
658
+ background: #80A9A7
659
+ }
660
+
661
+ /*Footer*/
662
+
663
+ .print-page-footer {
664
+ width: 100%;
665
+ float: left;
666
+ margin-top: 25px;
667
+ padding: 0;
668
+ box-sizing: border-box;
669
+ }
670
+
671
+ .de .print-page-footer {
672
+ margin-top: 10px
673
+ }
674
+
675
+ .footer-icon {
676
+ width: 39px;
677
+ float: left;
678
+ margin-top: 9px
679
+ }
680
+
681
+ .footer-content {
682
+ float: left;
683
+ width: calc(100% - 43px);
684
+ font-size: 8.5px;
685
+ color: rgba(103, 103, 103, 1);
686
+ font-family: 'Roboto';
687
+ font-weight: 400;
688
+ font-style: italic;
689
+ padding-left: 5px;
690
+ box-sizing: border-box;
691
+ line-height: 13px;
692
+ }
package/index.js CHANGED
@@ -93,9 +93,7 @@ module.exports = {
93
93
  let LOGS = '';
94
94
  let LOGS_FILE_PATH = __dirname + '/output/LOGS.txt';
95
95
  let PDF_FILE_PATH = __dirname + '/output/nasco-sample.pdf';
96
- if (reportData.client === 'sanusx') {
97
- PDF_FILE_PATH = __dirname + '/output/sanusx-sample.pdf';
98
- }
96
+
99
97
  let mailConfig = {
100
98
  host: reportData.host,
101
99
  port: reportData.port,
@@ -135,21 +133,93 @@ module.exports = {
135
133
  LOGS += '3: save decoded json' + '\n' + '=============' + '\n';
136
134
  LOGS += decodedJSON + '\n\n\n';
137
135
  }
138
- let html
139
- if (reportData.client === 'sanusx') {
140
- html = await generateHTMLSanusXReport(decodedJSON, isDebugging, reportData.client, reportData.language);
141
- } else {
142
- html = await generateHTMLWellbeingReport(decodedJSON, isDebugging, reportData.client, reportData.language);
143
- }
136
+ let html = await generateHTMLWellbeingReport(decodedJSON, isDebugging, reportData.client, reportData.language);
144
137
 
145
- console.log("shouldSendEmail", shouldSendEmail)
146
138
  // 3: save PDF buffer
147
- let fileBuffer
148
- if (reportData.client === 'sanusx') {
149
- fileBuffer = await generateSanusXReport(html);
139
+ let fileBuffer = await generatePDFWellbeingReport(html);
140
+ if (isDebugging) {
141
+ console.log('3: save PDF buffer')
142
+ LOGS += '3: save PDF buffer' + '\n' + '=============' + '\n';
143
+ LOGS += fileBuffer + '\n\n\n';
144
+ }
145
+
146
+ console.log("PDF_FILE_PATH", PDF_FILE_PATH)
147
+ fs.writeFileSync(PDF_FILE_PATH, fileBuffer, 'utf8');
148
+
149
+ // 4: save encoded base64
150
+ const base64data = Buffer.from(fileBuffer, 'utf8').toString('base64');
151
+ if (isDebugging) {
152
+ console.log('4: save encoded base64');
153
+ LOGS += '4: save encoded base64' + '\n' + '=============' + '\n';
154
+ LOGS += base64data + '\n\n\n';
155
+ }
156
+
157
+
158
+ // 5: save logs to file
159
+ fs.writeFileSync(LOGS_FILE_PATH, LOGS, 'utf8');
160
+ if (isDebugging) {
161
+ console.log('5: save logs to file');
162
+ }
163
+
164
+ if (isDownloadable) {
165
+ return fileBuffer;
150
166
  } else {
151
- fileBuffer = await generatePDFWellbeingReport(html);
167
+ if (shouldSendEmail)
168
+ return await sendNascoEmail(decodedJSON, PDF_FILE_PATH, mailConfig, reportData.client)
169
+ else
170
+ return base64data;
152
171
  }
172
+ },
173
+ generateSanuxPDF: async (data, isDebugging, isDownloadable, shouldSendEmail) => {
174
+ let reportData = JSON.parse(data)
175
+ let base64Object = reportData.data
176
+ let LOGS = '';
177
+ let LOGS_FILE_PATH = __dirname + '/output/LOGS.txt';
178
+ let PDF_FILE_PATH = __dirname + '/output/sanusx-sample.pdf';
179
+
180
+ let mailConfig = {
181
+ host: reportData.host,
182
+ port: reportData.port,
183
+ authUser: reportData.authUser,
184
+ authPass: reportData.authPass,
185
+ sendFromEmail: reportData.sendFromEmail,
186
+ secure: reportData.secure
187
+ }
188
+ if (isDebugging) {
189
+ if (fs.existsSync(LOGS_FILE_PATH)) {
190
+ fs.unlinkSync(LOGS_FILE_PATH);
191
+ }
192
+
193
+ if (fs.existsSync(PDF_FILE_PATH)) {
194
+ fs.unlinkSync(PDF_FILE_PATH);
195
+ }
196
+ }
197
+
198
+ // 1: save decoded json string
199
+ if (isDebugging) {
200
+ console.log('2: save json string');
201
+ LOGS += '2: save json string' + '\n' + '=============' + '\n';
202
+ LOGS += base64Object + '\n\n\n';
203
+ }
204
+ // 2: save decoded json string
205
+ const json = Buffer.from(base64Object, 'base64').toString('utf8');
206
+ if (isDebugging) {
207
+ console.log('2: save decoded json string');
208
+ LOGS += '2: save decoded json string' + '\n' + '=============' + '\n';
209
+ LOGS += json + '\n\n\n';
210
+ }
211
+
212
+ // 3: save decoded json
213
+ const decodedJSON = JSON.parse(json);
214
+ if (isDebugging) {
215
+ console.log('3: save decoded json string')
216
+ LOGS += '3: save decoded json' + '\n' + '=============' + '\n';
217
+ LOGS += decodedJSON + '\n\n\n';
218
+ }
219
+ let html = await generateHTMLSanusXReport(decodedJSON, isDebugging, reportData.client, reportData.language);
220
+
221
+ // 3: save PDF buffer
222
+ let fileBuffer = await generateSanusXReport(html);
153
223
  if (isDebugging) {
154
224
  console.log('3: save PDF buffer')
155
225
  LOGS += '3: save PDF buffer' + '\n' + '=============' + '\n';
@@ -10,14 +10,10 @@ const puppeteer = require("puppeteer");
10
10
 
11
11
 
12
12
  var localeService = new LocaleService(i18n);
13
- let isRTL = false;
14
13
 
15
14
 
16
15
  let OUT_FILE = 'output/sanusx-pdf.html';
17
16
  let Pdf_file = '';
18
- const appDir = path.dirname(require.main.filename);
19
-
20
-
21
17
  let debug = true;
22
18
 
23
19
  let debugLog = (val1, val2 = "") => {
@@ -85,12 +81,6 @@ let generateHTMLSanusXReport = async (data, isDebugging, clientName, language) =
85
81
  language = 'en'
86
82
  }
87
83
 
88
- let isRtl = false;
89
- if (language.indexOf('ar') !== -1) {
90
- language = 'ar-SA';
91
- isRtl = true;
92
- }
93
-
94
84
 
95
85
  let client = clientName ? clientName : 'default'
96
86
  let defaultConfig = require('../config/sanusx.json');
@@ -101,8 +91,7 @@ let generateHTMLSanusXReport = async (data, isDebugging, clientName, language) =
101
91
  debugLog("pdf language:", language);
102
92
 
103
93
  /*choose the right template*/
104
- let html = !isRtl ? fs.readFileSync(path.resolve(__dirname + '/../templates/sanusx/ltr_no_pages.html'), 'utf8') :
105
- fs.readFileSync(path.resolve(__dirname + '/../templates/sanusx/rtl_no_pages.html'), 'utf8');
94
+ let html = fs.readFileSync(path.resolve(__dirname + '/../templates/sanusx/ltr_no_pages.html'), 'utf8');
106
95
 
107
96
  let headerTemplate = fs.readFileSync(path.resolve(__dirname + '/../templates/sanusx/blocks/header.html'), 'utf8');
108
97
 
@@ -153,20 +142,179 @@ let generateHTMLSanusXReport = async (data, isDebugging, clientName, language) =
153
142
  .replace("{{avatarDesc1}}", localeService.t(avatar + 'Desc'))
154
143
  .replace("{{avatarDesc2}}", localeService.t(avatar + 'Details'))
155
144
 
145
+ /* Super powers section */
146
+ superPowerSectionTemplate = superPowerSectionTemplate.replace("{{superpowerImage}}", path.resolve(__dirname + '/../assets/sanusx/images/superpower_icon.png'))
147
+ .replace("{{SuperPowerTitle}}", localeService.t('SUPERPOWER'))
148
+ .replace("{{SuperPowerMsg}}", localeService.t(avatar + 'SUPERPOWER-msg'))
149
+ .replace("{{strengthImage}}", path.resolve(__dirname + '/../assets/sanusx/images/strength_icon.png'))
150
+ .replace("{{StrengthTitle}}", localeService.t('STRENGTH'))
151
+ .replace("{{StrengthMsg}}", localeService.t('STRENGTH-msg'))
152
+
153
+ .replace("{{weaknessImage}}", path.resolve(__dirname + '/../assets/sanusx/images/weakness_icon.png'))
154
+ .replace("{{WeaknessTitle}}", localeService.t('WEAKNESS'))
155
+ .replace("{{WeaknessMsg}}", localeService.t('WEAKNESS-msg'))
156
+ .replace("{{highestElementName}}", highestElementName[0].name)
157
+ .replace("{{lowestElementScore}}", lowestElementScore.name)
158
+
159
+ /* Personal Details section */
160
+ let physicalScore = data.calculation.physicalScore.toFixed(1)
161
+ let physicalAmount = ((physicalScore > 40 && physicalScore < 70) ? 255 : (physicalScore >= 70) ? 253 : 214);
162
+ let physicalColor = (physicalScore > 40 && physicalScore < 70) ? second_level_color : (physicalScore >= 70) ? third_level_color : first_level_color;
163
+
164
+ const rotatePhysicalAmount = (physicalScore / 100) * physicalAmount;
165
+ let psychologicalScore = data.calculation.psychologicalScore.toFixed(1)
166
+ let psychologicalAmount = ((psychologicalScore > 40 && psychologicalScore < 70) ? 255 : (psychologicalScore >= 70) ? 253 : 214);
167
+ let psychologicalColor = (psychologicalScore > 40 && psychologicalScore < 70) ? second_level_color : (psychologicalScore >= 70) ? third_level_color : first_level_color;
168
+ const rotatePsychologicalAmount = (psychologicalScore / 100) * psychologicalAmount;
169
+ let psychologicalScoreImage = (psychologicalScore > 40 && psychologicalScore < 70) ? "med" : (psychologicalScore >= 70) ? 'high' : 'low';
170
+ let physicalScoreImage = (physicalScore > 40 && physicalScore < 70) ? "med" : (physicalScore >= 70) ? 'high' : 'low';
171
+
172
+
173
+ personalDetailsSectionTemplate = personalDetailsSectionTemplate.replace("{{physicalScore}}", parseFloat(Math.floor(data.calculation.physicalScore)))
174
+ .replace("{{physicalScoreDecimalPart}}", parseFloat((data.calculation.physicalScore).toFixed(1) % 1).toFixed(1).substring(1))
175
+ .replace("{{physicalScoreStatement}}", data.calculation.physicalScoreStatement)
176
+ .replace("{{PhysicalWord}}", localeService.t('physicalScore'))
177
+ .replace(/{{rotatePhysicalAmount}}/gi, rotatePhysicalAmount)
178
+ .replace(/{{physicalColor}}/gi, physicalColor)
179
+ .replace("{{psychologicalScore}}", Math.floor(data.calculation.psychologicalScore))
180
+ .replace("{{psychologicalScoreDecimalPart}}", parseFloat((data.calculation.psychologicalScore).toFixed(1) % 1).toFixed(1).substring(1))
181
+ .replace("{{psychologicalWord}}", localeService.t('psychologicalScore'))
182
+ .replace("{{psychologicalScoreStatement}}", data.calculation.psychologicalScoreStatement)
183
+ .replace(/{{rotatePsychologicalAmount}}/gi, rotatePsychologicalAmount)
184
+ .replace("{{psychologicalColor}}", psychologicalColor)
185
+ .replace("{{tigerIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/tiger_icon.png'))
186
+ .replace("{{monkeyIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/monkey_icon.png'))
187
+ .replace("{{owlIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/owl_icon.png'))
188
+ .replace("{{middleArrowsImage}}", path.resolve(__dirname + '/../assets/sanusx/images/middle_arrows_image.png'))
189
+ .replace("{{physicalScoreImage}}", path.resolve(__dirname + '/../assets/sanusx/images/' + physicalScoreImage + '-segments-circle-SanusX.png'))
190
+ .replace("{{psychologicalScoreImage}}", path.resolve(__dirname + '/../assets/sanusx/images/' + psychologicalScoreImage + '-segments-circle-SanusX.png'))
191
+ .replaceAll("{{indicatorImage}}", path.resolve(__dirname + '/../assets/sanusx/images/indicator.png'))
192
+ .replace(/{{physicalColor}}/gi, physicalColor)
193
+ .replace("{{psychologicalColor}}", psychologicalColor)
194
+ .replace("{{closerLookTitle}}", localeService.t('closerLook'))
195
+ .replace("{{BodyTitle}}", localeService.t('body'))
196
+ .replace("{{MindTitle}}", localeService.t('mind'))
197
+ .replace("{{LifeStyleTitle}}", localeService.t('lifeStyle'))
198
+ .replace("{{LifeStyleExample}}", localeService.t('lifestyleExample'))
199
+ .replace("{{MindExample}}", localeService.t('mindExample'))
200
+ .replace("{{BodyExample}}", localeService.t('bodyExample'))
201
+
202
+ let bodyIcon = path.resolve(__dirname + '/../assets/sanusx/images/right_icon.png')
203
+ let lifestyleIcon = path.resolve(__dirname + '/../assets/sanusx/images/wrong_icon.png')
204
+ let mindIcon = path.resolve(__dirname + '/../assets/sanusx/images/right_icon.png')
205
+
206
+ let predictedBodyMsg, predictedLifestyleMsg, predictedHeartMsg = ''
207
+ let finalScore = 0;
208
+ if (!data.PartScoresHighestValues.body[0].isPredictiveElement) {
209
+ predictedBodyMsg = localeService.t('youPredictedWrong').replace("{$value}", data.PartScoresHighestValues.body[0].name)
210
+ } else {
211
+ finalScore++
212
+ predictedBodyMsg = localeService.t('youPredictedRight').replace("{$value}", data.PartScoresHighestValues.body[0].name)
213
+ }
214
+ if (!data.PartScoresHighestValues.mind[0].isPredictiveElement) {
215
+ predictedHeartMsg = localeService.t('youPredictedWrong').replace("{$value}", data.PartScoresHighestValues.mind[0].name)
216
+ } else {
217
+ finalScore++
218
+ predictedHeartMsg = localeService.t('youPredictedRight').replace("{$value}", data.PartScoresHighestValues.mind[0].name)
219
+ }
220
+ if (!data.PartScoresHighestValues.lifeStyle[0].isPredictiveElement) {
221
+ predictedLifestyleMsg = localeService.t('youPredictedWrong').replace("{$value}", data.PartScoresHighestValues.lifeStyle[0].name)
222
+ } else {
223
+ finalScore++
224
+ predictedLifestyleMsg = localeService.t('youPredictedRight').replace("{$value}", data.PartScoresHighestValues.lifeStyle[0].name)
225
+ }
226
+
227
+
228
+ let predictionsDesc = localeService.t('predictionsDesc').replace('{$val}', finalScore)
229
+ predictionsSectionTemplate = predictionsSectionTemplate
230
+ .replace("{{predictionsTitle}}", localeService.t('predictionsTitle'))
231
+ .replace("{{predictionsDesc}}", predictionsDesc)
232
+ .replace("{{bodyResultSanusX}}", localeService.t('bodyResultSanusX'))
233
+ .replace("{{lifestyleResultSanusX}}", localeService.t('lifeStyleResultSanusX'))
234
+ .replace("{{mindResultSanusX}}", localeService.t('mindResultSanusX'))
235
+ .replace("{{bodyResultPred}}", data.PartScoresHighestValues.body[0].name)
236
+ .replace("{{lifestyleResultPred}}", data.PartScoresHighestValues.lifeStyle[0].name)
237
+ .replace("{{mindResultPred}}", data.PartScoresHighestValues.mind[0].name)
238
+ .replace("{{forkIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/fork_icon.png'))
239
+ .replace("{{heartIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/heart_icon.png'))
240
+ .replace("{{leavesIcon}}", path.resolve(__dirname + '/../assets/sanusx/images/leaves_icon.png'))
241
+ .replace("{{predictedBodyMsg}}", predictedBodyMsg)
242
+ .replace("{{predictedLifestyleMsg}}", predictedLifestyleMsg)
243
+ .replace("{{predictedHeartMsg}}", predictedHeartMsg)
244
+ .replace("{{predictedBodyMsgIcon}}", bodyIcon)
245
+ .replace("{{predictedLifestyleMsgIcon}}", lifestyleIcon)
246
+ .replace("{{predictedHeartMsgIcon}}", mindIcon)
247
+
248
+
249
+ /* Recommendations section*/
250
+ /*tips*/
251
+ let tips = data.insights.tips
252
+ let allTips = []
253
+ let lifeStyleTips = []
254
+ let mindTips = []
255
+ let bodyTips = []
256
+ tips.map((tip, index) => {
257
+ if (index === 0) {
258
+ lifeStyleTips.push(tip)
259
+ }
260
+ if (index === 1) {
261
+ bodyTips.push(tip)
262
+ }
263
+ if (index === 2) {
264
+ mindTips.push(tip)
265
+ }
266
+ })
267
+ allTips.push(lifeStyleTips)
268
+ allTips.push(bodyTips)
269
+ allTips.push(mindTips)
270
+
271
+ let elementScores = data.insights.elementScores
156
272
 
273
+ recommendationsSectionTemplate = recommendationsSectionTemplate
274
+ .replace("{{recommendationsTitle}}", localeService.t('recommendationsTitle'))
157
275
  /*get the window from the dom to be used as a jquery function*/
158
276
  const $ = (require('jquery'))(dom.window);
159
277
 
160
278
  $('#content').addClass(language);
161
279
  $('#content').append(headerTemplate);
280
+ $('#content').append(superPowerSectionTemplate);
281
+ $('#content').append(personalDetailsSectionTemplate);
282
+ $('#content').append(predictionsSectionTemplate);
283
+ $('#content').append(recommendationsSectionTemplate);
162
284
 
285
+ $(".tips-section").append(renderInsightTips(allTips, elementScores));
163
286
 
164
287
  /*Footer*/
165
288
  let footerTemplateHTML = footerTemplate.replace("{{footerLogo}}", path.resolve(__dirname + '/../assets/sanusx/images/footer-logo.png'))
166
289
  .replace("{{sanusXReportFooter}}", localeService.t('sanusXReportFooter'));
167
290
 
168
291
  $('#content').append(footerTemplateHTML);
292
+ if (!data.PartScoresHighestValues.lifeStyle[0].isPredictiveElement) {
293
+ $(".prediction-component.lifestyle").addClass('prediction-wrong')
294
+ }
295
+ if (!data.PartScoresHighestValues.mind[0].isPredictiveElement) {
296
+ $(".prediction-component.mind").addClass('prediction-wrong')
297
+ }
298
+ if (!data.PartScoresHighestValues.body[0].isPredictiveElement) {
299
+ $(".prediction-component.body").addClass('prediction-wrong')
300
+ }
301
+
169
302
 
303
+ if (parseFloat(psychologicalScore) > 40 && parseFloat(psychologicalScore) < 70) {
304
+ $(".first-section-scores .psychological-score-section .part-1,.first-section-scores .psychological-score-section .part-3").addClass('inactive')
305
+ } else if (psychologicalScore >= 70) {
306
+ $(".first-section-scores .psychological-score-section .part-3,.first-section-scores .psychological-score-section .part-2").addClass('inactive')
307
+ } else {
308
+ $(".first-section-scores .psychological-score-section .part-1,.first-section-scores .psychological-score-section .part-2").addClass('inactive')
309
+ }
310
+
311
+ if (parseFloat(physicalScore) > 40 && parseFloat(physicalScore) < 70) {
312
+ $(".first-section-scores .physical-score-section .part-1,.first-section-scores .physical-score-section .part-3").addClass('inactive')
313
+ } else if (physicalScore >= 70) {
314
+ $(".first-section-scores .physical-score-section .part-3,.first-section-scores .physical-score-section .part-2").addClass('inactive')
315
+ } else {
316
+ $(".first-section-scores .physical-score-section .part-1,.first-section-scores .physical-score-section .part-2").addClass('inactive')
317
+ }
170
318
  $(".score-main").addClass(client);
171
319
 
172
320
 
@@ -236,7 +384,7 @@ let generateSanusXReport = async (data) => {
236
384
  debugLog("Buffer1 loaded!");
237
385
 
238
386
  let buffer = buffer1;
239
- await browser.close();
387
+ //await browser.close();
240
388
  return buffer;
241
389
 
242
390
 
@@ -285,7 +433,6 @@ let renderInsightTips = (tips, elementScores) => {
285
433
  let roundScore = Math.round(score / 2)
286
434
  let score_segments = Math.round(score / 2) + "/5"; // get score between 1 and 5
287
435
  let line1Class, line2Class, line3Class, line4Class, line5Class = ''
288
-
289
436
  if (roundScore === 1 || roundScore > 1) {
290
437
  line1Class = 'highlighted highlight-1'
291
438
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medicus.ai/medicus-report-pdf-generator",
3
- "version": "1.0.247",
3
+ "version": "1.0.249",
4
4
  "description": "Nasco corporate report - latest update in 5/3/2023 - New design for SanusX PDF",
5
5
  "main": "index.js",
6
6
  "scripts": {