feat(create-page): intial layout and page styling

Additional linting fixes
This commit is contained in:
enes 2024-08-15 18:57:40 +02:00
parent 963c8cdd20
commit 51ce2a18f3
4 changed files with 188 additions and 183 deletions

View File

@ -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<PdfFile[]>([])
const [parsingPdf, setParsingPdf] = useState<boolean>(false)
const [showDrawToolBox, setShowDrawToolBox] = useState<boolean>(false)
const [showDrawToolBox] = useState<boolean>(true)
const [selectedTool, setSelectedTool] = useState<DrawTool | null>()
const [toolbox] = useState<DrawTool[]>([
@ -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<HTMLDivElement, 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<HTMLDivElement, 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<HTMLDivElement, 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<HTMLDivElement, 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<HTMLSpanElement, 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<HTMLSpanElement, 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<HTMLSpanElement, 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<HTMLDivElement, 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<HTMLElement, 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 (
<Box
sx={{
width: '100%'
}}
>
<>
{pdfFile.pages.map((page, pdfPageIndex: number) => {
return (
<div
key={pdfPageIndex}
style={{
border: '1px solid #c4c4c4',
marginBottom: '10px'
}}
className={`${styles.pdfImageWrapper} ${selectedTool ? styles.drawing : ''}`}
onMouseMove={(event) => {
onMouseMove(event, page)
@ -516,7 +509,7 @@ export const DrawPDFFields = (props: Props) => {
</div>
)
})}
</Box>
</>
)
}
@ -533,34 +526,26 @@ export const DrawPDFFields = (props: Props) => {
}
return (
<Box>
<Box sx={{ mt: 1 }}>
<Typography sx={{ mb: 1 }}>Draw fields on the PDFs:</Typography>
{pdfFiles.map((pdfFile, pdfFileIndex: number) => {
return (
<Accordion
key={pdfFileIndex}
expanded={pdfFile.expanded}
onChange={(_event, expanded) => {
handleAccordionExpandChange(expanded, pdfFile)
}}
>
<AccordionSummary
expandIcon={<ExpandMore />}
aria-controls={`panel${pdfFileIndex}-content`}
id={`panel${pdfFileIndex}header`}
<div className={styles.view}>
{pdfFiles.map((pdfFile, pdfFileIndex: number) => {
return (
<>
<div className={styles.fileWrapper}>
{getPdfPages(pdfFile, pdfFileIndex)}
</div>
{pdfFileIndex < pdfFiles.length - 1 && (
<Divider
sx={{
fontSize: '12px',
color: 'rgba(0,0,0,0.15)'
}}
>
<PictureAsPdf sx={{ mr: 1 }} />
{pdfFile.file.name}
</AccordionSummary>
<AccordionDetails>
{getPdfPages(pdfFile, pdfFileIndex)}
</AccordionDetails>
</Accordion>
)
})}
</Box>
File Separator
</Divider>
)}
</>
)
})}
{showDrawToolBox && (
<Box className={styles.drawToolBoxContainer}>
@ -569,7 +554,7 @@ export const DrawPDFFields = (props: Props) => {
.filter((drawTool) => drawTool.active)
.map((drawTool: DrawTool, index: number) => {
return (
<Box
<div
key={index}
onClick={() => {
handleToolSelect(drawTool)
@ -578,12 +563,12 @@ export const DrawPDFFields = (props: Props) => {
>
{drawTool.icon}
{drawTool.label}
</Box>
</div>
)
})}
</Box>
</Box>
)}
</Box>
</div>
)
}

View File

@ -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;
}

View File

@ -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 && <LoadingSpinner desc={loadingSpinnerDesc} />}
<Container className={styles.container}>
<TextField
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
variant="outlined"
/>
<StickySideColumns
left={
<>
<TextField
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
variant="outlined"
/>
<Box>
<MuiFileInput
fullWidth
multiple
placeholder="Choose Files"
value={selectedFiles}
onChange={(value) => handleSelectFiles(value)}
<Box>
<MuiFileInput
fullWidth
multiple
placeholder="Choose Files"
value={selectedFiles}
onChange={(value) => handleSelectFiles(value)}
/>
{selectedFiles.length > 0 && (
<ul>
{selectedFiles.map((file, index) => (
<li key={index}>
<Typography component="label">{file.name}</Typography>
<IconButton onClick={() => handleRemoveFile(file)}>
<Clear style={{ color: 'red' }} />{' '}
</IconButton>
</li>
))}
</ul>
)}
</Box>
</>
}
right={
<>
<Typography component="label" variant="h6">
Add Counterparts
</Typography>
<Box className={styles.inputBlock}>
<Box className={styles.inputBlock}>
<TextField
label="nip05 / npub"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
helperText={error}
error={!!error}
/>
<FormControl fullWidth>
<InputLabel id="select-role-label">Role</InputLabel>
<Select
labelId="select-role-label"
id="demo-simple-select"
value={userRole}
label="Role"
onChange={(e) => setUserRole(e.target.value as UserRole)}
>
<MenuItem value={UserRole.signer}>
{UserRole.signer}
</MenuItem>
<MenuItem value={UserRole.viewer}>
{UserRole.viewer}
</MenuItem>
</Select>
</FormControl>
<Box
sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}
>
<Button
disabled={!userInput}
onClick={handleAddUser}
variant="contained"
>
Add
</Button>
</Box>
</Box>
</Box>
<DisplayUser
metadata={metadata}
users={users}
handleUserRoleChange={handleUserRoleChange}
handleRemoveUser={handleRemoveUser}
moveSigner={moveSigner}
/>
<Box
sx={{ mt: 1, mb: 5, display: 'flex', justifyContent: 'center' }}
>
<Button onClick={handleCreate} variant="contained">
Create
</Button>
</Box>
</>
}
>
<DrawPDFFields
metadata={metadata}
users={users}
selectedFiles={selectedFiles}
onDrawFieldsChange={onDrawFieldsChange}
/>
{selectedFiles.length > 0 && (
<ul>
{selectedFiles.map((file, index) => (
<li key={index}>
<Typography component="label">{file.name}</Typography>
<IconButton onClick={() => handleRemoveFile(file)}>
<Clear style={{ color: 'red' }} />{' '}
</IconButton>
</li>
))}
</ul>
)}
</Box>
<Typography component="label" variant="h6">
Add Counterparts
</Typography>
<Box className={styles.inputBlock}>
<Box className={styles.inputBlock}>
<TextField
label="nip05 / npub"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
helperText={error}
error={!!error}
/>
<FormControl fullWidth>
<InputLabel id="select-role-label">Role</InputLabel>
<Select
labelId="select-role-label"
id="demo-simple-select"
value={userRole}
label="Role"
onChange={(e) => setUserRole(e.target.value as UserRole)}
>
<MenuItem value={UserRole.signer}>{UserRole.signer}</MenuItem>
<MenuItem value={UserRole.viewer}>{UserRole.viewer}</MenuItem>
</Select>
</FormControl>
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
<Button
disabled={!userInput}
onClick={handleAddUser}
variant="contained"
>
Add
</Button>
</Box>
</Box>
</Box>
<DisplayUser
metadata={metadata}
users={users}
handleUserRoleChange={handleUserRoleChange}
handleRemoveUser={handleRemoveUser}
moveSigner={moveSigner}
/>
<DrawPDFFields
metadata={metadata}
users={users}
selectedFiles={selectedFiles}
onDrawFieldsChange={onDrawFieldsChange}
/>
<Box sx={{ mt: 1, mb: 5, display: 'flex', justifyContent: 'center' }}>
<Button onClick={handleCreate} variant="contained">
Create
</Button>
</Box>
</StickySideColumns>
</Container>
</>
)

View File

@ -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;