import { Button, Group, Stack, Text, Box, Transition } from "@mantine/core"; import classes from './InputChain.module.css' import { useEffect, useState } from "react"; interface InputChainProps { text: string; hidden: number; onPassed: () => void; onNotPassed?: () => void; size?: string; w?: number; } export function InputChainHidden(props : InputChainProps) { const text = props.text; if(text.trim() == ""){ return (<>); } const words = text.split(" "); const [hiddenIndices, setHiddenIndices] = useState([]); const [selectedWords, setSelectedWords] = useState<(string | null)[]>([]); const [availableWords, setAvailableWords] = useState([]); const [wrongIndices, setWrongIndices] = useState([]); const [correctIndices, setCorrectIndices] = useState([]); const [mounted, setMounted] = useState(false); useEffect(() => { let hidden : number[] = []; while (hidden.length < props.hidden) { let num = Math.floor(Math.random() * words.length); if(hidden.indexOf(num) == -1){ hidden.push(num); } } hidden.sort((a, b) => a - b); setHiddenIndices(hidden); const hiddenWords = hidden.map(idx => words[idx]); const shuffled = [...hiddenWords].sort(() => Math.random() - 0.5); setAvailableWords(shuffled); setSelectedWords(new Array(hidden.length).fill(null)); setTimeout(() => setMounted(true), 100); }, []); const handleWordClick = (word: string) => { const firstEmptyIndex = selectedWords.findIndex(w => w === null); if (firstEmptyIndex !== -1) { const newSelected = [...selectedWords]; newSelected[firstEmptyIndex] = word; setSelectedWords(newSelected); setAvailableWords(availableWords.filter(w => w !== word)); checkIfPassed(newSelected); validateWords(newSelected); } }; const handleRemoveWord = (index: number) => { const word = selectedWords[index]; if (word) { const newSelected = [...selectedWords]; newSelected[index] = null; setSelectedWords(newSelected); setAvailableWords([...availableWords, word]); if(props.onNotPassed){ props.onNotPassed(); } validateWords(newSelected); } }; const validateWords = (selected: (string | null)[]) => { const wrong: number[] = []; const correct: number[] = []; selected.forEach((word, idx) => { if (word !== null) { if (word === words[hiddenIndices[idx]]) { correct.push(idx); } else { wrong.push(idx); } } }); setWrongIndices(wrong); setCorrectIndices(correct); }; const checkIfPassed = (selected: (string | null)[]) => { const allFilled = selected.every(w => w !== null); if (allFilled) { const isCorrect = selected.every((word, idx) => word === words[hiddenIndices[idx]] ); if (isCorrect) { props.onPassed(); } else if(props.onNotPassed) { props.onNotPassed(); } } else { if(props.onNotPassed){ props.onNotPassed(); } } }; return ( {/* Target area - where words should be placed */} {(styles) => ( Click the words in the correct order: {words.map((word, i) => { const hiddenIdx = hiddenIndices.indexOf(i); const isHidden = hiddenIdx !== -1; if (!isHidden) { return ( {i + 1}. {word} ); } const isWrong = wrongIndices.includes(hiddenIdx); const isCorrect = correctIndices.includes(hiddenIdx); return ( ); })} )} {/* Available words area */} {(transitionStyles) => ( Available words: {availableWords.map((word, idx) => ( ))} )} ); }