generated from betagouv/template-nextjs
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: image upload and drawing (#41)
* 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
Showing
72 changed files
with
9,379 additions
and
1,326 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ALTER TABLE pictures ADD COLUMN "finalUrl" TEXT; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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":{}}}}}}}}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.