possible answers fix, next path fix, prettier format

This commit is contained in:
mrfry 2023-04-10 14:46:17 +02:00
parent e17bbe6402
commit 70b53e89aa
9 changed files with 377 additions and 360 deletions

View file

@ -1,3 +1,3 @@
module.exports = { module.exports = {
basePath: '/data-editor', basePath: '/dataeditor',
} }

View file

@ -3,9 +3,9 @@ import React from 'react'
import styles from './LoadingIndicator.module.css' import styles from './LoadingIndicator.module.css'
export default function LoadingIndicator() { export default function LoadingIndicator() {
return ( return (
<div className={styles.loadContainer}> <div className={styles.loadContainer}>
<div className={styles.load} /> <div className={styles.load} />
</div> </div>
) )
} }

View file

@ -5,125 +5,130 @@ import styles from './question.module.css'
const overflowLength = 140 const overflowLength = 140
export default function Question({ question, onChange, index }) { export default function Question({ question, onChange, index }) {
// FIXME: focus change when input changes to textarea // FIXME: focus change when input changes to textarea
const possibleAnswers = const possibleAnswers =
question.possibleAnswers || question.data.possibleAnswers question.possibleAnswers || question.data.possibleAnswers
return ( return (
<div className={styles.questionContainer}> <div className={styles.questionContainer}>
{question.Q && question.Q.length > overflowLength ? ( {question.Q && question.Q.length > overflowLength ? (
<textarea <textarea
placeholder="Kérdés..." placeholder="Kérdés..."
value={question.Q} value={question.Q}
onChange={(e) => { onChange={(e) => {
onChange({
...question,
Q: e.target.value,
})
}}
/>
) : (
<input
placeholder="Kérdés..."
type="text"
value={question.Q}
onChange={(e) => {
onChange({
...question,
Q: e.target.value,
})
}}
/>
)}
{question.A && question.A.length > overflowLength ? (
<textarea
placeholder="Helyes válasz..."
value={question.A}
onChange={(e) => {
onChange({
...question,
A: e.target.value,
})
}}
/>
) : (
<input
placeholder="Helyes válasz..."
type="text"
value={question.A}
onChange={(e) => {
onChange({
...question,
A: e.target.value,
})
}}
/>
)}
{possibleAnswers && possibleAnswers.length > 0 ? (
<>
<div className={styles.text}>Lehetséges válaszok:</div>
<div className={styles.possibleAnswers}>
{possibleAnswers.map((possibleAnswer, i) => {
// {"text":"a. Kétismeretlenes egyenletrendszert használunk.",
// "selectedByUser":true}
const pa =
typeof possibleAnswer === 'string'
? possibleAnswer
: possibleAnswer.text
return (
<div key={i}>
<div>
<input
onChange={() => {
onChange({ onChange({
...question, ...question,
A: pa, Q: e.target.value,
}) })
}}
checked={pa === question.A}
value={pa}
type="radio"
name={`possiblea${index ? index : ''}`}
/>
<span>{pa}</span>
</div>
<span
onClick={() => {
const newPossibleAnswers = possibleAnswers.filter(
(pa, j) => {
return j !== i
}
)
// FIXME: 2 possible answers?
onChange({
...question,
data: {
...question.data,
possibleAnswers: newPossibleAnswers,
},
possibleAnswers: newPossibleAnswers,
})
}} }}
className={styles.delete} />
> ) : (
Törlés <input
</span> placeholder="Kérdés..."
</div> type="text"
) value={question.Q}
})} onChange={(e) => {
</div> onChange({
</> ...question,
) : null} Q: e.target.value,
<input })
type="text" }}
value={JSON.stringify(question.data)} />
name="data" )}
onChange={(e) => { {question.A && question.A.length > overflowLength ? (
console.log(e.target.value) <textarea
}} placeholder="Helyes válasz..."
/> value={question.A}
</div> onChange={(e) => {
) onChange({
...question,
A: e.target.value,
})
}}
/>
) : (
<input
placeholder="Helyes válasz..."
type="text"
value={question.A}
onChange={(e) => {
onChange({
...question,
A: e.target.value,
})
}}
/>
)}
{possibleAnswers && possibleAnswers.length > 0 ? (
<>
<div className={styles.text}>Lehetséges válaszok:</div>
<div className={styles.possibleAnswers}>
{possibleAnswers.map((possibleAnswer, i) => {
// {"text":"a. Kétismeretlenes egyenletrendszert használunk.",
// "selectedByUser":true}
const pa =
typeof possibleAnswer === 'string'
? possibleAnswer
: possibleAnswer.val
return (
<div key={i}>
<div>
<input
onChange={() => {
onChange({
...question,
A: pa,
})
}}
checked={pa === question.A}
value={pa}
type="radio"
name={`possiblea${
index ? index : ''
}`}
/>
<span>{pa}</span>
</div>
<span
onClick={() => {
const newPossibleAnswers =
possibleAnswers.filter(
(pa, j) => {
return j !== i
}
)
// FIXME: 2 possible answers?
onChange({
...question,
data: {
...question.data,
possibleAnswers:
newPossibleAnswers,
},
possibleAnswers:
newPossibleAnswers,
})
}}
className={styles.delete}
>
Törlés
</span>
</div>
)
})}
</div>
</>
) : null}
<input
type="text"
value={JSON.stringify(question.data)}
name="data"
onChange={(e) => {
console.log(e.target.value)
}}
/>
</div>
)
} }

View file

@ -6,80 +6,86 @@ import styles from './Questions.module.css'
import commonStyles from '../commonStyles.module.css' import commonStyles from '../commonStyles.module.css'
class Questions extends PureComponent { class Questions extends PureComponent {
render() { render() {
const { subjs, onChange } = this.props const { subjs, onChange } = this.props
return ( return (
<div> <div>
{subjs.map((subj) => { {subjs.map((subj) => {
return ( return (
<div key={subj.Name}> <div key={subj.Name}>
<div className={styles.subjName}>{subj.Name}</div> <div className={styles.subjName}>{subj.Name}</div>
{subj.Questions.map((qo, i) => { {subj.Questions.map((qo, i) => {
const question = qo.q const question = qo.q
const unsaved = qo.unsaved const unsaved = qo.unsaved
return ( return (
<React.Fragment key={i}> <React.Fragment key={i}>
<hr /> <hr />
<div className={`${unsaved ? styles.unsaved : ''}`}> <div
<Question className={`${
index={`${subj.Name}_${i}`} unsaved ? styles.unsaved : ''
question={question} }`}
onChange={(newVal) => { >
onChange({ <Question
index: i, index={`${subj.Name}_${i}`}
subjName: subj.Name, question={question}
type: 'edit', onChange={(newVal) => {
newVal: newVal, onChange({
}) index: i,
}} subjName: subj.Name,
/> type: 'edit',
<div className={commonStyles.actions}> newVal: newVal,
<div })
onClick={() => { }}
onChange({ />
index: i, <div
subjName: subj.Name, className={commonStyles.actions}
type: 'reset', >
}) <div
}} onClick={() => {
> onChange({
Visszaállítás index: i,
subjName: subj.Name,
type: 'reset',
})
}}
>
Visszaállítás
</div>
<div
onClick={() => {
onChange({
index: i,
subjName: subj.Name,
type: 'save',
})
}}
>
Mentés
</div>
<div
onClick={() => {
onChange({
index: i,
subjName: subj.Name,
type: 'delete',
})
}}
>
Törlés
</div>
</div>
</div>
</React.Fragment>
)
})}
</div> </div>
<div )
onClick={() => { })}
onChange({
index: i,
subjName: subj.Name,
type: 'save',
})
}}
>
Mentés
</div>
<div
onClick={() => {
onChange({
index: i,
subjName: subj.Name,
type: 'delete',
})
}}
>
Törlés
</div>
</div>
</div>
</React.Fragment>
)
})}
</div> </div>
) )
})} }
</div>
)
}
} }
export default Questions export default Questions

View file

@ -6,96 +6,98 @@ import styles from './subject.module.css'
import commonStyles from '../commonStyles.module.css' import commonStyles from '../commonStyles.module.css'
function DeletedQuestion({ reset }) { function DeletedQuestion({ reset }) {
return ( return (
<div> <div>
<div className={styles.deletedQuestion}>Törölt kérdés</div> <div className={styles.deletedQuestion}>Törölt kérdés</div>
<div className={commonStyles.actions}> <div className={commonStyles.actions}>
<div <div
onClick={() => { onClick={() => {
reset() reset()
}} }}
> >
Visszaállítás Visszaállítás
</div>
</div>
</div> </div>
</div> )
</div>
)
} }
export default function Subject(props) { export default function Subject(props) {
const { const {
subj, subj,
unsavedIndexes, unsavedIndexes,
deletedIndexes, deletedIndexes,
editedIndexes, editedIndexes,
resetQuestion, resetQuestion,
handleQuestionChange, handleQuestionChange,
saveQuestion, saveQuestion,
deleteQuestion, deleteQuestion,
} = props } = props
if (subj) { if (subj) {
return ( return (
<div className={styles.questionContainer}> <div className={styles.questionContainer}>
{subj.Questions.map((question, i) => { {subj.Questions.map((question, i) => {
// FIXME: list edited questions first? // FIXME: list edited questions first?
const unsaved = unsavedIndexes.includes(i) const unsaved = unsavedIndexes.includes(i)
const edited = editedIndexes.includes(i) const edited = editedIndexes.includes(i)
const deleted = deletedIndexes.includes(i) const deleted = deletedIndexes.includes(i)
return ( return (
<React.Fragment key={i}> <React.Fragment key={i}>
<hr /> <hr />
{deleted ? ( {deleted ? (
<DeletedQuestion <DeletedQuestion
reset={() => { reset={() => {
resetQuestion(i) resetQuestion(i)
}} }}
index={i} index={i}
/> />
) : ( ) : (
<div <div
className={`${unsaved ? styles.unsaved : ''} ${ className={`${
edited ? styles.edited : '' unsaved ? styles.unsaved : ''
}`} } ${edited ? styles.edited : ''}`}
> >
<Question <Question
index={i} index={i}
onChange={(newq) => { onChange={(newq) => {
handleQuestionChange(newq, i) handleQuestionChange(newq, i)
}} }}
question={question} question={question}
/> />
<div className={commonStyles.actions}> <div className={commonStyles.actions}>
<div <div
onClick={() => { onClick={() => {
resetQuestion(i) resetQuestion(i)
}} }}
> >
Visszaállítás Visszaállítás
</div> </div>
<div <div
onClick={() => { onClick={() => {
saveQuestion(i) saveQuestion(i)
}} }}
> >
{edited ? 'Kérdés mentve' : 'Kérdés mentése'} {edited
</div> ? 'Kérdés mentve'
<div : 'Kérdés mentése'}
onClick={() => { </div>
deleteQuestion(i) <div
}} onClick={() => {
> deleteQuestion(i)
Kérdés törlése }}
</div> >
</div> Kérdés törlése
</div> </div>
)} </div>
</React.Fragment> </div>
) )}
})} </React.Fragment>
</div> )
) })}
} else { </div>
return <div /> )
} } else {
return <div />
}
} }

View file

@ -3,32 +3,34 @@ import React from 'react'
import styles from './SubjectSelector.module.css' import styles from './SubjectSelector.module.css'
export default function SubjectSelector(props) { export default function SubjectSelector(props) {
const { activeSubjName, searchTerm, data, onSubjSelect } = props const { activeSubjName, searchTerm, data, onSubjSelect } = props
return ( return (
<div className={styles.subjectSelector}> <div className={styles.subjectSelector}>
{data.map((subj, i) => { {data.map((subj, i) => {
if (!subj.Name.toLowerCase().includes(searchTerm.toLowerCase())) { if (
return null !subj.Name.toLowerCase().includes(searchTerm.toLowerCase())
} ) {
return null
}
return ( return (
<div <div
className={ className={
activeSubjName === subj.Name activeSubjName === subj.Name
? 'subjItem activeSubjItem' ? 'subjItem activeSubjItem'
: 'subjItem' : 'subjItem'
} }
key={i} key={i}
onClick={() => onSubjSelect(subj.Name)} onClick={() => onSubjSelect(subj.Name)}
> >
<span className={styles.subjName}>{subj.Name}</span> <span className={styles.subjName}>{subj.Name}</span>
<span className={styles.questionCount}> <span className={styles.questionCount}>
[ {subj.Questions.length} ] [ {subj.Questions.length} ]
</span> </span>
</div> </div>
) )
})} })}
</div> </div>
) )
} }

View file

@ -1,37 +1,39 @@
import React from 'react' import React from 'react'
export default function DbSelector(props) { export default function DbSelector(props) {
const { selectedDb, qdbs, onChange, hideLockedDbs } = props const { selectedDb, qdbs, onChange, hideLockedDbs } = props
const selectedIndex = const selectedIndex =
qdbs && selectedDb qdbs && selectedDb
? qdbs.findIndex((qdb) => { ? qdbs.findIndex((qdb) => {
return qdb.name === selectedDb.name return qdb.name === selectedDb.name
}) })
: -1 : -1
return ( return (
<> <>
<select <select
style={{ margin: '10px 0px' }} style={{ margin: '10px 0px' }}
defaultValue={selectedIndex} defaultValue={selectedIndex}
value={selectedIndex} value={selectedIndex}
onChange={(event) => { onChange={(event) => {
onChange(qdbs[event.target.value]) onChange(qdbs[event.target.value])
}} }}
> >
<option value={-1}>{' -- Válassz egy kérdés adatbázist -- '}</option> <option value={-1}>
{qdbs.map((qdb, i) => { {' -- Válassz egy kérdés adatbázist -- '}
if (hideLockedDbs && qdb.locked) { </option>
return null {qdbs.map((qdb, i) => {
} if (hideLockedDbs && qdb.locked) {
return null
}
return ( return (
<option value={i} key={qdb.name}> <option value={i} key={qdb.name}>
{qdb.name} {qdb.name}
</option> </option>
) )
})} })}
</select> </select>
</> </>
) )
} }

View file

@ -3,26 +3,26 @@ import React from 'react'
import styles from './searchBar.module.css' import styles from './searchBar.module.css'
export default function SearchBar(props) { export default function SearchBar(props) {
const { onChange, value } = props const { onChange, value } = props
return ( return (
<div className={styles.searchContainer}> <div className={styles.searchContainer}>
<input <input
placeholder="Keresés..." placeholder="Keresés..."
className={styles.searchBar} className={styles.searchBar}
type="text" type="text"
value={value} value={value}
onChange={(e) => { onChange={(e) => {
onChange(e.target.value) onChange(e.target.value)
}} }}
/> />
<button <button
onClick={() => { onClick={() => {
onChange('') onChange('')
}} }}
className={styles.clearButton} className={styles.clearButton}
> >
</button> </button>
</div> </div>
) )
} }

View file

@ -4,7 +4,7 @@ import React from 'react'
import '../defaultStyles.css' import '../defaultStyles.css'
function MyApp({ Component, pageProps, router }) { function MyApp({ Component, pageProps, router }) {
return <Component {...pageProps} router={router} /> return <Component {...pageProps} router={router} />
} }
// Only uncomment this method if you have blocking data requirements for // Only uncomment this method if you have blocking data requirements for