feat: added clear-all button

feat: disable ui elements over eliminating elements
This commit is contained in:
Richard Wong 2026-01-10 13:50:09 +08:00
parent 998cf03865
commit e8f0950dc0
5 changed files with 80 additions and 50 deletions

View File

@ -14,7 +14,7 @@
"live_validation": "Enable live validation", "live_validation": "Enable live validation",
"note_live_validation": "Check this box to enable live validation feedback as you type. Uncheck to only show correctness upon completion.", "note_live_validation": "Check this box to enable live validation feedback as you type. Uncheck to only show correctness upon completion.",
"pick_pack": "Pick your pack(s)", "pick_pack": "Pick your pack(s)",
"shuffle_card": "Shuffle Cards:", "tools": "Tools:",
"verses": "Verses:" "verses": "Verses:"
}, },
"verse_validator": { "verse_validator": {

View File

@ -14,7 +14,7 @@
"live_validation": "Enable live validation", "live_validation": "Enable live validation",
"note_live_validation": "Check this box to enable live validation feedback as you type. Uncheck to only show correctness upon completion.", "note_live_validation": "Check this box to enable live validation feedback as you type. Uncheck to only show correctness upon completion.",
"pick_pack": "Pick your pack(s)", "pick_pack": "Pick your pack(s)",
"shuffle_card": "Shuffle Cards:", "tools": "Tools:",
"verses": "Verses:" "verses": "Verses:"
}, },
"verse_validator": { "verse_validator": {

View File

@ -28,3 +28,20 @@
color: black; color: black;
} }
} }
.setting-disabled {
opacity: 0.5;
}
.tool-bar {
display: flex;
gap: 10px; /* Adjust as needed */
align-items: center;
}
.lang-bar {
display: flex;
gap: 10px; /* Adjust as needed */
align-items: center;
}

View File

@ -16,7 +16,7 @@ import logo from './assets/droplet.svg';
import { Suspense } from "react"; import { Suspense } from "react";
const ArrayTester = ({ array, toHideReference, liveValidation, translate}) => { const ArrayTester = ({ array, toHideReference, liveValidation, clearKey, translate}) => {
const list = array.map((element, index) => ( const list = array.map((element, index) => (
// key needs to be unique; chose 3 elements that will separate all elements // key needs to be unique; chose 3 elements that will separate all elements
<VerseValidator <VerseValidator
@ -24,6 +24,7 @@ const ArrayTester = ({ array, toHideReference, liveValidation, translate}) => {
element={element} element={element}
toHideReference={toHideReference} toHideReference={toHideReference}
liveValidation={liveValidation} liveValidation={liveValidation}
clearKey={clearKey} // Pass clearKey down
t={translate} // this passes the t i18 object to the function t={translate} // this passes the t i18 object to the function
index={index + 1} index={index + 1}
/> />
@ -82,14 +83,20 @@ const loadCustomData = (language) => {
function Page() { function Page() {
// refresh button for refresh // refresh button for refresh
const RefreshButton = ({ onClick }) => { const RefreshButton = ({ onClick, disabled }) => {
return <button onClick={onClick}>Shuffle</button>; return <button onClick={onClick} disabled={disabled}>Shuffle</button>;
}; };
// refresh variables where incrementing state forces refresh // refresh variables where incrementing state forces refresh
const [refreshKey, setRefreshKey] = useState(0); const [shuffleKey, setShuffleKey] = useState(0);
const handleRefresh = () => { const handleShuffle = () => {
// Increment the key to force a re-render // Increment the key to force a re-render
setRefreshKey(refreshKey => refreshKey + 1); setShuffleKey(shuffleKey => shuffleKey + 1);
};
// New state for clearing all inputs
const [clearKey, setClearKey] = useState(0);
const handleClearAll = () => {
setClearKey(clearKey => clearKey + 1);
}; };
// setup i18 for function // setup i18 for function
@ -191,7 +198,7 @@ function Page() {
[] []
); );
return toShuffle ? _.sample(list, testCount) : _.first(list, testCount); return toShuffle ? _.sample(list, testCount) : _.first(list, testCount);
}, [VerseData, checked, testCount, toShuffle, refreshKey]); }, [VerseData, checked, testCount, toShuffle, shuffleKey]);
@ -199,8 +206,12 @@ function Page() {
<div className="App"> <div className="App">
<h1>{t('main.title')}</h1> <h1>{t('main.title')}</h1>
<h2>{t('main.pick_lang')}</h2> <h2>{t('main.pick_lang')}</h2>
<div className="lang-bar">
<button type="button" onClick={() => changeLanguage('en')}>English</button> <button type="button" onClick={() => changeLanguage('en')}>English</button>
<button type="button" onClick={() => changeLanguage('kn')}>Korean</button> <button type="button" onClick={() => changeLanguage('kn')}>Korean</button>
</div>
<h2>{t('main.pick_num_verses')}</h2> <h2>{t('main.pick_num_verses')}</h2>
<label className="test-count-box-label" htmlFor="testCountBox"> <label className="test-count-box-label" htmlFor="testCountBox">
{t('main.num_verses_tested')} {t('main.num_verses_tested')}
@ -237,36 +248,31 @@ function Page() {
</h2> </h2>
<p>{t('main.note_set_shuffle')}</p> <p>{t('main.note_set_shuffle')}</p>
<div> <div className={(toShuffle || toReview) ? 'setting-disabled' : ''}>
{!(toShuffle || toReview) ?
<>
<h2> <h2>
{t('main.hide_reference')} {t('main.hide_reference')}
<input <input
type="checkbox" type="checkbox"
checked={toHideReference} checked={toHideReference}
onChange={handleHideReferenceCheckboxChange} onChange={handleHideReferenceCheckboxChange}
disabled={toShuffle || toReview}
/> />
</h2> </h2>
<p>{t('main.note_hide_reference')}</p> <p>{t('main.note_hide_reference')}</p>
</>:
<p></p>}
</div> </div>
{!(toReview) ? <div className={toReview ? 'setting-disabled' : ''}>
<>
<h2> <h2>
{t('main.live_validation')} {t('main.live_validation')}
<input <input
type="checkbox" type="checkbox"
checked={liveValidation} checked={liveValidation}
onChange={handleLiveValidationCheckboxChange} onChange={handleLiveValidationCheckboxChange}
disabled={toReview}
/> />
</h2> </h2>
<p>{t('main.note_live_validation')}</p> <p>{t('main.note_live_validation')}</p>
</> : </div>
<p></p>
}
<h2>{t('main.pick_pack')}</h2> <h2>{t('main.pick_pack')}</h2>
@ -278,13 +284,10 @@ function Page() {
setExpanded={setExpanded} setExpanded={setExpanded}
/> />
<div key={refreshKey}> <h2>{t('main.tools')}</h2>
{toShuffle ? <div className="tool-bar">
<> <RefreshButton onClick={handleShuffle} disabled={!toShuffle} />
<h2>{t('main.shuffle_card')}</h2> <button onClick={handleClearAll}>Clear All</button>
<RefreshButton onClick={handleRefresh} />
</>:
<p></p>}
</div> </div>
<h1>{t('main.verses')}</h1> <h1>{t('main.verses')}</h1>
@ -297,6 +300,7 @@ function Page() {
array={testList} array={testList}
toHideReference={toHideReference} toHideReference={toHideReference}
liveValidation={liveValidation} liveValidation={liveValidation}
clearKey={clearKey} // Pass clearKey down
translate={t} translate={t}
/> />
} }

View File

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState, useEffect, useRef } from "react";
import "./VerseValidator.css"; import "./VerseValidator.css";
import { StringDiff } from "react-string-diff"; import { StringDiff } from "react-string-diff";
import { containsKorean, jamoSubstringMatch } from './utils'; import { containsKorean, jamoSubstringMatch } from './utils';
@ -12,7 +12,7 @@ const STATE = {
// function to render and handle logic of each of the cells // function to render and handle logic of each of the cells
const VerseValidator = ({ element: { pack, title, chapterTitle, reference, verse } , toHideReference, liveValidation, t, index}) => { // useful use of destructuring here const VerseValidator = ({ element: { pack, title, chapterTitle, reference, verse } , toHideReference, liveValidation, clearKey, t, index}) => { // useful use of destructuring here
const [inputReference, setReference] = useState('') const [inputReference, setReference] = useState('')
const [referenceBool, setReferenceBool] = useState(STATE.INCORRECT) const [referenceBool, setReferenceBool] = useState(STATE.INCORRECT)
const [inputChapterTitle, setChapterTitle] = useState('') const [inputChapterTitle, setChapterTitle] = useState('')
@ -24,6 +24,15 @@ const VerseValidator = ({ element: { pack, title, chapterTitle, reference, verse
const [hintBool, setHintBool] = useState(false) const [hintBool, setHintBool] = useState(false)
const [diffBool, setDiffBool] = useState(false) const [diffBool, setDiffBool] = useState(false)
const [isComposing, setIsComposing] = useState(false); const [isComposing, setIsComposing] = useState(false);
const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
handleReset();
}
}, [clearKey]);
useEffect(() => { useEffect(() => {
// Re-run validation for all fields when liveValidation changes // Re-run validation for all fields when liveValidation changes