From 86c8cc00fd9a019690c9f700c2496459ea1d3a54 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 15 Aug 2024 18:57:40 +0200 Subject: [PATCH 01/15] feat(create-page): intial layout and page styling Additional linting fixes --- src/components/DrawPDFFields/index.tsx | 157 +++++++-------- .../DrawPDFFields/style.module.scss | 15 +- src/pages/create/index.tsx | 189 ++++++++++-------- src/pages/create/style.module.scss | 10 +- 4 files changed, 188 insertions(+), 183 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index e98187c..1b36cd7 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -1,20 +1,15 @@ import { AccessTime, CalendarMonth, - ExpandMore, Gesture, - PictureAsPdf, Badge, Work, Close } from '@mui/icons-material' import { Box, - Typography, - Accordion, - AccordionDetails, - AccordionSummary, CircularProgress, + Divider, FormControl, InputLabel, MenuItem, @@ -53,7 +48,7 @@ export const DrawPDFFields = (props: Props) => { const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) - const [showDrawToolBox, setShowDrawToolBox] = useState(false) + const [showDrawToolBox] = useState(true) const [selectedTool, setSelectedTool] = useState() const [toolbox] = useState([ @@ -95,6 +90,16 @@ export const DrawPDFFields = (props: Props) => { useEffect(() => { if (selectedFiles) { + /** + * Reads the pdf binary files and converts it's pages to images + * creates the pdfFiles object and sets to a state + */ + const parsePdfPages = async () => { + const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles) + + setPdfFiles(pdfFiles) + } + setParsingPdf(true) parsePdfPages().finally(() => { @@ -105,7 +110,7 @@ export const DrawPDFFields = (props: Props) => { useEffect(() => { if (pdfFiles) props.onDrawFieldsChange(pdfFiles) - }, [pdfFiles]) + }, [pdfFiles, props]) /** * Drawing events @@ -132,12 +137,15 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param page PdfPage where press happened */ - const onMouseDown = (event: any, page: PdfPage) => { + const onMouseDown = ( + event: React.MouseEvent, + page: PdfPage + ) => { // Proceed only if left click if (event.button !== 0) return // Only allow drawing if mouse is not over other drawn element - const isOverPdfImageWrapper = event.target.tagName === 'IMG' + const isOverPdfImageWrapper = event.currentTarget.tagName === 'IMG' if (!selectedTool || !isOverPdfImageWrapper) { return @@ -185,7 +193,10 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param page PdfPage where moving is happening */ - const onMouseMove = (event: any, page: PdfPage) => { + const onMouseMove = ( + event: React.MouseEvent, + page: PdfPage + ) => { if (mouseState.clicked && selectedTool) { const lastElementIndex = page.drawnFields.length - 1 const lastDrawnField = page.drawnFields[lastElementIndex] @@ -216,7 +227,9 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField Which we are moving */ - const onDrawnFieldMouseDown = (event: any) => { + const onDrawnFieldMouseDown = ( + event: React.MouseEvent + ) => { event.stopPropagation() // Proceed only if left click @@ -239,11 +252,14 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are moving */ - const onDranwFieldMouseMove = (event: any, drawnField: DrawnField) => { + const onDranwFieldMouseMove = ( + event: React.MouseEvent, + drawnField: DrawnField + ) => { if (mouseState.dragging) { const { mouseX, mouseY, rect } = getMouseCoordinates( event, - event.target.parentNode + event.currentTarget.parentNode as HTMLElement ) const coordsOffset = mouseState.coordsInWrapper @@ -272,7 +288,9 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are resizing */ - const onResizeHandleMouseDown = (event: any) => { + const onResizeHandleMouseDown = ( + event: React.MouseEvent + ) => { // Proceed only if left click if (event.button !== 0) return @@ -288,11 +306,14 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are resizing */ - const onResizeHandleMouseMove = (event: any, drawnField: DrawnField) => { + const onResizeHandleMouseMove = ( + event: React.MouseEvent, + drawnField: DrawnField + ) => { if (mouseState.resizing) { const { mouseX, mouseY } = getMouseCoordinates( event, - event.target.parentNode.parentNode + event.currentTarget.parentNode as HTMLElement ) const width = mouseX - drawnField.left @@ -313,7 +334,7 @@ export const DrawPDFFields = (props: Props) => { * @param drawnFileIndex drawn file index */ const onRemoveHandleMouseDown = ( - event: any, + event: React.MouseEvent, pdfFileIndex: number, pdfPageIndex: number, drawnFileIndex: number @@ -331,7 +352,9 @@ export const DrawPDFFields = (props: Props) => { * so select can work properly * @param event Mouse event */ - const onUserSelectHandleMouseDown = (event: any) => { + const onUserSelectHandleMouseDown = ( + event: React.MouseEvent + ) => { event.stopPropagation() } @@ -341,8 +364,11 @@ export const DrawPDFFields = (props: Props) => { * @param customTarget mouse coordinates relative to this element, if not provided * event.target will be used */ - const getMouseCoordinates = (event: any, customTarget?: any) => { - const target = customTarget ? customTarget : event.target + const getMouseCoordinates = ( + event: React.MouseEvent, + customTarget?: HTMLElement + ) => { + const target = customTarget ? customTarget : event.currentTarget const rect = target.getBoundingClientRect() const mouseX = event.clientX - rect.left //x position within the element. const mouseY = event.clientY - rect.top //y position within the element. @@ -354,31 +380,6 @@ export const DrawPDFFields = (props: Props) => { } } - /** - * Reads the pdf binary files and converts it's pages to images - * creates the pdfFiles object and sets to a state - */ - const parsePdfPages = async () => { - const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles) - - setPdfFiles(pdfFiles) - } - - /** - * - * @returns if expanded pdf accordion is present - */ - const hasExpandedPdf = () => { - return !!pdfFiles.filter((pdfFile) => !!pdfFile.expanded).length - } - - const handleAccordionExpandChange = (expanded: boolean, pdfFile: PdfFile) => { - pdfFile.expanded = expanded - - refreshPdfFiles() - setShowDrawToolBox(hasExpandedPdf()) - } - /** * Changes the drawing tool * @param drawTool to draw with @@ -398,19 +399,11 @@ export const DrawPDFFields = (props: Props) => { */ const getPdfPages = (pdfFile: PdfFile, pdfFileIndex: number) => { return ( - + <> {pdfFile.pages.map((page, pdfPageIndex: number) => { return (
{ onMouseMove(event, page) @@ -516,7 +509,7 @@ export const DrawPDFFields = (props: Props) => {
) })} -
+ ) } @@ -533,34 +526,26 @@ export const DrawPDFFields = (props: Props) => { } return ( - - - Draw fields on the PDFs: - - {pdfFiles.map((pdfFile, pdfFileIndex: number) => { - return ( - { - handleAccordionExpandChange(expanded, pdfFile) - }} - > - } - aria-controls={`panel${pdfFileIndex}-content`} - id={`panel${pdfFileIndex}header`} +
+ {pdfFiles.map((pdfFile, pdfFileIndex: number) => { + return ( + <> +
+ {getPdfPages(pdfFile, pdfFileIndex)} +
+ {pdfFileIndex < pdfFiles.length - 1 && ( + - - {pdfFile.file.name} - - - {getPdfPages(pdfFile, pdfFileIndex)} - - - ) - })} - + File Separator + + )} + + ) + })} {showDrawToolBox && ( @@ -569,7 +554,7 @@ export const DrawPDFFields = (props: Props) => { .filter((drawTool) => drawTool.active) .map((drawTool: DrawTool, index: number) => { return ( - { handleToolSelect(drawTool) @@ -578,12 +563,12 @@ export const DrawPDFFields = (props: Props) => { > {drawTool.icon} {drawTool.label} - +
) })}
)} - + ) } diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 7490d1f..0d84c4b 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -51,7 +51,6 @@ position: relative; -webkit-user-select: none; user-select: none; - margin-bottom: 10px; > img { display: block; @@ -81,7 +80,7 @@ } &.edited { - border: 1px dotted #01aaad + border: 1px dotted #01aaad; } .resizeHandle { @@ -124,3 +123,15 @@ padding: 5px 0; } } + +.fileWrapper { + display: flex; + flex-direction: column; + gap: 15px; +} + +.view { + display: flex; + flex-direction: column; + gap: 25px; +} diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index fe4ac7f..36e6584 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -64,6 +64,7 @@ import styles from './style.module.scss' import { PdfFile } from '../../types/drawing' import { DrawPDFFields } from '../../components/DrawPDFFields' import { Mark } from '../../types/mark.ts' +import { StickySideColumns } from '../../layouts/StickySideColumns.tsx' export const CreatePage = () => { const navigate = useNavigate() @@ -702,94 +703,110 @@ export const CreatePage = () => { <> {isLoading && } - setTitle(e.target.value)} - variant="outlined" - /> + + setTitle(e.target.value)} + variant="outlined" + /> - - handleSelectFiles(value)} + + handleSelectFiles(value)} + /> + + {selectedFiles.length > 0 && ( +
    + {selectedFiles.map((file, index) => ( +
  • + {file.name} + handleRemoveFile(file)}> + {' '} + +
  • + ))} +
+ )} +
+ + } + right={ + <> + + Add Counterparts + + + + setUserInput(e.target.value)} + helperText={error} + error={!!error} + /> + + Role + + + + + + + + + + + + + + + } + > + - - {selectedFiles.length > 0 && ( -
    - {selectedFiles.map((file, index) => ( -
  • - {file.name} - handleRemoveFile(file)}> - {' '} - -
  • - ))} -
- )} -
- - - Add Counterparts - - - - setUserInput(e.target.value)} - helperText={error} - error={!!error} - /> - - Role - - - - - - - - - - - - - - - - +
) diff --git a/src/pages/create/style.module.scss b/src/pages/create/style.module.scss index 395936b..9304618 100644 --- a/src/pages/create/style.module.scss +++ b/src/pages/create/style.module.scss @@ -1,14 +1,6 @@ @import '../../styles/colors.scss'; .container { - display: flex; - flex-direction: column; - color: $text-color; - margin-top: 10px; - gap: 10px; - width: 550px; - max-width: 550px; - .inputBlock { display: flex; flex-direction: column; @@ -38,4 +30,4 @@ cursor: pointer; } } -} \ No newline at end of file +} From 4cf578b51438711bdb7112c386b268406b7c94ed Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 15 Aug 2024 18:59:06 +0200 Subject: [PATCH 02/15] chore(lint): reduce max warnings --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 447fdda..88a1439 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 25", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 14", "lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:staged": "eslint --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "formatter:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"", From 6641cf2ee703c4c973c69ecde864030fb2e91596 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 15 Aug 2024 19:50:44 +0200 Subject: [PATCH 03/15] fix: simplify events, more ts and clean up --- src/components/DrawPDFFields/index.tsx | 82 ++++++++++--------- .../DrawPDFFields/style.module.scss | 7 ++ 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 1b36cd7..6bf9ed7 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -48,7 +48,6 @@ export const DrawPDFFields = (props: Props) => { const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) - const [showDrawToolBox] = useState(true) const [selectedTool, setSelectedTool] = useState() const [toolbox] = useState([ @@ -144,10 +143,7 @@ export const DrawPDFFields = (props: Props) => { // Proceed only if left click if (event.button !== 0) return - // Only allow drawing if mouse is not over other drawn element - const isOverPdfImageWrapper = event.currentTarget.tagName === 'IMG' - - if (!selectedTool || !isOverPdfImageWrapper) { + if (!selectedTool) { return } @@ -199,8 +195,14 @@ export const DrawPDFFields = (props: Props) => { ) => { if (mouseState.clicked && selectedTool) { const lastElementIndex = page.drawnFields.length - 1 + const lastDrawnField = page.drawnFields[lastElementIndex] + // Return early if we don't have lastDrawnField + // Issue noticed in the console when dragging out of bounds + // to the page below (without releaseing mouse click) + if (!lastDrawnField) return + const { mouseX, mouseY } = getMouseCoordinates(event) const width = mouseX - lastDrawnField.left @@ -252,14 +254,14 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are moving */ - const onDranwFieldMouseMove = ( + const onDrawnFieldMouseMove = ( event: React.MouseEvent, drawnField: DrawnField ) => { if (mouseState.dragging) { const { mouseX, mouseY, rect } = getMouseCoordinates( event, - event.currentTarget.parentNode as HTMLElement + event.currentTarget.parentElement ) const coordsOffset = mouseState.coordsInWrapper @@ -313,7 +315,10 @@ export const DrawPDFFields = (props: Props) => { if (mouseState.resizing) { const { mouseX, mouseY } = getMouseCoordinates( event, - event.currentTarget.parentNode as HTMLElement + // currentTarget = span handle + // 1st parent = drawnField + // 2nd parent = img + event.currentTarget.parentElement?.parentElement ) const width = mouseX - drawnField.left @@ -366,7 +371,7 @@ export const DrawPDFFields = (props: Props) => { */ const getMouseCoordinates = ( event: React.MouseEvent, - customTarget?: HTMLElement + customTarget?: HTMLElement | null ) => { const target = customTarget ? customTarget : event.currentTarget const rect = target.getBoundingClientRect() @@ -405,16 +410,15 @@ export const DrawPDFFields = (props: Props) => {
{ - onMouseMove(event, page) - }} - onMouseDown={(event) => { - onMouseDown(event, page) - }} > { + onMouseMove(event, page) + }} + onMouseDown={(event) => { + onMouseDown(event, page) + }} draggable="false" - style={{ width: '100%' }} src={page.image} /> @@ -424,7 +428,7 @@ export const DrawPDFFields = (props: Props) => { key={drawnFieldIndex} onMouseDown={onDrawnFieldMouseDown} onMouseMove={(event) => { - onDranwFieldMouseMove(event, drawnField) + onDrawnFieldMouseMove(event, drawnField) }} className={styles.drawingRectangle} style={{ @@ -529,7 +533,7 @@ export const DrawPDFFields = (props: Props) => {
{pdfFiles.map((pdfFile, pdfFileIndex: number) => { return ( - <> +
{getPdfPages(pdfFile, pdfFileIndex)}
@@ -543,32 +547,30 @@ export const DrawPDFFields = (props: Props) => { File Separator )} - +
) })} - {showDrawToolBox && ( - - - {toolbox - .filter((drawTool) => drawTool.active) - .map((drawTool: DrawTool, index: number) => { - return ( -
{ - handleToolSelect(drawTool) - }} - className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`} - > - {drawTool.icon} - {drawTool.label} -
- ) - })} -
+ + + {toolbox + .filter((drawTool) => drawTool.active) + .map((drawTool: DrawTool, index: number) => { + return ( +
{ + handleToolSelect(drawTool) + }} + className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`} + > + {drawTool.icon} + {drawTool.label} +
+ ) + })}
- )} +
) } diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 0d84c4b..249b66c 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -93,6 +93,13 @@ border: 1px solid rgb(160, 160, 160); border-radius: 50%; cursor: pointer; + + // Increase the area a bit so it's easier to click + &::after { + content: ''; + position: absolute; + inset: -14px; + } } .removeHandle { From c2199b79bdd4e352dda618502536a5e16cb81258 Mon Sep 17 00:00:00 2001 From: enes Date: Fri, 16 Aug 2024 11:08:03 +0200 Subject: [PATCH 04/15] refactor(create-page): styling --- src/pages/create/index.tsx | 143 +++++++++++++---------------- src/pages/create/style.module.scss | 19 ++-- 2 files changed, 78 insertions(+), 84 deletions(-) diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 36e6584..4d292b2 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -6,7 +6,6 @@ import { IconButton, InputLabel, MenuItem, - Paper, Select, Table, TableBody, @@ -705,99 +704,87 @@ export const CreatePage = () => { +
setTitle(e.target.value)} variant="outlined" /> - - - handleSelectFiles(value)} - /> - - {selectedFiles.length > 0 && ( -
    - {selectedFiles.map((file, index) => ( -
  • - {file.name} - handleRemoveFile(file)}> - {' '} - -
  • - ))} -
- )} -
- +
    + {selectedFiles.length > 0 && + selectedFiles.map((file, index) => ( +
  • + {file.name} + handleRemoveFile(file)}> + {' '} + +
  • + ))} +
+ handleSelectFiles(value)} + /> +
} right={ - <> +
Add Counterparts - - - setUserInput(e.target.value)} - helperText={error} - error={!!error} - /> - - Role - - - - + setUserInput(e.target.value)} + helperText={error} + error={!!error} + /> + + Role + + + + - - +
+ + - - +
+
} > { return ( - + diff --git a/src/pages/create/style.module.scss b/src/pages/create/style.module.scss index 9304618..527ef5c 100644 --- a/src/pages/create/style.module.scss +++ b/src/pages/create/style.module.scss @@ -1,11 +1,18 @@ @import '../../styles/colors.scss'; -.container { - .inputBlock { - display: flex; - flex-direction: column; - gap: 25px; - } +.flexWrap { + display: flex; + flex-direction: column; + gap: 15px; +} + +.paperGroup { + border-radius: 4px; + background: white; + padding: 15px; + display: flex; + flex-direction: column; + gap: 15px; } .subHeader { From 29e6c851504f884cdeae738bb70323a7703f2f74 Mon Sep 17 00:00:00 2001 From: enes Date: Fri, 16 Aug 2024 16:14:35 +0200 Subject: [PATCH 05/15] fix(create-page): only show signers in counterpart select --- src/components/DrawPDFFields/index.tsx | 54 +++++++++++++------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 6bf9ed7..99d8b78 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -19,7 +19,7 @@ import styles from './style.module.scss' import { useEffect, useState } from 'react' import * as PDFJS from 'pdfjs-dist' -import { ProfileMetadata, User } from '../../types' +import { ProfileMetadata, User, UserRole } from '../../types' import { PdfFile, DrawTool, @@ -474,36 +474,38 @@ export const DrawPDFFields = (props: Props) => { labelId="counterparts" label="Counterparts" > - {props.users.map((user, index) => { - let displayValue = truncate( - hexToNpub(user.pubkey), - { - length: 16 - } - ) - - const metadata = props.metadata[user.pubkey] - - if (metadata) { - displayValue = truncate( - metadata.name || - metadata.display_name || - metadata.username, + {props.users + .filter((u) => u.role === UserRole.signer) + .map((user, index) => { + let displayValue = truncate( + hexToNpub(user.pubkey), { length: 16 } ) - } - return ( - - {displayValue} - - ) - })} + const metadata = props.metadata[user.pubkey] + + if (metadata) { + displayValue = truncate( + metadata.name || + metadata.display_name || + metadata.username, + { + length: 16 + } + ) + } + + return ( + + {displayValue} + + ) + })} From 48f54d8568f86f205859b2bd9ef5fd3491c8448b Mon Sep 17 00:00:00 2001 From: enes Date: Mon, 19 Aug 2024 08:30:22 +0200 Subject: [PATCH 06/15] refactor(create-page): update designs and add files navigation --- src/components/DrawPDFFields/index.tsx | 11 +- .../DrawPDFFields/style.module.scss | 4 + src/layouts/StickySideColumns.module.scss | 3 + src/pages/create/index.tsx | 427 +++++++++++------- src/pages/create/style.module.scss | 111 ++++- 5 files changed, 361 insertions(+), 195 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 99d8b78..992f273 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -535,12 +535,17 @@ export const DrawPDFFields = (props: Props) => {
{pdfFiles.map((pdfFile, pdfFileIndex: number) => { return ( -
-
+ <> +
{getPdfPages(pdfFile, pdfFileIndex)}
{pdfFileIndex < pdfFiles.length - 1 && ( { File Separator )} -
+ ) })} diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 249b66c..e0a09dc 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -1,3 +1,5 @@ +@import '../../styles/sizes.scss'; + .pdfFieldItem { background: white; padding: 10px; @@ -135,6 +137,8 @@ display: flex; flex-direction: column; gap: 15px; + position: relative; + scroll-margin-top: $header-height + $body-vertical-padding; } .view { diff --git a/src/layouts/StickySideColumns.module.scss b/src/layouts/StickySideColumns.module.scss index 7690822..7495cad 100644 --- a/src/layouts/StickySideColumns.module.scss +++ b/src/layouts/StickySideColumns.module.scss @@ -10,6 +10,9 @@ .sidesWrap { position: relative; + + // HACK: Stop grid column from growing + min-width: 0; } .sides { diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 4d292b2..57e41b0 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -1,26 +1,18 @@ -import { Clear, DragHandle } from '@mui/icons-material' +import { DragHandle } from '@mui/icons-material' import { - Box, Button, - FormControl, IconButton, - InputLabel, + ListItem, + ListItemIcon, + ListItemText, MenuItem, Select, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, TextField, - Tooltip, - Typography + Tooltip } from '@mui/material' import type { Identifier, XYCoord } from 'dnd-core' import saveAs from 'file-saver' import JSZip from 'jszip' -import { MuiFileInput } from 'mui-file-input' import { Event, kinds } from 'nostr-tools' import { useEffect, useRef, useState } from 'react' import { DndProvider, useDrag, useDrop } from 'react-dnd' @@ -64,6 +56,14 @@ import { PdfFile } from '../../types/drawing' import { DrawPDFFields } from '../../components/DrawPDFFields' import { Mark } from '../../types/mark.ts' import { StickySideColumns } from '../../layouts/StickySideColumns.tsx' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { + faEye, + faPen, + faPlus, + faTrash, + faUpload +} from '@fortawesome/free-solid-svg-icons' export const CreatePage = () => { const navigate = useNavigate() @@ -76,7 +76,14 @@ export const CreatePage = () => { const [authUrl, setAuthUrl] = useState() const [title, setTitle] = useState(`sigit_${formatTimestamp(Date.now())}`) + const [selectedFiles, setSelectedFiles] = useState([]) + const fileInputRef = useRef(null) + const handleUploadButtonClick = () => { + if (fileInputRef.current) { + fileInputRef.current.click() + } + } const [userInput, setUserInput] = useState('') const [userRole, setUserRole] = useState(UserRole.signer) @@ -268,19 +275,22 @@ export const CreatePage = () => { }) } - const handleSelectFiles = (files: File[]) => { - setSelectedFiles((prev) => { - const prevFileNames = prev.map((file) => file.name) - - const newFiles = files.filter( - (file) => !prevFileNames.includes(file.name) - ) - - return [...prev, ...newFiles] - }) + const handleSelectFiles = (event: React.ChangeEvent) => { + if (event.target.files) { + setSelectedFiles(Array.from(event.target.files)) + } } - const handleRemoveFile = (fileToRemove: File) => { + const handleFileClick = (name: string) => { + document.getElementById(name)?.scrollIntoView({ behavior: 'smooth' }) + } + + const handleRemoveFile = ( + event: React.MouseEvent, + fileToRemove: File + ) => { + event.stopPropagation() + setSelectedFiles((prevFiles) => prevFiles.filter((file) => file.name !== fileToRemove.name) ) @@ -705,71 +715,134 @@ export const CreatePage = () => { - setTitle(e.target.value)} - variant="outlined" - /> -
    +
    + setTitle(e.target.value)} + sx={{ + width: '100%', + fontSize: '16px', + '& .MuiInputBase-input': { + padding: '7px 14px' + }, + '& .MuiOutlinedInput-notchedOutline': { + display: 'none' + } + }} + /> +
    +
      {selectedFiles.length > 0 && selectedFiles.map((file, index) => ( -
    1. - {file.name} - handleRemoveFile(file)}> - {' '} - -
    2. + + + ))} -
- handleSelectFiles(value)} - /> + +
} right={
- - Add Counterparts - - +
setUserInput(e.target.value)} helperText={error} error={!!error} + fullWidth + sx={{ + fontSize: '16px', + '& .MuiInputBase-input': { + padding: '7px 14px' + }, + '& .MuiOutlinedInput-notchedOutline': { + display: 'none' + } + }} /> - - Role - - - + - +
{ handleRemoveUser={handleRemoveUser} moveSigner={moveSigner} /> - -
+ +
} > @@ -815,80 +888,76 @@ const DisplayUser = ({ moveSigner }: DisplayUsersProps) => { return ( - -
- - - User - Role - Action - - - - - {users - .filter((user) => user.role === UserRole.signer) - .map((user, index) => ( - + + {users + .filter((user) => user.role === UserRole.signer) + .map((user, index) => ( + + ))} + + {users + .filter((user) => user.role === UserRole.viewer) + .map((user, index) => { + const userMeta = metadata[user.pubkey] + return ( +
+
+ - ))} - - {users - .filter((user) => user.role === UserRole.viewer) - .map((user, index) => { - const userMeta = metadata[user.pubkey] - return ( - - - - - - - - - - handleRemoveUser(user.pubkey)}> - - - - - - ) - })} - -
-
+
+ + + handleRemoveUser(user.pubkey)}> + + + + + ) + })} + ) } @@ -992,16 +1061,14 @@ const SignerRow = ({ drag(drop(ref)) return ( - - - + +
- - - null} + renderValue={(value) => ( + + )} + onChange={(e) => + handleUserRoleChange(e.target.value as UserRole, user.pubkey) + } + sx={{ + fontSize: '16px', + minWidth: '44px', + '& .MuiInputBase-input': { + padding: '7px 14px!important', + textOverflow: 'unset!important' + }, + '& .MuiOutlinedInput-notchedOutline': { + display: 'none' } - > - {UserRole.signer} - {UserRole.viewer} - - - - - handleRemoveUser(user.pubkey)}> - - - - - + }} + > + {UserRole.signer} + {UserRole.viewer} + + + handleRemoveUser(user.pubkey)}> + + + +
) } diff --git a/src/pages/create/style.module.scss b/src/pages/create/style.module.scss index 527ef5c..f838f67 100644 --- a/src/pages/create/style.module.scss +++ b/src/pages/create/style.module.scss @@ -6,6 +6,60 @@ gap: 15px; } +.orderedFilesList { + counter-reset: item; + list-style-type: none; + margin: 0; + + li { + display: flex; + align-items: center; + + transition: ease 0.4s; + border-radius: 4px; + background: #ffffff; + padding: 7px 10px; + color: rgba(0, 0, 0, 0.5); + min-height: 45px; + cursor: pointer; + gap: 10px; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + &::before { + content: counter(item) ' '; + counter-increment: item; + font-size: 14px; + } + :nth-child(1) { + flex-grow: 1; + + font-size: 16px; + + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + + button { + color: $primary-main; + } + + &:hover, + &.active, + &:focus-within { + background: $primary-main; + color: white; + + button { + color: white; + } + } + } +} + .paperGroup { border-radius: 4px; background: white; @@ -13,28 +67,49 @@ display: flex; flex-direction: column; gap: 15px; + + // Automatic scrolling if paper-group gets large enough + // used for files on the left and users on the right + max-height: 350px; + overflow-x: hidden; + overflow-y: auto; } -.subHeader { - border-bottom: 0.5px solid; -} +.inputWrapper { + display: flex; + align-items: center; -.tableHeaderCell { - border-right: 1px solid rgba(224, 224, 224, 1); -} + height: 34px; + overflow: hidden; + border-radius: 4px; + outline: solid 1px #dddddd; + background: white; -.tableCell { - border-right: 1px solid rgba(224, 224, 224, 1); - height: 56px; + width: 100%; - .user { - display: flex; - align-items: center; - gap: 10px; - - .name { - text-align: center; - cursor: pointer; - } + &:focus-within { + outline-color: $primary-main; + } +} + +.user { + display: flex; + gap: 10px; + + font-size: 14px; + text-align: start; + justify-content: center; + align-items: center; + + a:hover { + text-decoration: none; + } +} + +.avatar { + flex-grow: 1; + + &:first-child { + margin-left: 34px; } } From 1caeb48e6c91e0c8fd052caa8df0a5299f3e5f03 Mon Sep 17 00:00:00 2001 From: enes Date: Mon, 19 Aug 2024 14:55:26 +0200 Subject: [PATCH 07/15] fix(create-page): file list --- src/components/DrawPDFFields/index.tsx | 28 ++++++++++++-------------- src/pages/create/index.tsx | 20 +++++++++++------- src/pages/create/style.module.scss | 11 ++++++---- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 992f273..62216e1 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -16,7 +16,7 @@ import { Select } from '@mui/material' import styles from './style.module.scss' -import { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import * as PDFJS from 'pdfjs-dist' import { ProfileMetadata, User, UserRole } from '../../types' @@ -535,26 +535,24 @@ export const DrawPDFFields = (props: Props) => {
{pdfFiles.map((pdfFile, pdfFileIndex: number) => { return ( - <> +
{getPdfPages(pdfFile, pdfFileIndex)} + {pdfFileIndex < pdfFiles.length - 1 && ( + + File Separator + + )}
- {pdfFileIndex < pdfFiles.length - 1 && ( - - File Separator - - )} - +
) })} diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 57e41b0..970e001 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -52,6 +52,7 @@ import { } from '../../utils' import { Container } from '../../components/Container' import styles from './style.module.scss' +import fileListStyles from '../../components/FileList/style.module.scss' import { PdfFile } from '../../types/drawing' import { DrawPDFFields } from '../../components/DrawPDFFields' import { Mark } from '../../types/mark.ts' @@ -69,6 +70,8 @@ export const CreatePage = () => { const navigate = useNavigate() const location = useLocation() const { uploadedFiles } = location.state || {} + const [currentFile, setCurrentFile] = useState() + const isActive = (file: File) => file.name === currentFile?.name const [isLoading, setIsLoading] = useState(false) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('') @@ -281,8 +284,8 @@ export const CreatePage = () => { } } - const handleFileClick = (name: string) => { - document.getElementById(name)?.scrollIntoView({ behavior: 'smooth' }) + const handleFileClick = (id: string) => { + document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) } const handleRemoveFile = ( @@ -737,13 +740,16 @@ export const CreatePage = () => {
    {selectedFiles.length > 0 && selectedFiles.map((file, index) => ( - - +
))} + + {!!error && ( + {error} + )} } > @@ -934,6 +940,8 @@ const DisplayUser = ({ IconComponent={() => null} renderValue={(value) => ( )} @@ -942,9 +950,12 @@ const DisplayUser = ({ } sx={{ fontSize: '16px', - minWidth: '44px', + minWidth: '34px', + maxWidth: '34px', + minHeight: '34px', + maxHeight: '34px', '& .MuiInputBase-input': { - padding: '7px 14px!important', + padding: '10px !important', textOverflow: 'unset!important' }, '& .MuiOutlinedInput-notchedOutline': { @@ -956,9 +967,20 @@ const DisplayUser = ({ {UserRole.viewer} - handleRemoveUser(user.pubkey)}> - - + ) @@ -1073,7 +1095,7 @@ const SignerRow = ({ data-handler-id={handlerId} ref={ref} > - +
null} renderValue={(value) => ( - + )} onChange={(e) => handleUserRoleChange(e.target.value as UserRole, user.pubkey) } sx={{ fontSize: '16px', - minWidth: '44px', + minWidth: '34px', + maxWidth: '34px', + minHeight: '34px', + maxHeight: '34px', '& .MuiInputBase-input': { - padding: '7px 14px!important', + padding: '10px !important', textOverflow: 'unset!important' }, '& .MuiOutlinedInput-notchedOutline': { @@ -1112,9 +1141,20 @@ const SignerRow = ({ {UserRole.viewer} - handleRemoveUser(user.pubkey)}> - - +
) diff --git a/src/pages/create/style.module.scss b/src/pages/create/style.module.scss index b47e2f3..e85323d 100644 --- a/src/pages/create/style.module.scss +++ b/src/pages/create/style.module.scss @@ -104,9 +104,16 @@ .avatar { flex-grow: 1; + min-width: 0; &:first-child { - margin-left: 34px; + margin-left: 24px; + } + + img { + // Override the default avatar size + width: 30px; + height: 30px; } } From 19f7151db7eb8a1122ec5252f14b934f0f676113 Mon Sep 17 00:00:00 2001 From: enes Date: Mon, 19 Aug 2024 18:05:14 +0200 Subject: [PATCH 09/15] refactor(create-page): toolbox update --- src/components/DrawPDFFields/index.tsx | 84 +------- .../DrawPDFFields/style.module.scss | 42 ---- src/pages/create/index.tsx | 181 +++++++++++++++++- src/pages/create/style.module.scss | 47 +++++ src/types/drawing.ts | 15 +- 5 files changed, 245 insertions(+), 124 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 62216e1..7e87cb3 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -1,11 +1,4 @@ -import { - AccessTime, - CalendarMonth, - Gesture, - Badge, - Work, - Close -} from '@mui/icons-material' +import { Close } from '@mui/icons-material' import { Box, CircularProgress, @@ -22,11 +15,10 @@ import * as PDFJS from 'pdfjs-dist' import { ProfileMetadata, User, UserRole } from '../../types' import { PdfFile, - DrawTool, MouseState, PdfPage, DrawnField, - MarkType + DrawTool } from '../../types/drawing' import { truncate } from 'lodash' import { hexToNpub } from '../../utils' @@ -41,48 +33,15 @@ interface Props { users: User[] metadata: { [key: string]: ProfileMetadata } onDrawFieldsChange: (pdfFiles: PdfFile[]) => void + selectedTool?: DrawTool } export const DrawPDFFields = (props: Props) => { - const { selectedFiles } = props + const { selectedFiles, selectedTool } = props const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) - const [selectedTool, setSelectedTool] = useState() - const [toolbox] = useState([ - { - identifier: MarkType.SIGNATURE, - icon: , - label: 'Signature', - active: false - }, - { - identifier: MarkType.FULLNAME, - icon: , - label: 'Full Name', - active: true - }, - { - identifier: MarkType.JOBTITLE, - icon: , - label: 'Job Title', - active: false - }, - { - identifier: MarkType.DATE, - icon: , - label: 'Date', - active: false - }, - { - identifier: MarkType.DATETIME, - icon: , - label: 'Datetime', - active: false - } - ]) - const [mouseState, setMouseState] = useState({ clicked: false }) @@ -385,20 +344,6 @@ export const DrawPDFFields = (props: Props) => { } } - /** - * Changes the drawing tool - * @param drawTool to draw with - */ - const handleToolSelect = (drawTool: DrawTool) => { - // If clicked on the same tool, unselect - if (drawTool.identifier === selectedTool?.identifier) { - setSelectedTool(null) - return - } - - setSelectedTool(drawTool) - } - /** * Renders the pdf pages and drawing elements */ @@ -555,27 +500,6 @@ export const DrawPDFFields = (props: Props) => { ) })} - - - - {toolbox - .filter((drawTool) => drawTool.active) - .map((drawTool: DrawTool, index: number) => { - return ( -
{ - handleToolSelect(drawTool) - }} - className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`} - > - {drawTool.icon} - {drawTool.label} -
- ) - })} -
-
) } diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index e0a09dc..855325e 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -7,48 +7,6 @@ cursor: pointer; } -.drawToolBoxContainer { - position: fixed; - bottom: 0; - left: 0; - right: 0; - display: flex; - justify-content: center; - z-index: 50; - - .drawToolBox { - display: flex; - gap: 10px; - min-width: 100px; - background-color: white; - padding: 15px; - box-shadow: 0 0 10px 1px #0000003b; - border-radius: 4px; - - .toolItem { - display: flex; - flex-direction: column; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.137); - padding: 5px; - cursor: pointer; - -webkit-user-select: none; - user-select: none; - - &.selected { - border-color: #01aaad; - color: #01aaad; - } - - &:not(.selected) { - &:hover { - border-color: #01aaad79; - } - } - } - } -} - .pdfImageWrapper { position: relative; -webkit-user-select: none; diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 35780cb..a544d0f 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -51,16 +51,35 @@ import { import { Container } from '../../components/Container' import styles from './style.module.scss' import fileListStyles from '../../components/FileList/style.module.scss' -import { PdfFile } from '../../types/drawing' +import { DrawTool, MarkType, PdfFile } from '../../types/drawing' import { DrawPDFFields } from '../../components/DrawPDFFields' import { Mark } from '../../types/mark.ts' import { StickySideColumns } from '../../layouts/StickySideColumns.tsx' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { + fa1, + faBriefcase, + faCalendarDays, + faCheckDouble, + faCircleDot, + faClock, + faCreditCard, + faEllipsis, faEye, faGripLines, + faHeading, + faIdCard, + faImage, + faPaperclip, faPen, + faPhone, faPlus, + faSignature, + faSquareCaretDown, + faSquareCheck, + faStamp, + faT, + faTableCellsLarge, faTrash, faUpload } from '@fortawesome/free-solid-svg-icons' @@ -108,6 +127,132 @@ export const CreatePage = () => { ) const [drawnPdfs, setDrawnPdfs] = useState([]) + const [selectedTool, setSelectedTool] = useState() + const [toolbox] = useState([ + { + identifier: MarkType.TEXT, + icon: , + label: 'Text', + active: false + }, + { + identifier: MarkType.SIGNATURE, + icon: , + label: 'Signature', + active: false + }, + { + identifier: MarkType.JOBTITLE, + icon: , + label: 'Job Title', + active: false + }, + { + identifier: MarkType.FULLNAME, + icon: , + label: 'Full Name', + active: true + }, + { + identifier: MarkType.INITIALS, + icon: , + label: 'Initials', + active: false + }, + { + identifier: MarkType.DATETIME, + icon: , + label: 'Date Time', + active: false + }, + { + identifier: MarkType.DATE, + icon: , + label: 'Date', + active: false + }, + { + identifier: MarkType.NUMBER, + icon: , + label: 'Number', + active: false + }, + { + identifier: MarkType.IMAGES, + icon: , + label: 'Images', + active: false + }, + { + identifier: MarkType.CHECKBOX, + icon: , + label: 'Checkbox', + active: false + }, + { + identifier: MarkType.MULTIPLE, + icon: , + label: 'Multiple', + active: false + }, + { + identifier: MarkType.FILE, + icon: , + label: 'File', + active: false + }, + { + identifier: MarkType.RADIO, + icon: , + label: 'Radio', + active: false + }, + { + identifier: MarkType.SELECT, + icon: , + label: 'Select', + active: false + }, + { + identifier: MarkType.CELLS, + icon: , + label: 'Cells', + active: false + }, + { + identifier: MarkType.STAMP, + icon: , + label: 'Stamp', + active: false + }, + { + identifier: MarkType.PAYMENT, + icon: , + label: 'Payment', + active: false + }, + { + identifier: MarkType.PHONE, + icon: , + label: 'Phone', + active: false + } + ]) + + /** + * Changes the drawing tool + * @param drawTool to draw with + */ + const handleToolSelect = (drawTool: DrawTool) => { + // If clicked on the same tool, unselect + if (drawTool.identifier === selectedTool?.identifier) { + setSelectedTool(undefined) + return + } + + setSelectedTool(drawTool) + } + useEffect(() => { users.forEach((user) => { if (!(user.pubkey in metadata)) { @@ -866,6 +1011,39 @@ export const CreatePage = () => { Publish +
+ {toolbox.map((drawTool: DrawTool, index: number) => { + return ( +
{ + handleToolSelect(drawTool) + } + : () => null + } + className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${!drawTool.active ? styles.comingSoon : ''} + `} + > + {drawTool.icon} + {drawTool.label} + {drawTool.active ? ( + + ) : ( + + Coming soon + + )} +
+ ) + })} +
+ {!!error && ( {error} )} @@ -877,6 +1055,7 @@ export const CreatePage = () => { users={users} selectedFiles={selectedFiles} onDrawFieldsChange={onDrawFieldsChange} + selectedTool={selectedTool} /> diff --git a/src/pages/create/style.module.scss b/src/pages/create/style.module.scss index e85323d..1f40fa6 100644 --- a/src/pages/create/style.module.scss +++ b/src/pages/create/style.module.scss @@ -123,3 +123,50 @@ overflow: hidden; flex-grow: 1; } + +.toolbox { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 15px; + + max-height: 450px; + overflow-x: hidden; + overflow-y: auto; +} + +.toolItem { + width: 90px; + height: 90px; + + transition: ease 0.2s; + display: inline-flex; + flex-direction: column; + gap: 5px; + border-radius: 4px; + padding: 10px 5px 5px 5px; + background: rgba(0, 0, 0, 0.05); + color: rgba(0, 0, 0, 0.5); + align-items: center; + justify-content: center; + font-size: 14px; + cursor: pointer; + -webkit-user-select: none; + user-select: none; + + &.selected { + background: $primary-main; + color: white; + } + + &:not(.selected) { + &:hover { + background: $primary-light; + color: white; + } + } + + &.comingSoon { + opacity: 0.5; + cursor: not-allowed; + } +} diff --git a/src/types/drawing.ts b/src/types/drawing.ts index f14dbea..1e65038 100644 --- a/src/types/drawing.ts +++ b/src/types/drawing.ts @@ -41,9 +41,22 @@ export interface DrawTool { } export enum MarkType { + TEXT = 'TEXT', SIGNATURE = 'SIGNATURE', JOBTITLE = 'JOBTITLE', FULLNAME = 'FULLNAME', + INITIALS = 'INITIALS', + DATETIME = 'DATETIME', DATE = 'DATE', - DATETIME = 'DATETIME' + NUMBER = 'NUMBER', + IMAGES = 'IMAGES', + CHECKBOX = 'CHECKBOX', + MULTIPLE = 'MULTIPLE', + FILE = 'FILE', + RADIO = 'RADIO', + SELECT = 'SELECT', + CELLS = 'CELLS', + STAMP = 'STAMP', + PAYMENT = 'PAYMENT', + PHONE = 'PHONE' } From 0d1a7ba17118996d91c57737cfac4b036d796e31 Mon Sep 17 00:00:00 2001 From: enes Date: Mon, 19 Aug 2024 18:16:48 +0200 Subject: [PATCH 10/15] fix(draw): add resize cursor to resize handle --- src/components/DrawPDFFields/style.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 855325e..8c888ec 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -52,7 +52,7 @@ background-color: #fff; border: 1px solid rgb(160, 160, 160); border-radius: 50%; - cursor: pointer; + cursor: nwse-resize; // Increase the area a bit so it's easier to click &::after { From 6f88f22933ddd6bf787c69d0dcaf12032d5ea4f9 Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 20 Aug 2024 09:23:42 +0200 Subject: [PATCH 11/15] fix: leaky styling and warnings Closes #147 --- src/components/FileList/style.module.scss | 1 - .../MarkFormField/style.module.scss | 92 +++++++++---------- src/components/UserAvatar/index.tsx | 2 +- src/pages/create/index.tsx | 5 +- src/pages/create/style.module.scss | 4 + src/pages/home/index.tsx | 6 +- 6 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/components/FileList/style.module.scss b/src/components/FileList/style.module.scss index 9a379ea..22d8515 100644 --- a/src/components/FileList/style.module.scss +++ b/src/components/FileList/style.module.scss @@ -83,7 +83,6 @@ li { } .fileItem:hover { - transition: ease 0.2s; background: #4c82a3; color: white; } diff --git a/src/components/MarkFormField/style.module.scss b/src/components/MarkFormField/style.module.scss index b5c6bb9..ef80df0 100644 --- a/src/components/MarkFormField/style.module.scss +++ b/src/components/MarkFormField/style.module.scss @@ -8,6 +8,39 @@ left: 0; align-items: center; z-index: 1000; + + button { + transition: ease 0.2s; + width: auto; + border-radius: 4px; + outline: unset; + border: unset; + background: unset; + color: #ffffff; + background: #4c82a3; + font-weight: 500; + font-size: 14px; + padding: 8px 15px; + white-space: nowrap; + display: flex; + flex-direction: row; + grid-gap: 12px; + justify-content: center; + align-items: center; + text-decoration: unset; + position: relative; + cursor: pointer; + } + + button:hover { + background: #5e8eab; + color: white; + } + + button:active { + background: #447592; + color: white; + } } .actions { @@ -19,7 +52,7 @@ flex-direction: column; align-items: center; grid-gap: 15px; - box-shadow: 0 -2px 4px 0 rgb(0,0,0,0.1); + box-shadow: 0 -2px 4px 0 rgb(0, 0, 0, 0.1); max-width: 750px; &.expanded { @@ -73,7 +106,7 @@ .textInput { height: 100px; - background: rgba(0,0,0,0.1); + background: rgba(0, 0, 0, 0.1); border-radius: 4px; border: solid 2px #4c82a3; display: flex; @@ -84,17 +117,19 @@ .input { border-radius: 4px; - border: solid 1px rgba(0,0,0,0.15); + border: solid 1px rgba(0, 0, 0, 0.15); padding: 5px 10px; font-size: 16px; width: 100%; - background: linear-gradient(rgba(0,0,0,0.00), rgba(0,0,0,0.00) 100%), linear-gradient(white, white); + background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0) 100%), + linear-gradient(white, white); } .input:focus { - border: solid 1px rgba(0,0,0,0.15); + border: solid 1px rgba(0, 0, 0, 0.15); outline: none; - background: linear-gradient(rgba(0,0,0,0.05), rgba(0,0,0,0.05) 100%), linear-gradient(white, white); + background: linear-gradient(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05) 100%), + linear-gradient(white, white); } .actionsBottom { @@ -105,41 +140,6 @@ align-items: center; } -button { - transition: ease 0.2s; - width: auto; - border-radius: 4px; - outline: unset; - border: unset; - background: unset; - color: #ffffff; - background: #4c82a3; - font-weight: 500; - font-size: 14px; - padding: 8px 15px; - white-space: nowrap; - display: flex; - flex-direction: row; - grid-gap: 12px; - justify-content: center; - align-items: center; - text-decoration: unset; - position: relative; - cursor: pointer; -} - -button:hover { - transition: ease 0.2s; - background: #5e8eab; - color: white; -} - -button:active { - transition: ease 0.2s; - background: #447592; - color: white; -} - .submitButton { width: 100%; max-width: 300px; @@ -172,18 +172,18 @@ button:active { font-size: 12px; padding: 5px 10px; border-radius: 3px; - background: rgba(0,0,0,0.1); - color: rgba(0,0,0,0.5); + background: rgba(0, 0, 0, 0.1); + color: rgba(0, 0, 0, 0.5); } .paginationButton:hover { background: #447592; - color: rgba(255,255,255,0.5); + color: rgba(255, 255, 255, 0.5); } .paginationButtonDone { background: #5e8eab; - color: rgb(255,255,255); + color: rgb(255, 255, 255); } .paginationButtonCurrent { @@ -204,7 +204,7 @@ button:active { background: white; color: #434343; padding: 5px 30px; - box-shadow: 0px -3px 4px 0 rgb(0,0,0,0.1); + box-shadow: 0px -3px 4px 0 rgb(0, 0, 0, 0.1); position: absolute; top: -25px; } diff --git a/src/components/UserAvatar/index.tsx b/src/components/UserAvatar/index.tsx index 9ae60ce..6049a07 100644 --- a/src/components/UserAvatar/index.tsx +++ b/src/components/UserAvatar/index.tsx @@ -30,7 +30,7 @@ export const UserAvatar = ({ pubkey, name, image }: UserAvatarProps) => { padding: 0 }} /> - {name ? : null} + {name ? {name} : null} ) } diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index a544d0f..7da2b79 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -915,7 +915,7 @@ export const CreatePage = () => {
From b12ce258eb83620aa0dae546f146d381b9d61093 Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 20 Aug 2024 09:44:04 +0200 Subject: [PATCH 12/15] fix(create-page): show other file types in content --- src/components/DrawPDFFields/index.tsx | 37 ++++++++++++------- .../DrawPDFFields/style.module.scss | 12 ++++++ src/utils/meta.ts | 8 ++++ 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 7e87cb3..8fb921d 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -21,7 +21,7 @@ import { DrawTool } from '../../types/drawing' import { truncate } from 'lodash' -import { hexToNpub } from '../../utils' +import { extractFileExtension, hexToNpub } from '../../utils' import { toPdfFiles } from '../../utils/pdf.ts' PDFJS.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.mjs', @@ -478,25 +478,34 @@ export const DrawPDFFields = (props: Props) => { return (
- {pdfFiles.map((pdfFile, pdfFileIndex: number) => { + {selectedFiles.map((file, i) => { + const name = file.name + const extension = extractFileExtension(name) + const pdfFile = pdfFiles.find((pdf) => pdf.file.name === name) return ( - +
- {getPdfPages(pdfFile, pdfFileIndex)} - {pdfFileIndex < pdfFiles.length - 1 && ( - - File Separator - + {pdfFile ? ( + getPdfPages(pdfFile, i) + ) : ( +
+ This is a {extension} file +
)}
+ {i < selectedFiles.length - 1 && ( + + File Separator + + )}
) })} diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 8c888ec..142f88a 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -104,3 +104,15 @@ flex-direction: column; gap: 25px; } + +.otherFile { + border-radius: 4px; + background: rgba(255, 255, 255, 0.5); + height: 100px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + color: rgba(0, 0, 0, 0.25); + font-size: 14px; +} diff --git a/src/utils/meta.ts b/src/utils/meta.ts index 276f049..0bee969 100644 --- a/src/utils/meta.ts +++ b/src/utils/meta.ts @@ -190,3 +190,11 @@ export const extractFileExtensions = (fileNames: string[]) => { return { extensions, isSame } } + +/** + * @param fileName - Filename to check + * @returns Extension string + */ +export const extractFileExtension = (fileName: string) => { + return fileName.split('.').pop() +} From bec3c92b03c4127c9f768770640f6c41d0c329be Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 20 Aug 2024 14:28:34 +0200 Subject: [PATCH 13/15] fix: add missing null and reduce warning limit --- package.json | 2 +- src/components/DrawPDFFields/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 88a1439..f1c513c 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 14", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 10", "lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:staged": "eslint --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "formatter:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"", diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 8b8a2a2..d0c4b61 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -328,7 +328,7 @@ export const DrawPDFFields = (props: Props) => { */ const getMouseCoordinates = ( event: React.MouseEvent, - customTarget?: HTMLElement + customTarget?: HTMLElement | null ) => { const target = customTarget ? customTarget : event.currentTarget const rect = target.getBoundingClientRect() From 61f39d17ff4619c2b6beedf7d3189c03278aeede Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 20 Aug 2024 14:38:03 +0200 Subject: [PATCH 14/15] fix(lint): add deps, remove any, update warning limit --- package.json | 2 +- src/pages/sign/index.tsx | 6 ++++-- src/pages/sign/internal/displayMeta.tsx | 2 +- src/types/errors/DecryptionError.ts | 24 ++++++++++++++++-------- src/utils/zip.ts | 6 ++++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index f1c513c..758d63d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 10", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 6", "lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:staged": "eslint --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "formatter:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"", diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index a762292..be755f4 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -236,9 +236,11 @@ export const SignPage = () => { if (!arrayBuffer) return const blob = new Blob([arrayBuffer]) saveAs(blob, `exported-${unixNow()}.sigit.zip`) - } catch (error: any) { + } catch (error) { console.log('error in zip:>> ', error) - toast.error(error.message || 'Error occurred in generating zip file') + if (error instanceof Error) { + toast.error(error.message || 'Error occurred in generating zip file') + } } } diff --git a/src/pages/sign/internal/displayMeta.tsx b/src/pages/sign/internal/displayMeta.tsx index fbc9264..03ba364 100644 --- a/src/pages/sign/internal/displayMeta.tsx +++ b/src/pages/sign/internal/displayMeta.tsx @@ -141,7 +141,7 @@ export const DisplayMeta = ({ }) } }) - }, [users, submittedBy]) + }, [users, submittedBy, metadata]) const downloadFile = async (filename: string) => { const arrayBuffer = await files[filename].file.arrayBuffer() diff --git a/src/types/errors/DecryptionError.ts b/src/types/errors/DecryptionError.ts index 6a174b8..7014ab8 100644 --- a/src/types/errors/DecryptionError.ts +++ b/src/types/errors/DecryptionError.ts @@ -1,18 +1,26 @@ export class DecryptionError extends Error { public message: string = '' - constructor(public inputError: any) { + constructor(public inputError: unknown) { super() - if (inputError.message.toLowerCase().includes('expected')) { - this.message = `The decryption key length or format is invalid.` - } else if ( - inputError.message.includes('The JWK "alg" member was inconsistent') - ) { - this.message = `The decryption key is invalid.` + // Make sure inputError has access to the .message + if (inputError instanceof Error) { + if (inputError.message.toLowerCase().includes('expected')) { + this.message = `The decryption key length or format is invalid.` + } else if ( + inputError.message.includes('The JWK "alg" member was inconsistent') + ) { + this.message = `The decryption key is invalid.` + } else { + this.message = + inputError.message || 'An error occurred while decrypting file.' + } } else { + // We don't have message on the inputError + // Stringify whole error and set that as a message this.message = - inputError.message || 'An error occurred while decrypting file.' + JSON.stringify(inputError) || 'An error occurred while decrypting file.' } this.name = 'DecryptionError' diff --git a/src/utils/zip.ts b/src/utils/zip.ts index 7a7a49f..577dd86 100644 --- a/src/utils/zip.ts +++ b/src/utils/zip.ts @@ -37,9 +37,11 @@ const readContentOfZipEntry = async ( const loadZip = async (data: InputFileFormat): Promise => { try { return await JSZip.loadAsync(data) - } catch (err: any) { + } catch (err) { console.log('err in loading zip file :>> ', err) - toast.error(err.message || 'An error occurred in loading zip file.') + if (err instanceof Error) { + toast.error(err.message || 'An error occurred in loading zip file.') + } return null } } From 404f4aa3a1e8db7ff90300b107496f59a28a539e Mon Sep 17 00:00:00 2001 From: enes Date: Tue, 20 Aug 2024 14:40:12 +0200 Subject: [PATCH 15/15] fix(lint): update warning limit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 758d63d..dc13581 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 6", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 2", "lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint:staged": "eslint --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "formatter:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",