2024-08-11 22:19:26 +03:00
|
|
|
import { CurrentUserMark } from '../../types/mark.ts'
|
|
|
|
import {
|
|
|
|
findNextIncompleteCurrentUserMark,
|
2024-10-11 15:05:28 +02:00
|
|
|
getToolboxLabelByMarkType,
|
2024-08-11 22:19:26 +03:00
|
|
|
isCurrentUserMarksComplete,
|
|
|
|
isCurrentValueLast
|
|
|
|
} from '../../utils'
|
2024-08-20 14:21:45 +03:00
|
|
|
import React, { useState } from 'react'
|
2024-11-18 17:20:20 +01:00
|
|
|
import { MarkInput } from '../MarkTypeStrategy/MarkInput.tsx'
|
2024-12-06 13:24:10 +01:00
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
|
|
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
2024-12-13 13:36:44 +01:00
|
|
|
import { Button } from '@mui/material'
|
|
|
|
import styles from './style.module.scss'
|
2024-08-11 22:19:26 +03:00
|
|
|
|
|
|
|
interface MarkFormFieldProps {
|
|
|
|
currentUserMarks: CurrentUserMark[]
|
|
|
|
handleCurrentUserMarkChange: (mark: CurrentUserMark) => void
|
2024-10-25 18:42:16 +02:00
|
|
|
handleSelectedMarkValueChange: (value: string) => void
|
2024-12-06 13:24:10 +01:00
|
|
|
handleSubmit: (event: React.MouseEvent<HTMLButtonElement>) => void
|
2024-08-20 14:21:45 +03:00
|
|
|
selectedMark: CurrentUserMark
|
|
|
|
selectedMarkValue: string
|
2024-08-11 22:19:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Responsible for rendering a form field connected to a mark and keeping track of its value.
|
|
|
|
*/
|
|
|
|
const MarkFormField = ({
|
|
|
|
handleSubmit,
|
|
|
|
handleSelectedMarkValueChange,
|
|
|
|
selectedMark,
|
|
|
|
selectedMarkValue,
|
|
|
|
currentUserMarks,
|
|
|
|
handleCurrentUserMarkChange
|
|
|
|
}: MarkFormFieldProps) => {
|
2024-08-12 12:32:36 +03:00
|
|
|
const [displayActions, setDisplayActions] = useState(true)
|
2024-12-06 13:24:10 +01:00
|
|
|
const [complete, setComplete] = useState(false)
|
|
|
|
|
2024-08-11 22:19:26 +03:00
|
|
|
const isReadyToSign = () =>
|
|
|
|
isCurrentUserMarksComplete(currentUserMarks) ||
|
|
|
|
isCurrentValueLast(currentUserMarks, selectedMark, selectedMarkValue)
|
|
|
|
const isCurrent = (currentMark: CurrentUserMark) =>
|
2024-12-06 13:24:10 +01:00
|
|
|
currentMark.id === selectedMark.id && !complete
|
2024-08-12 12:08:53 +03:00
|
|
|
const isDone = (currentMark: CurrentUserMark) =>
|
|
|
|
isCurrent(currentMark) ? !!selectedMarkValue : currentMark.isCompleted
|
2024-08-11 22:19:26 +03:00
|
|
|
const findNext = () => {
|
|
|
|
return (
|
|
|
|
currentUserMarks[selectedMark.id] ||
|
|
|
|
findNextIncompleteCurrentUserMark(currentUserMarks)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
|
|
|
event.preventDefault()
|
|
|
|
console.log('handle form submit runs...')
|
2024-12-06 13:24:10 +01:00
|
|
|
|
|
|
|
// Without this line, we lose mark values when switching
|
|
|
|
handleCurrentUserMarkChange(selectedMark)
|
|
|
|
|
|
|
|
if (!complete) {
|
|
|
|
isReadyToSign()
|
|
|
|
? setComplete(true)
|
|
|
|
: handleCurrentUserMarkChange(findNext()!)
|
|
|
|
}
|
2024-08-11 22:19:26 +03:00
|
|
|
}
|
2024-12-06 13:24:10 +01:00
|
|
|
|
2024-08-12 12:32:36 +03:00
|
|
|
const toggleActions = () => setDisplayActions(!displayActions)
|
2024-10-11 15:05:28 +02:00
|
|
|
const markLabel = getToolboxLabelByMarkType(selectedMark.mark.type)
|
2024-11-18 17:20:20 +01:00
|
|
|
|
2024-12-06 13:24:10 +01:00
|
|
|
const handleCurrentUserMarkClick = (mark: CurrentUserMark) => {
|
|
|
|
setComplete(false)
|
|
|
|
handleCurrentUserMarkChange(mark)
|
|
|
|
}
|
|
|
|
|
|
|
|
const handleSelectCompleteMark = () => {
|
|
|
|
handleCurrentUserMarkChange(selectedMark)
|
|
|
|
setComplete(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
const handleSignAndComplete = (
|
|
|
|
event: React.MouseEvent<HTMLButtonElement>
|
|
|
|
) => {
|
|
|
|
handleSubmit(event)
|
|
|
|
}
|
|
|
|
|
2024-08-11 22:19:26 +03:00
|
|
|
return (
|
|
|
|
<div className={styles.container}>
|
2024-08-12 12:08:53 +03:00
|
|
|
<div className={styles.trigger}>
|
2024-08-12 12:32:36 +03:00
|
|
|
<button
|
|
|
|
onClick={toggleActions}
|
|
|
|
className={styles.triggerBtn}
|
|
|
|
type="button"
|
2024-10-07 12:59:55 +02:00
|
|
|
title="Toggle"
|
2024-08-12 12:32:36 +03:00
|
|
|
>
|
|
|
|
<svg
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
viewBox="-64 0 512 512"
|
|
|
|
width="1em"
|
|
|
|
height="1em"
|
|
|
|
fill="currentColor"
|
|
|
|
transform={displayActions ? 'rotate(180)' : 'rotate(0)'}
|
|
|
|
>
|
|
|
|
<path d="M352 352c-8.188 0-16.38-3.125-22.62-9.375L192 205.3l-137.4 137.4c-12.5 12.5-32.75 12.5-45.25 0s-12.5-32.75 0-45.25l160-160c12.5-12.5 32.75-12.5 45.25 0l160 160c12.5 12.5 12.5 32.75 0 45.25C368.4 348.9 360.2 352 352 352z"></path>
|
|
|
|
</svg>
|
|
|
|
</button>
|
2024-08-12 12:08:53 +03:00
|
|
|
</div>
|
2024-08-12 12:32:36 +03:00
|
|
|
<div className={`${styles.actions} ${displayActions && styles.expanded}`}>
|
2024-08-11 22:19:26 +03:00
|
|
|
<div className={styles.actionsWrapper}>
|
|
|
|
<div className={styles.actionsTop}>
|
|
|
|
<div className={styles.actionsTopInfo}>
|
2024-12-06 13:24:10 +01:00
|
|
|
{!complete && (
|
|
|
|
<p className={styles.actionsTopInfoText}>Add {markLabel}</p>
|
|
|
|
)}
|
|
|
|
{complete && <p className={styles.actionsTopInfoText}>Finish</p>}
|
2024-08-11 22:19:26 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className={styles.inputWrapper}>
|
2024-12-06 13:24:10 +01:00
|
|
|
{!complete && (
|
|
|
|
<form onSubmit={(e) => handleFormSubmit(e)}>
|
|
|
|
<MarkInput
|
|
|
|
markType={selectedMark.mark.type}
|
|
|
|
key={selectedMark.id}
|
|
|
|
value={selectedMarkValue}
|
|
|
|
placeholder={markLabel}
|
|
|
|
handler={handleSelectedMarkValueChange}
|
|
|
|
userMark={selectedMark}
|
|
|
|
/>
|
|
|
|
<div className={styles.actionsBottom}>
|
2024-12-13 13:36:44 +01:00
|
|
|
<Button type="submit" className={styles.submitButton}>
|
2024-12-06 13:24:10 +01:00
|
|
|
NEXT
|
2024-12-13 13:36:44 +01:00
|
|
|
</Button>
|
2024-12-06 13:24:10 +01:00
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{complete && (
|
2024-08-11 22:19:26 +03:00
|
|
|
<div className={styles.actionsBottom}>
|
2024-12-13 13:36:44 +01:00
|
|
|
<Button
|
2024-12-06 13:24:10 +01:00
|
|
|
onClick={handleSignAndComplete}
|
2024-12-13 13:44:17 +01:00
|
|
|
className={[styles.submitButton, styles.completeButton].join(
|
|
|
|
' '
|
|
|
|
)}
|
2024-12-06 13:24:10 +01:00
|
|
|
disabled={!isReadyToSign()}
|
2024-12-13 13:36:44 +01:00
|
|
|
autoFocus
|
2024-12-06 13:24:10 +01:00
|
|
|
>
|
|
|
|
SIGN AND COMPLETE
|
2024-12-13 13:36:44 +01:00
|
|
|
</Button>
|
2024-08-11 22:19:26 +03:00
|
|
|
</div>
|
2024-12-06 13:24:10 +01:00
|
|
|
)}
|
|
|
|
|
2024-08-11 22:19:26 +03:00
|
|
|
<div className={styles.footerContainer}>
|
|
|
|
<div className={styles.footer}>
|
|
|
|
{currentUserMarks.map((mark, index) => {
|
|
|
|
return (
|
|
|
|
<div className={styles.pagination} key={index}>
|
|
|
|
<button
|
2024-12-13 13:36:44 +01:00
|
|
|
type="button"
|
2024-11-11 16:21:22 +01:00
|
|
|
className={`${styles.paginationButton} ${isDone(mark) ? styles.paginationButtonDone : ''}`}
|
2024-12-06 13:24:10 +01:00
|
|
|
onClick={() => handleCurrentUserMarkClick(mark)}
|
2024-08-11 22:19:26 +03:00
|
|
|
>
|
|
|
|
{mark.id}
|
|
|
|
</button>
|
|
|
|
{isCurrent(mark) && (
|
|
|
|
<div className={styles.paginationButtonCurrent}></div>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})}
|
2024-12-06 13:24:10 +01:00
|
|
|
<div className={styles.pagination}>
|
|
|
|
<button
|
2024-12-13 13:36:44 +01:00
|
|
|
type="button"
|
2024-12-06 13:24:10 +01:00
|
|
|
className={`${styles.paginationButton} ${isReadyToSign() ? styles.paginationButtonDone : ''}`}
|
|
|
|
onClick={handleSelectCompleteMark}
|
2024-12-13 13:36:44 +01:00
|
|
|
title="Complete"
|
2024-12-06 13:24:10 +01:00
|
|
|
>
|
|
|
|
<FontAwesomeIcon
|
|
|
|
className={styles.finishPage}
|
|
|
|
icon={faCheck}
|
|
|
|
/>
|
|
|
|
</button>
|
|
|
|
{complete && (
|
|
|
|
<div className={styles.paginationButtonCurrent}></div>
|
|
|
|
)}
|
|
|
|
</div>
|
2024-08-11 22:19:26 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default MarkFormField
|