Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@
"@aws-sdk/client-cognito-identity-provider": "^3.496.0",
"@aws-sdk/client-s3": "^3.496.0",
"aws-sdk-mock": "^5.1.0",
"axios": "^1.6.0",
"axios": "^1.18.1",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-fileupload": "^1.2.0",
"helmet": "^7.1.0",
"join-images": "^1.1.5",
"lodash": "^4.17.21",
"lodash": "^4.18.1",
"loglevel": "^1.7.1",
"mongodb-memory-server": "^7.4.0",
"mongoose": "^6.0.6",
"mongoose-encryption": "^2.1.0",
"node-2fa": "^2.0.2",
"omit-deep-lodash": "^1.1.5",
"pad": "^3.2.0",
"pdf2pic": "^3.1.3",
"supertest": "^6.1.3",
"twilio": "^3.71.1"
"twilio": "^6.0.2"
},
"devDependencies": {
"@3dp4me/types": "workspace:*",
Expand All @@ -35,10 +34,14 @@
"@types/lodash": "^4.14.202",
"@types/node": "^20.9.4",
"@types/pad": "^1.0.2",
"canvas": "^3.2.3",
"cross-env": "^7.0.3",
"dotenv": "^17.4.2",
"eslint-config-3dp4me": "workspace:*",
"exceljs": "^4.4.0",
"jest": "^27.0.6",
"node-loader": "^2.1.0",
"omit-deep-lodash": "^1.1.5",
"rimraf": "^5.0.5",
"ts-loader": "^9.5.1",
"typescript": "^5.3.3",
Expand Down
3 changes: 1 addition & 2 deletions apps/backend/src/middleware/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ export const requireRole =
// If there isn't a user, authenticate
if (!req.user) {
return requireAuthentication(req, res, () => {
requireRole(role)
next()
requireRole(role)(req, res, next)
})
}
if (!req.user.roles.includes(role)) return sendResponse(res, 403, ERR_NOT_APPROVED)
Expand Down
27 changes: 5 additions & 22 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,19 @@
"@emotion/styled": "^11.14.1",
"@mui/icons-material": "^6.4.5",
"@mui/material": "^6.4.5",
"@sweetalert/with-react": "^0.1.1",
"@tanstack/react-query": "^5.17.19",
"@vis.gl/react-google-maps": "^1.4.2",
"Chip": "link:@mui/material/Chip",
"aws-amplify": "4.2.11",
"axios": "^1.6.0",
"axios": "^1.18.1",
"date-fns": "^3.3.0",
"js-file-download": "^0.4.12",
"lodash": "^4.17.21",
"lodash.omit": "^4.5.0",
"lodash": "^4.18.1",
"mic-recorder-to-mp3": "^2.2.2",
"object-hash": "^3.0.0",
"react": "^18.2.0",
"react-app-rewired": "^2.2.1",
"react-code-input": "^3.10.1",
"react-datepicker": "^4.25.0",
"react-datepicker": "^9.1.0",
"react-dom": "^18.2.0",
"react-html5-camera-photo": "^1.5.5",
"react-image-gallery": "^1.2.7",
Expand All @@ -45,7 +42,7 @@
"react-promise-tracker": "^2.1.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"react-signature-canvas": "^1.0.6",
"react-signature-canvas": "1.1.0-alpha.2",
"react-switch": "^6.0.0",
"signature_pad": "^2.3.2",
"styled-components": "^6.1.8",
Expand All @@ -57,18 +54,12 @@
"@babel/core": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"@babel/preset-react": "^7.23.3",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-image": "^3.0.3",
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.5",
"@types/jest": "^29.5.8",
"@types/lodash": "^4.14.202",
"@types/lodash.omit": "^4.5.9",
"@types/node": "^20.9.4",
"@types/object-hash": "^3.0.6",
"@types/react": "^18.2.37",
"@types/react-datepicker": "^4.19.3",
"@types/react-datepicker": "^7.0.0",
"@types/react-dom": "^18.2.15",
"@types/react-html5-camera-photo": "^1.5.3",
"@types/react-image-gallery": "^1.2.4",
Expand All @@ -83,17 +74,9 @@
"css-loader": "^6.8.1",
"dotenv-webpack": "^8.0.1",
"eslint-config-3dp4me": "workspace:*",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.3",
"image-webpack-loader": "^8.1.0",
"react-app-env": "^1.2.3",
"react-app-rewired": "^2.2.1",
"rimraf": "^5.0.5",
"rollup": "^4.5.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.9.2",
"sass": "^1.69.5",
"sass-loader": "^13.3.2",
"source-map-explorer": "^2.5.3",
Expand Down
39 changes: 0 additions & 39 deletions apps/frontend/rollup.config.mjs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { Nullish, Signature, SignaturePoint } from '@3dp4me/types'
import omit from 'lodash.omit'
import omit from 'lodash/omit'
import { FC, useEffect, useRef, useState } from 'react'
import ReactSignatureCanvas from 'react-signature-canvas'
import SignaturePad from 'signature_pad'

interface ControlledSignatureCanvasProps {
value: Nullish<Signature>
width: number
height: number
}

/**
* This library doesn't work great for "controlled" canvases. So we just encapsulate it here so that
* we can make it mount and unmout on every value update
* @returns
*/
export const ControlledSignatureCanvas: FC<ControlledSignatureCanvasProps> = ({ value }) => {
export const ControlledSignatureCanvas: FC<ControlledSignatureCanvasProps> = ({
value,
width,
height,
}) => {
const sigCanvas = useRef<ReactSignatureCanvas | null>(null)
const [doesCanvasHaveData, setDoesCanvasHaveData] = useState(false)

Expand All @@ -31,7 +38,7 @@ export const ControlledSignatureCanvas: FC<ControlledSignatureCanvasProps> = ({
)

setDoesCanvasHaveData(true)
setImmediate(() => sigCanvas.current?.fromData(data as any))
setTimeout(() => sigCanvas.current?.fromData(data as SignaturePad.Point[][]), 0)
}, [value, sigCanvas.current, doesCanvasHaveData])

/**
Expand Down Expand Up @@ -67,5 +74,13 @@ export const ControlledSignatureCanvas: FC<ControlledSignatureCanvasProps> = ({
return formattedData
}

return <ReactSignatureCanvas ref={sigCanvas} clearOnResize={false} />
// Giving the canvas explicit dimensions makes the library skip its own
// offsetWidth-based resize on mount, which reads 0 if layout hasn't settled
return (
<ReactSignatureCanvas
ref={sigCanvas}
clearOnResize={false}
canvasProps={{ width, height }}
/>
)
}
4 changes: 2 additions & 2 deletions apps/frontend/src/components/Fields/DateField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ registerLocale(LANGUAGES.AR, arSA)
const DateField = ({ displayName, isDisabled, fieldId, value, onChange }: DateFieldProps) => {
const selectedLang = useTranslations()[1]

const sendChanges = (date: Date) => {
onChange(fieldId, date.toString())
const sendChanges = (date: Date | null) => {
onChange(fieldId, date?.toString() || '')
}

const className = isDisabled ? 'input-field datepicker' : 'active-input datepicker'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ const CellEditContainer = styled(TableCell)`
width: 100%;
}

.react-datepicker-popper {
z-index: 10;
}

// Take full width for date picker
.react-datepicker-wrapper {
width: 100%;
Expand Down
35 changes: 29 additions & 6 deletions apps/frontend/src/components/Fields/SignatureField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import './SignatureField.scss'
import { Nullish, Path, PathValue, Signature, TranslatedString } from '@3dp4me/types'
import Button from '@mui/material/Button'
import hash from 'object-hash'
import { useState } from 'react'
import { useLayoutEffect, useRef, useState } from 'react'

import { useTranslations } from '../../hooks/useTranslations'
import { ControlledSignatureCanvas } from '../ControlledSignatureCanvas/ControlledSignatureCanvas'
Expand All @@ -31,6 +31,23 @@ const SignatureField = <T extends string>({
const [isModalOpen, setIsModalOpen] = useState(false)
const [isDocumentVisible, setIsDocumentVisible] = useState(false)
const translations = useTranslations()[0]
const sigContainerRef = useRef<HTMLDivElement | null>(null)
const [canvasWidth, setCanvasWidth] = useState(0)

// Watch the container's size so the canvas gets a real width even if the
// container had no layout (width 0) when this component first mounted
useLayoutEffect(() => {
const container = sigContainerRef.current
if (!container) return undefined

const observer = new ResizeObserver(() =>
setTimeout(() => setCanvasWidth(container.offsetWidth), 0)
)
observer.observe(container)
return () => {
observer.disconnect()
}
}, [])

/**
* Saves signature data points along with the canvas width and height so that
Expand Down Expand Up @@ -89,9 +106,15 @@ const SignatureField = <T extends string>({
onSave={onNewSignature}
isOpen={isModalOpen}
/>
<div className="sig-container">
{/* We need to keep changing the key to force a rerender */}
<ControlledSignatureCanvas key={hashSignature(value)} value={value} />
<div className="sig-container" ref={sigContainerRef}>
{canvasWidth > 0 && (
<ControlledSignatureCanvas
key={hashSignature(value, canvasWidth)}
value={value}
width={canvasWidth}
height={canvasWidth / 2}
/>
)}
<div className="sig-ctl-container">
<Button
className="sig-ctl-button doc-btn"
Expand All @@ -115,10 +138,10 @@ const SignatureField = <T extends string>({
)
}

const hashSignature = (sig: Nullish<Signature>): string => {
const hashSignature = (sig: Nullish<Signature>, width: number): string => {
if (!sig) return hash(Math.random())

return hash(JSON.stringify(sig))
return hash(JSON.stringify(sig) + width.toString())
}

export default SignatureField
14 changes: 1 addition & 13 deletions apps/frontend/webpack.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import Dotenv from "dotenv-webpack";
// const path = require("path")
import path from "path";
// import { Configuration } from "webpack";
import CopyWebpackPlugin from "copy-webpack-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";
import nodeExternals from "webpack-node-externals"

const config = {
mode: "production",
Expand Down Expand Up @@ -34,15 +30,7 @@ const config = {

{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
disable: true,
},
},
],
type: 'asset/resource',
},

{ test: /\.([cm]?ts|tsx)$/, loader: "ts-loader", exclude: /node_modules/ },
Expand Down
Loading
Loading