test-crud
Version:
es una prueba acerca de como publicar un package name
324 lines (297 loc) • 10.1 kB
JSX
import React, { Fragment, useEffect, useState } from 'react'
import { Editor, EditorState, CompositeDecorator, Modifier } from 'draft-js'
import { ContentState } from 'draft-js'
import 'draft-js/dist/Draft.css'
import {
// Button,
Divider,
IconButton,
List,
ListItem,
ListItemButton,
ListItemText,
Popover,
Tooltip,
} from '@mui/material'
import { useFormikContext } from 'formik'
import GTranslateIcon from '@mui/icons-material/GTranslate'
import SpellcheckIcon from '@mui/icons-material/Spellcheck'
import useApi from '../../../hooks/useApi'
import { correctorOrtografico } from '../../../api/horasApi'
import LanguagueTranslatorModal from '../modal/LanguagueTranslatorModal'
import styles from './AppTextFieldCorrector.module.css'
// Mock suggestions for demonstration
// Component to display underlined "misspelled" words
const SpellCheckSpan = (props) => {
return (
<span className={styles.checkSpan} onClick={props.onClick}>
{props.children}
</span>
)
}
// Create a decorator to find and style misspelled words
const createSpellCheckDecorator = (onWordClick, sugerencias) =>
new CompositeDecorator([
{
strategy: (contentBlock, callback) => {
const text = contentBlock.getText()
sugerencias &&
sugerencias.forEach(({ token }) => {
text.split(' ').forEach((word, index) => {
if (word.toUpperCase() === token.toUpperCase()) {
const start = text.indexOf(word, index)
callback(start, start + word.length)
}
})
})
},
component: (props) => {
return (
<SpellCheckSpan
{...props}
onClick={() => onWordClick(sugerencias, props)}
/>
)
},
},
])
// Main editor component
const AppTextFieldCorrector = ({ name }) => {
const {
setFieldValue,
setFieldTouched,
errors,
touched,
values,
initialValues,
} = useFormikContext()
const [editorState, setEditorState] = useState(EditorState.createEmpty())
const [showSuggestions, setShowSuggestions] = useState(false)
const [suggestionsPosition, setSuggestionsPosition] = useState({ x: 0, y: 0 })
const [selectedWord, setSelectedWord] = useState('')
const [selectedWordStartPos, setSelectedWordStartPos] = useState('')
const [selectedWordEndPos, setSelectedWordEndPos] = useState('')
const [selectedWordRange, setSelectedWordRange] = useState(null)
const [selectedBlockKey, setSelectedBlockKey] = useState('')
const [sugerencias, setSugerencias] = useState([])
const [openLanguageTranslatorDialog, setOpenLanguageTranslatorDialog] = useState(false)
const [anchorEl, setAnchorEl] = useState(null)
const { request: solicitarCorregir } = useApi(correctorOrtografico, null)
useEffect(() => {
if (initialValues[name]) {
const contentState = ContentState.createFromText(initialValues[name])
const newEditorState = EditorState.createWithContent(contentState)
setEditorState(newEditorState)
}
}, [initialValues[name]])
useEffect(() => {
setFieldValue(
name,
editorState.getCurrentContent().getPlainText().toUpperCase()
)
}, [editorState])
const handleWordClick = (sugerencias, props) => {
const word = props.decoratedText
const wordSuggestion = sugerencias?.find(
({ token }) => token.toUpperCase() === word.toUpperCase()
)
if (wordSuggestion?.suggestions) {
setShowSuggestions(true) // Mostrar sugerencias
setSugerencias(wordSuggestion.suggestions) // Actualizar las sugerencias
} else {
setShowSuggestions(false) // Ocultar sugerencias si no hay sugerencias disponibles
}
const selectionState = props.contentState.getSelectionAfter()
// const boundingRect = window
// .getSelection()
// .getRangeAt(0)
// .getBoundingClientRect()
// setSuggestionsPosition({
// x: boundingRect.x,
// y: boundingRect.y + boundingRect.height,
// })
const rect = window.getSelection().getRangeAt(0).getBoundingClientRect()
setSuggestionsPosition({ x: rect.left, y: rect.bottom })
setAnchorEl(document.querySelector(`.${styles.editorContainer}`))
setSelectedWord(word)
setSelectedWordStartPos(props.start)
setSelectedWordEndPos(props.end)
setSelectedWordRange(selectionState)
setSelectedBlockKey(props.blockKey)
}
const replaceWordWithSuggestion = (suggestion) => {
const currentContent = editorState.getCurrentContent()
const wordRange = selectedWordRange.merge({
anchorKey: selectedBlockKey,
focusKey: selectedBlockKey,
anchorOffset: selectedWordStartPos,
focusOffset: selectedWordEndPos,
})
const contentState = Modifier.replaceText(
currentContent,
wordRange,
suggestion
)
const newState = EditorState.push(editorState, contentState, 'remove-range')
setEditorState(newState)
setShowSuggestions(false)
setAnchorEl(null)
}
const handleTraslate = (translatedText) => {
const contentState = ContentState.createFromText(translatedText)
const newEditorState = EditorState.createWithContent(contentState)
setEditorState(newEditorState)
setOpenLanguageTranslatorDialog(false)
}
const handleChange = (newEditorState) => {
setEditorState(newEditorState)
}
const handleSpellCheck = async () => {
const text = editorState.getCurrentContent().getPlainText().toUpperCase()
const nuevasSugerencias = await solicitarCorregir({
text: text,
})
if (nuevasSugerencias?.length > 0) {
const newDecorator = createSpellCheckDecorator(
handleWordClick,
nuevasSugerencias
)
const withNewDecorator = EditorState.set(editorState, {
decorator: newDecorator,
})
setEditorState(withNewDecorator)
setSugerencias(
nuevasSugerencias?.find(
({ token }) => token === selectedWord.toUpperCase()
)?.suggestions
)
}
}
// const handleClickAddWord = (sugerencias, props) => {
// // console.log('sugerencias << ', sugerencias)
// // console.log('props << ', props)
// console.log('agregar palabra')
// }
const handleClose = () => {
setAnchorEl(null)
}
return (
<div>
<div className={styles.editorContainer}>
<Editor
editorState={editorState}
onChange={handleChange}
onBlur={() => setFieldTouched(name)}
/>
<Tooltip title="Corrector ortográfico" placement="top">
<IconButton
color="info"
aria-label="Corrector de texto"
onClick={handleSpellCheck}
size="small"
>
<SpellcheckIcon fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Traductor" placement="top">
<IconButton
color="secondary"
aria-label="Traducir a ingles"
onClick={async () => {
const contentState = ContentState.createFromText(
editorState.getCurrentContent().getPlainText() || ''
)
const newEditorState = EditorState.createWithContent(contentState)
await setEditorState(newEditorState)
setOpenLanguageTranslatorDialog(true)
}}
size="small"
>
<GTranslateIcon fontSize="small" />
</IconButton>
</Tooltip>
</div>
<Popover
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={handleClose}
anchorReference="anchorPosition"
anchorPosition={{
top: suggestionsPosition.y,
left: suggestionsPosition.x,
}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
{showSuggestions && (
<div className={styles.suggestionsContainer}>
<List
sx={{
maxHeight: '100px',
overflow: 'auto',
boxSizing: 'border-box',
boxShadow: 5,
scrollbarWidth: 'thin',
scrollbarColor: '#fff',
borderRadius: 1,
'&::-webkit-scrollbar': {
width: '6px',
},
'&::-webkit-scrollbar-track': {
backgroundColor: 'none',
},
'&::-webkit-scrollbar-thumb': {
backgroundColor: '#c1c1c1',
borderRadius: '4px',
},
scrollBehavior: 'smooth',
transition: 'scroll-top 0.3s ease-out',
}}
>
{sugerencias?.map((suggestion, index) => (
<Fragment key={index}>
<ListItem disablePadding>
<ListItemButton
onClick={() => replaceWordWithSuggestion(suggestion)}
>
<ListItemText primary={suggestion} />
</ListItemButton>
</ListItem>
<Divider />
</Fragment>
))}
</List>
{/* <Button
variant="text"
onClick={() =>
handleClickAddWord(sugerencias, {
start: selectedWordStartPos,
end: selectedWordEndPos,
contentState: editorState.getCurrentContent(),
})
}
>
Agregar Palabra
</Button> */}
</div>
)}
</Popover>
<LanguagueTranslatorModal
open={openLanguageTranslatorDialog}
onClose={() => setOpenLanguageTranslatorDialog(false)}
onTranslate={handleTraslate}
textToTranslate={editorState
.getCurrentContent()
.getPlainText()
.toUpperCase()}
/>
</div>
)
}
export default AppTextFieldCorrector