193 lines
6.6 KiB
TypeScript
Raw Normal View History

import { CurrentUserMark } from '../../types/mark.ts'
import {
findNextIncompleteCurrentUserMark,
2024-10-11 15:05:28 +02:00
getToolboxLabelByMarkType,
isCurrentUserMarksComplete,
isCurrentValueLast
} from '../../utils'
2024-08-20 14:21:45 +03:00
import React, { useState } from 'react'
import { MarkInput } from '../MarkTypeStrategy/MarkInput.tsx'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCheck } from '@fortawesome/free-solid-svg-icons'
import { Button } from '@mui/material'
import styles from './style.module.scss'
interface MarkFormFieldProps {
currentUserMarks: CurrentUserMark[]
handleCurrentUserMarkChange: (mark: CurrentUserMark) => void
2024-10-25 18:42:16 +02:00
handleSelectedMarkValueChange: (value: string) => void
handleSubmit: (event: React.MouseEvent<HTMLButtonElement>) => void
2024-08-20 14:21:45 +03:00
selectedMark: CurrentUserMark
selectedMarkValue: string
}
/**
* 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)
const [complete, setComplete] = useState(false)
const isReadyToSign = () =>
isCurrentUserMarksComplete(currentUserMarks) ||
isCurrentValueLast(currentUserMarks, selectedMark, selectedMarkValue)
const isCurrent = (currentMark: CurrentUserMark) =>
currentMark.id === selectedMark.id && !complete
2024-08-12 12:08:53 +03:00
const isDone = (currentMark: CurrentUserMark) =>
isCurrent(currentMark) ? !!selectedMarkValue : currentMark.isCompleted
const findNext = () => {
return (
currentUserMarks[selectedMark.id] ||
findNextIncompleteCurrentUserMark(currentUserMarks)
)
}
const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
console.log('handle form submit runs...')
// Without this line, we lose mark values when switching
handleCurrentUserMarkChange(selectedMark)
if (!complete) {
isReadyToSign()
? setComplete(true)
: handleCurrentUserMarkChange(findNext()!)
}
}
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)
const handleCurrentUserMarkClick = (mark: CurrentUserMark) => {
setComplete(false)
handleCurrentUserMarkChange(mark)
}
const handleSelectCompleteMark = () => {
handleCurrentUserMarkChange(selectedMark)
setComplete(true)
}
const handleSignAndComplete = (
event: React.MouseEvent<HTMLButtonElement>
) => {
handleSubmit(event)
}
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"
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}`}>
<div className={styles.actionsWrapper}>
<div className={styles.actionsTop}>
<div className={styles.actionsTopInfo}>
{!complete && (
<p className={styles.actionsTopInfoText}>Add {markLabel}</p>
)}
{complete && <p className={styles.actionsTopInfoText}>Finish</p>}
</div>
</div>
<div className={styles.inputWrapper}>
{!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}>
<Button type="submit" className={styles.submitButton}>
NEXT
</Button>
</div>
</form>
)}
{complete && (
<div className={styles.actionsBottom}>
<Button
onClick={handleSignAndComplete}
className={[styles.submitButton, styles.completeButton].join(
' '
)}
disabled={!isReadyToSign()}
autoFocus
>
SIGN AND COMPLETE
</Button>
</div>
)}
<div className={styles.footerContainer}>
<div className={styles.footer}>
{currentUserMarks.map((mark, index) => {
return (
<div className={styles.pagination} key={index}>
<button
type="button"
className={`${styles.paginationButton} ${isDone(mark) ? styles.paginationButtonDone : ''}`}
onClick={() => handleCurrentUserMarkClick(mark)}
>
{mark.id}
</button>
{isCurrent(mark) && (
<div className={styles.paginationButtonCurrent}></div>
)}
</div>
)
})}
<div className={styles.pagination}>
<button
type="button"
className={`${styles.paginationButton} ${isReadyToSign() ? styles.paginationButtonDone : ''}`}
onClick={handleSelectCompleteMark}
title="Complete"
>
<FontAwesomeIcon
className={styles.finishPage}
icon={faCheck}
/>
</button>
{complete && (
<div className={styles.paginationButtonCurrent}></div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default MarkFormField