Data.json new structure fix

This commit is contained in:
mrfry 2020-10-15 10:05:03 +02:00
parent 6bc51fb387
commit 280a94398b
4 changed files with 90 additions and 83 deletions

View file

@ -5,7 +5,7 @@ import Questions from './Questions.js'
import constants from '../constants.json' import constants from '../constants.json'
class QuestionSearchResult extends PureComponent { class QuestionSearchResult extends PureComponent {
render () { render() {
const { data, searchTerm, onChange, deleteQuestion } = this.props const { data, searchTerm, onChange, deleteQuestion } = this.props
let subjs = [] let subjs = []
@ -16,14 +16,17 @@ class QuestionSearchResult extends PureComponent {
} }
if (searchTerm) { if (searchTerm) {
subjs = data.Subjects.reduce((acc, subj) => { subjs = data.reduce((acc, subj) => {
const resultQuestions = subj.Questions.reduce((qacc, question) => { const resultQuestions = subj.Questions.reduce((qacc, question) => {
const keys = [ 'Q', 'A', 'data' ] const keys = ['Q', 'A', 'data']
keys.some((key) => { keys.some((key) => {
if (typeof question[key] !== 'string') { if (typeof question[key] !== 'string') {
return false return false
} }
if (question[key] && question[key].toLowerCase().includes(searchTerm.toLowerCase())) { if (
question[key] &&
question[key].toLowerCase().includes(searchTerm.toLowerCase())
) {
qacc.push(question) qacc.push(question)
return true return true
} }
@ -34,20 +37,22 @@ class QuestionSearchResult extends PureComponent {
acc.push({ acc.push({
Name: subj.Name, Name: subj.Name,
Questions: resultQuestions, Questions: resultQuestions,
ind: subj.ind ind: subj.ind,
}) })
} }
return acc return acc
}, []) }, [])
results = subjs.reduce(countReducer, 0) results = subjs.reduce(countReducer, 0)
} else { } else {
results = data.Subjects.reduce(countReducer, 0) results = data.reduce(countReducer, 0)
} }
const renderCount = () => { const renderCount = () => {
return ( return (
<div> <div>
{searchTerm ? '' : 'Kezdj el írni kereséshez!'} {results} {searchTerm ? 'találat' : 'kérdés' } {searchTerm ? subjs.length : data.Subjects.length} tárgy {searchTerm ? '' : 'Kezdj el írni kereséshez!'} {results}{' '}
{searchTerm ? 'találat' : 'kérdés'}{' '}
{searchTerm ? subjs.length : data.length} tárgy
</div> </div>
) )
} }
@ -56,10 +61,8 @@ class QuestionSearchResult extends PureComponent {
return renderCount() return renderCount()
} else { } else {
return ( return (
<div > <div>
<div> <div>{renderCount()}</div>
{renderCount()}
</div>
<div> <div>
<Questions <Questions
deleteQuestion={deleteQuestion} deleteQuestion={deleteQuestion}

View file

@ -1,27 +1,26 @@
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.Subjects.map((subj, i) => { {data.map((subj, i) => {
if (!subj.Name.toLowerCase().includes(searchTerm.toLowerCase())) { if (!subj.Name.toLowerCase().includes(searchTerm.toLowerCase())) {
return null return null
} }
return ( return (
<div <div
className={activeSubjName === subj.Name className={
? 'subjItem activeSubjItem' activeSubjName === subj.Name
: 'subjItem' ? 'subjItem activeSubjItem'
: 'subjItem'
} }
key={i} key={i}
onClick={() => onSubjSelect(subj.Name)} onClick={() => onSubjSelect(subj.Name)}
> >
<span className={styles.subjName}> <span className={styles.subjName}>{subj.Name}</span>
{subj.Name}
</span>
<span className={styles.questionCount}> <span className={styles.questionCount}>
[ {subj.Questions.length} ] [ {subj.Questions.length} ]
</span> </span>

View file

@ -6,7 +6,7 @@ import SubjectSelector from '../components/SubjectSelector.js'
import styles from './subjectView.module.css' import styles from './subjectView.module.css'
export default function SubjectView (props) { export default function SubjectView(props) {
const { data, onChange, deleteQuestion } = props const { data, onChange, deleteQuestion } = props
const [activeSubjName, setActiveSubjName] = useState('') const [activeSubjName, setActiveSubjName] = useState('')
const [searchTerm, setSearchTerm] = useState('') const [searchTerm, setSearchTerm] = useState('')
@ -15,14 +15,16 @@ export default function SubjectView (props) {
const [qCount, setQCount] = useState(0) const [qCount, setQCount] = useState(0)
useEffect(() => { useEffect(() => {
setSCount(data.Subjects.length) setSCount(data.length)
setQCount(data.Subjects.reduce((acc, subj) => { setQCount(
return acc + subj.Questions.length data.reduce((acc, subj) => {
}, 0)) return acc + subj.Questions.length
}, 0)
)
}, []) }, [])
if (data) { if (data) {
let currSubj = data.Subjects.find((subj) => { let currSubj = data.find((subj) => {
return subj.Name === activeSubjName return subj.Name === activeSubjName
}) })
@ -30,11 +32,13 @@ export default function SubjectView (props) {
<div> <div>
<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={searchTerm} value={searchTerm}
onChange={(e) => { setSearchTerm(e.target.value) }} onChange={(e) => {
setSearchTerm(e.target.value)
}}
/> />
<button <button
onClick={() => { onClick={() => {
@ -42,7 +46,7 @@ export default function SubjectView (props) {
}} }}
className={styles.clearButton} className={styles.clearButton}
> >
X X
</button> </button>
</div> </div>
<hr /> <hr />
@ -50,7 +54,9 @@ export default function SubjectView (props) {
data={data} data={data}
activeSubjName={activeSubjName} activeSubjName={activeSubjName}
searchTerm={searchTerm} searchTerm={searchTerm}
onSubjSelect={(subjName) => { setActiveSubjName(subjName) }} onSubjSelect={(subjName) => {
setActiveSubjName(subjName)
}}
/> />
<hr /> <hr />
<div> <div>
@ -66,8 +72,6 @@ export default function SubjectView (props) {
</div> </div>
) )
} else { } else {
return ( return <LoadingIndicator />
<LoadingIndicator />
)
} }
} }

View file

@ -11,7 +11,7 @@ import constants from '../constants.json'
const views = { const views = {
subject: 'SUBJECT', subject: 'SUBJECT',
question: 'QUESTION', question: 'QUESTION',
welcome: 'WELCOME' welcome: 'WELCOME',
} }
// TODO: Add question on subjects view // TODO: Add question on subjects view
@ -19,7 +19,7 @@ const views = {
// TODO: question.data editor // TODO: question.data editor
// TODO: edit \n-s in questions / answers // TODO: edit \n-s in questions / answers
export default function Index (props) { export default function Index(props) {
const [data, setData] = useState(null) const [data, setData] = useState(null)
const [view, setView] = useState(views.welcome) const [view, setView] = useState(views.welcome)
const [sending, setSending] = useState(false) const [sending, setSending] = useState(false)
@ -31,16 +31,16 @@ export default function Index (props) {
const getCount = (d) => { const getCount = (d) => {
return { return {
subjectCount: d.Subjects.length, subjectCount: d.length,
questionCount: d.Subjects.reduce((acc, subj) => { questionCount: d.reduce((acc, subj) => {
acc += subj.Questions.length acc += subj.Questions.length
return acc return acc
}, 0) }, 0),
} }
} }
const setIndexes = (d) => { const setIndexes = (d) => {
d.Subjects.forEach((subj, i) => { d.forEach((subj, i) => {
subj.ind = i subj.ind = i
subj.Questions.forEach((question, j) => { subj.Questions.forEach((question, j) => {
question.ind = j question.ind = j
@ -54,7 +54,7 @@ export default function Index (props) {
const toFetch = `${constants.apiUrl}data.json` const toFetch = `${constants.apiUrl}data.json`
console.info('Fetching', toFetch) console.info('Fetching', toFetch)
fetch(toFetch, { fetch(toFetch, {
credentials: 'include' credentials: 'include',
}) })
.then((resp) => { .then((resp) => {
if (resp && resp.ok) { if (resp && resp.ok) {
@ -81,31 +81,25 @@ export default function Index (props) {
}, []) }, [])
if (error) { if (error) {
return ( return <div>{error}</div>
<div>
{error}
</div>
)
} }
const deleteQuestion = (subjInd, questionInd) => { const deleteQuestion = (subjInd, questionInd) => {
data.Subjects[subjInd].Questions.splice(questionInd, 1) data[subjInd].Questions.splice(questionInd, 1)
setData({ setData([...setIndexes(data)])
...setIndexes(data)
})
} }
const onChange = (subjInd, questionInd, newVal) => { const onChange = (subjInd, questionInd, newVal) => {
const key = subjInd + '/' + questionInd const key = subjInd + '/' + questionInd
setEditedQuestions({ setEditedQuestions({
...editedQuestions, ...editedQuestions,
[key]: editedQuestions[key] ? editedQuestions[key] + 1 : 1 [key]: editedQuestions[key] ? editedQuestions[key] + 1 : 1,
}) })
data.Subjects[subjInd].Questions[questionInd] = newVal data[subjInd].Questions[questionInd] = newVal
setData({ setData({
...data ...data,
}) })
} }
@ -119,8 +113,8 @@ export default function Index (props) {
const rawResponse = await fetch(constants.apiUrl + 'uploaddata', { const rawResponse = await fetch(constants.apiUrl + 'uploaddata', {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', Accept: 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json',
}, },
credentials: 'include', credentials: 'include',
body: JSON.stringify({ body: JSON.stringify({
@ -128,32 +122,35 @@ export default function Index (props) {
count: getCount(data), count: getCount(data),
initialCount: initialCount, initialCount: initialCount,
password: password, password: password,
editedQuestions: editedQuestions editedQuestions: editedQuestions,
}) }),
}) })
rawResponse.json() rawResponse
.json()
.then((resp) => { .then((resp) => {
setSending(false) setSending(false)
if (resp.status === 'ok') { if (resp.status === 'ok') {
alert(`Sikeres feltöltés! thankx ${resp.user}!`) // eslint-disable-line alert(`Sikeres feltöltés! thankx ${resp.user}!`) // eslint-disable-line
console.log('OK') console.log('OK')
} else if (resp.status === 'invalidPass') { } else if (resp.status === 'invalidPass') {
alert('Hibás jelszó!') // eslint-disable-line alert('Hibás jelszó!') // eslint-disable-line
console.log('invalidPass') console.log('invalidPass')
} else { } else {
alert('Hiba feltöltés közben! (szerver oldalon)! Több adat konzolban') // eslint-disable-line alert(
'Hiba feltöltés közben! (szerver oldalon)! Több adat konzolban'
) // eslint-disable-line
console.error('RESPONSE', resp) console.error('RESPONSE', resp)
console.error(resp.message) console.error(resp.message)
} }
}) })
.catch((e) => { .catch((e) => {
setSending(false) setSending(false)
alert('Hiba feltöltés közben! (kliens oldalon)! Több adat konzolban') // eslint-disable-line alert('Hiba feltöltés közben! (kliens oldalon)! Több adat konzolban') // eslint-disable-line
console.error('Error posting data', e) console.error('Error posting data', e)
}) })
} catch (e) { } catch (e) {
setSending(false) setSending(false)
alert('Hiba feltöltés közben! (kliens oldalon)! Több adat konzolban') // eslint-disable-line alert('Hiba feltöltés közben! (kliens oldalon)! Több adat konzolban') // eslint-disable-line
console.error('Error posting data', e) console.error('Error posting data', e)
} }
} }
@ -182,29 +179,25 @@ export default function Index (props) {
<br /> <br />
{initialCount.questionCount} kérdés, {initialCount.subjectCount} tárgy {initialCount.questionCount} kérdés, {initialCount.subjectCount} tárgy
<p /> <p />
Itt az éles adatbázis kérdései jelennek meg, amiket tudsz szerkeszteni. A kérdésekhez Itt az éles adatbázis kérdései jelennek meg, amiket tudsz
tartozó '.data' prop-ot még nem tudod rendesen szerkeszteni, az később lesz implementálva. szerkeszteni. A kérdésekhez tartozó '.data' prop-ot még nem tudod
A Tárgy / Kérdés nézet között tudsz válogatni. rendesen szerkeszteni, az később lesz implementálva. A Tárgy / Kérdés
nézet között tudsz válogatni.
<br /> <br />
Tárgy nézet: a tárgyak dobozban kattints egy tárgyra, minden kérdés ott lessz hozzá. Tárgy nézet: a tárgyak dobozban kattints egy tárgyra, minden kérdés
ott lessz hozzá.
<br /> <br />
Kérdés nézet: Kereső sávba írd be a kérdést / választ, a találatok ha kevesebb mint 250 Kérdés nézet: Kereső sávba írd be a kérdést / választ, a találatok ha
megjelennek, és ott tudod szerkeszteni kevesebb mint 250 megjelennek, és ott tudod szerkeszteni
</div> </div>
) )
} else { } else {
return ( return <div>No view!</div>
<div>
No view!
</div>
)
} }
} }
if (!data) { if (!data) {
return ( return <LoadingIndicator />
<LoadingIndicator />
)
} }
return ( return (
@ -219,10 +212,12 @@ export default function Index (props) {
</span> </span>
<span> <span>
<input <input
placeholder='Jelszó feltöltéshez' placeholder="Jelszó feltöltéshez"
type='text' type="text"
value={password} value={password}
onChange={(e) => { setPassword(e.target.value) }} onChange={(e) => {
setPassword(e.target.value)
}}
/> />
</span> </span>
<span <span
@ -239,12 +234,18 @@ export default function Index (props) {
</div> </div>
<div className={styles.viewButtonContainer}> <div className={styles.viewButtonContainer}>
<span <span
onClick={() => { setView(views.question) }}> onClick={() => {
Kérdés nézet setView(views.question)
}}
>
Kérdés nézet
</span> </span>
<span <span
onClick={() => { setView(views.subject) }}> onClick={() => {
Tárgy nézet setView(views.subject)
}}
>
Tárgy nézet
</span> </span>
</div> </div>
{renderView()} {renderView()}