Skip to content

Commit

Permalink
feat: image upload and drawing (#41)
Browse files Browse the repository at this point in the history
* fix: display correct status

* fix: edit banner spacings

* feat: set edit banner sticky on mobile

* fix: return arrow size

* feat: set menu title position to sticky

* fix: some styles

* fix: simplify header

* fix: show reports on 2 columns from 6 items

* feat: add info messages

* feat: display report item on 3 rows

* fix: new colors

* fix: informative message mb

* fix: set printable colors

* fix(pdf): set header sticky on desktop

* fix: recipients textarea styles

* fix: menu header padding and more

* fix: remove *

* fix: form labels

* fix: date picker

* fix: margins

* gitignore

* fix: pdf styles can now be italic and bold

* fix: align tab title with content on firefox

* fix: report search columns styles

* fix: more report search styles

* fix: use createdBy along with redactedBy to allow user to edit a report

* refactor: add useCanEdit hook

* fix: mail carriage return

* wip: add version to env

* feat: add version at build time

* feat: add version component

* fix: menu title padding

* feat: add "city" and "zipcode" within the search params

* Mep pictures (#39)

* feat: add pictures table + button

* feat: add pictures to db

* feat: add input file with capture prop

* feat: add report pictures

* wip

* feat: display pictures in app and in pdf

* big wip

* alos peut être ?

* types?

* wip: service worker

* alors peut être ?

* feat: background image upload

* feat: cleanup local pictures when uploaded

* fix: use local picture data if it exists

* fix: correctly display pdf images

* feat: add pictures on backend pdf gen

* fix: add react import

* fix: add pictures to backend pdf gen

* fix(SW): use idb instead of electric

* fix(SW): set env vars in self object

* add logs

* more logs

* feat: set url in idb so SW can use it

* fix: little oopsie

* fix: safe parse env

* feat: store uploading status for each picture

* fix: sw updates

* maybe

* feat: listen to upload status in app

* fix: cache every page

* fix: manifest

* fix: use minio for image upload

* fix: correctly set bg url

* fix: remove capture attribute

* fix: correctly clear images on delete

* fix: merge

* wip

* fix: correctly sync pictures

* remove top badge

* add logs

* fix: disable sentry if no dsn

* add logs

* feat: add tmp_pictures table and make backend create pictures

* feat: add pic status badges

* fix: initial pic status

* fix(SW): remove throw from sync request

* fix: sort pictures + delete

* feat: reset SW on local data deletion

* cleanup

* wip: drawing canvas

* feat: remove auto retry

* wip: draw on picture

* maybe?

* fix: try to upload image within main process

* fix: offline upload

* feat(pdf): break page before pictures

* fix(pdf): blank page

* feat: add picture_lines in db and save lines

* feat: draw on canvas and sync with backend and pdf

* fix: picture lines migration

* fix: service worker and offline sync

* fix: dockerfile

* fix: backend dockerfile

* should be ok now

* feat: add marianne font

* fix(pdf): rollback to helvetica

* fix: display correct status

* fix: status

* feat(picture edition): add desktop layout
  • Loading branch information
ledouxm authored Nov 17, 2024
1 parent 3e5a877 commit 677a583
Show file tree
Hide file tree
Showing 72 changed files with 9,379 additions and 1,326 deletions.
13 changes: 13 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=

MINIO_USER=
MINIO_PASSWORD=

PG_PROXY_PORT=
PG_PROXY_PASSWORD=

Expand All @@ -22,6 +25,16 @@ EMAIL_PORT=
EMAIL_USER=
EMAIL_PASSWORD=

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_BUCKET_NAME=
AWS_REGION=
AWS_ENDPOINT=

MINIO_URL=
MINIO_BUCKET=
MINIO_ACCESS_KEY_ID=
MINIO_SECRET_KEY=
SENTRY_DSN=

# FRONTEND
Expand Down
15 changes: 14 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
################################
# BASE IMAGE FOR EVERY SERVICE #
################################
FROM --platform=linux/amd64 node:20-alpine AS with-pnpm
FROM --platform=linux/amd64 node:20.11-alpine AS with-pnpm
RUN apk add --no-cache \
build-base \
g++ \
cairo-dev \
jpeg-dev \
pango-dev \
giflib-dev \
pixman-dev \
pangomm-dev \
libjpeg-turbo-dev \
freetype-dev
RUN npm i -g pnpm

################################
Expand Down Expand Up @@ -33,6 +44,8 @@ RUN pnpm install --frozen-lockfile
# BACKEND SERVICE #
################################
FROM with-deps AS backend


WORKDIR /usr/src/app
COPY packages/backend/ ./packages/backend/
COPY packages/pdf/ ./packages/pdf/
Expand Down
8 changes: 8 additions & 0 deletions db/migrations/907-add_pictures.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE pictures (
id TEXT PRIMARY KEY,
"reportId" TEXT REFERENCES report(id) ON DELETE CASCADE,
url TEXT,
"createdAt" TIMESTAMP
);

ALTER TABLE pictures ENABLE ELECTRIC;
7 changes: 7 additions & 0 deletions db/migrations/908-add_tmp_pictures.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE tmp_pictures (
id TEXT PRIMARY KEY,
"reportId" TEXT REFERENCES report(id) ON DELETE CASCADE,
"createdAt" TIMESTAMP
);

ALTER TABLE tmp_pictures ENABLE ELECTRIC;
8 changes: 8 additions & 0 deletions db/migrations/909-add_picture_lines.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE picture_lines (
id TEXT PRIMARY KEY,
"pictureId" TEXT,
lines TEXT NOT NULL,
"createdAt" TIMESTAMP
);

ALTER TABLE picture_lines ENABLE ELECTRIC;
1 change: 1 addition & 0 deletions db/migrations/910-add_picture_final_url.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE pictures ADD COLUMN "finalUrl" TEXT;
13 changes: 13 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ version: "3.1"

volumes:
pg_data:
minio_data:

services:
# frontend:
Expand Down Expand Up @@ -57,3 +58,15 @@ services:
restart: always
ports:
- "${ADMINER_PORT:-8081}:8080"

minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
environment:
MINIO_ROOT_USER: ${MINIO_USER}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD}
command: server --console-address ":9001" /data
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"pnpm": {
"patchedDependencies": {
"react-pdf-html@2.0.4": "patches/react-pdf-html@2.0.4.patch"
},
"overrides": {
"restructure": "3.0.0"
}
}
}
2 changes: 1 addition & 1 deletion packages/backend/openapi.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"openapi":"3.1.0","info":{"title":"CR VIF API","description":"CR VIF API Documentation","version":"1.0"},"components":{"schemas":{}},"paths":{"/api/create-user":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"udap_id":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"required":["name","udap_id","email","password"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/login":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/refresh-token":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"token","required":true},{"schema":{"type":"string"},"in":"query","name":"refreshToken","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/send-reset-password":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/reset-password":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"temporaryLink":{"type":"string"},"newPassword":{"type":"string"}},"required":["temporaryLink","newPassword"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/udaps":{"get":{"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}}}}}}}},"/api/pdf/report":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"htmlString":{"type":"string"},"reportId":{"type":"string"},"recipients":{"type":"string"}},"required":["htmlString","reportId","recipients"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}},"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"reportId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{}}}}}}}}}}
{"openapi":"3.1.0","info":{"title":"CR VIF API","description":"CR VIF API Documentation","version":"1.0"},"components":{"schemas":{}},"paths":{"/api/create-user":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"udap_id":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"required":["name","udap_id","email","password"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/login":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/refresh-token":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"token","required":true},{"schema":{"type":"string"},"in":"query","name":"refreshToken","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"udap_id":{"type":"string"},"udap":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}},"required":["id","name","udap_id","udap"]},"token":{"type":"string"},"expiresAt":{"type":"string"},"refreshToken":{"type":"string"}},"required":["token","expiresAt","refreshToken"]}}}}}}},"/api/send-reset-password":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/reset-password":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"temporaryLink":{"type":"string"},"newPassword":{"type":"string"}},"required":["temporaryLink","newPassword"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/api/udaps":{"get":{"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"department":{"type":"string"},"completeCoords":{"type":"string"},"visible":{"type":"boolean"},"name":{"type":"string"},"address":{"type":"string"},"zipCode":{"type":"string"},"city":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"marianne_text":{"type":"string"},"drac_text":{"type":"string"},"udap_text":{"type":"string"}},"required":["id","department"]}}}}}}}},"/api/upload/image":{"post":{"responses":{"200":{"description":"Default Response"}}}},"/api/upload/picture":{"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"reportId","required":true},{"schema":{"type":"string"},"in":"query","name":"pictureId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{}}}}}}}},"/api/upload/picture/{pictureId}/lines":{"post":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"reportId","required":true},{"schema":{"type":"string"},"in":"path","name":"pictureId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}}},"/api/pdf/report":{"post":{"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"htmlString":{"type":"string"},"reportId":{"type":"string"},"recipients":{"type":"string"}},"required":["htmlString","reportId","recipients"]}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"string"}}}}}},"get":{"parameters":[{"schema":{"type":"string"},"in":"query","name":"reportId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{}}}}}}}}}}
2 changes: 2 additions & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@react-pdf/renderer": "^3.4.2",
"@sentry/node": "^7.70.0",
"@sinclair/typebox": "^0.32.20",
"canvas": "^2.11.2",
"date-fns": "^3.6.0",
"debug": "^4.3.4",
"dotenv": "^16.4.5",
Expand All @@ -54,6 +55,7 @@
"drizzle-typebox": "^0.1.1",
"drizzle-zod": "^0.5.1",
"fastify": "^4.26.2",
"fastify-multer": "^2.0.3",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.13",
"pastable": "^2.2.1",
Expand Down
Binary file added packages/backend/public/fonts/Marianne-Bold.ttf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6 changes: 5 additions & 1 deletion packages/backend/src/envVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ const envSchema = z.object({
EMAIL_USER: z.string(),
EMAIL_PASSWORD: z.string(),
EMAIL_EMITTER: z.string(),
SENTRY_DSN: z.string(),
MINIO_ACCESS_KEY_ID: z.string(),
MINIO_SECRET_KEY: z.string(),
MINIO_URL: z.string(),
MINIO_BUCKET: z.string(),
SENTRY_DSN: z.string().optional(),
});

export const ENV = envSchema.parse(process.env);
Expand Down
61 changes: 61 additions & 0 deletions packages/backend/src/features/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { db } from "../db/db";
import canvas, { createCanvas, loadImage } from "canvas";
import fs from "fs/promises";

export const getPictureWithLines = async ({ pictureId }: { pictureId: string }) => {
const picture = await db.pictures.findFirst({
where: { id: pictureId },
});

const pictureLines = await db.picture_lines.findFirst({
where: { pictureId },
});

const lines = JSON.parse(pictureLines?.lines || "[]");
const buffer = await applyLinesToPicture({ pictureUrl: picture!.url!, lines });

await fs.writeFile("./test.png", buffer);

return buffer;
};

export const applyLinesToPicture = async ({
pictureUrl,
lines,
}: {
pictureUrl: string;
lines: Array<{ points: { x: number; y: number }[]; color: string }>;
}) => {
try {
const image = await loadImage(pictureUrl);

const canvas = createCanvas(image.width, image.height);
const ctx = canvas.getContext("2d");

ctx.drawImage(image, 0, 0);

ctx.lineWidth = 5;
ctx.lineCap = "round";
ctx.lineJoin = "round";

lines.forEach((line) => {
ctx.strokeStyle = line.color;
if (line.points.length > 0) {
ctx.beginPath();

ctx.moveTo(line.points[0]!.x, line.points[0]!.y);

for (let i = 1; i < line.points.length; i++) {
ctx.lineTo(line.points[i]!.x, line.points[i]!.y);
}

ctx.stroke();
}
});

return canvas.toBuffer("image/png");
} catch (error) {
console.error("Error processing image:", error);
throw error;
}
};
10 changes: 6 additions & 4 deletions packages/backend/src/features/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { ENV, isDev } from "../envVars";

isDev
? null
: Sentry.init({
dsn: ENV.SENTRY_DSN,
tracesSampleRate: 1.0,
});
: ENV.SENTRY_DSN
? Sentry.init({
dsn: ENV.SENTRY_DSN,
tracesSampleRate: 1.0,
})
: null;

const sentry = isDev ? null : Sentry;

Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { ENV } from "./envVars";
import { generateOpenApi, initFastify } from "./router";
import { makeDebug } from "./features/debug";
import { initClauseV2 } from "./tmp";
import { initFonts } from "@cr-vif/pdf";

initFonts("./public/");

const debug = makeDebug("index");

Expand Down
2 changes: 2 additions & 0 deletions packages/backend/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import fs from "node:fs/promises";
import { makeDebug } from "./features/debug";
import { staticDataPlugin } from "./routes/staticDataRoutes";
import { pdfPlugin } from "./routes/pdfRoutes";
import { uploadPlugin } from "./routes/uploadRoutes";
import { sentry } from "./features/sentry";

const debug = makeDebug("fastify");
Expand Down Expand Up @@ -54,6 +55,7 @@ export const initFastify = async () => {

await instance.register(userPlugin);
await instance.register(staticDataPlugin);
await instance.register(uploadPlugin, { prefix: "/upload" });
await instance.register(pdfPlugin, { prefix: "/pdf" });
},
{ prefix: "/api" },
Expand Down
18 changes: 15 additions & 3 deletions packages/backend/src/routes/pdfRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Type, type FastifyPluginAsyncTypebox } from "@fastify/type-provider-typebox";
import { renderToBuffer } from "@react-pdf/renderer";
import { ReportPDFDocument } from "@cr-vif/pdf";
import { Udap } from "@cr-vif/electric-client/frontend";
import { Pictures, Udap } from "@cr-vif/electric-client/frontend";
import { authenticate } from "./authMiddleware";
import { db } from "../db/db";
import { sendReportMail } from "../features/mail";
import { getPDFName } from "../services/uploadService";
import React from "react";

export const pdfPlugin: FastifyPluginAsyncTypebox = async (fastify, _) => {
fastify.addHook("preHandler", authenticate);
Expand All @@ -14,7 +15,9 @@ export const pdfPlugin: FastifyPluginAsyncTypebox = async (fastify, _) => {
const { reportId, htmlString } = request.body;
const { udap } = request.user.user;

const pdf = await generatePdf({ htmlString, udap });
const pictures = await db.pictures.findMany({ where: { reportId }, orderBy: { createdAt: "asc" } });

const pdf = await generatePdf({ htmlString, udap, pictures });

const name = getPDFName(reportId);

Expand Down Expand Up @@ -57,12 +60,21 @@ export const pdfPlugin: FastifyPluginAsyncTypebox = async (fastify, _) => {
);
};

const generatePdf = async ({ htmlString, udap }: { htmlString: string; udap: Udap }) => {
const generatePdf = async ({
htmlString,
udap,
pictures,
}: {
htmlString: string;
udap: Udap;
pictures: Pictures[];
}) => {
return renderToBuffer(
<ReportPDFDocument
udap={udap as Udap}
htmlString={htmlString}
images={{ marianne: "./public/marianne.png", marianneFooter: "./public/marianne_footer.png" }}
pictures={pictures}
/>,
);
};
Expand Down
Loading

0 comments on commit 677a583

Please sign in to comment.