mirror of
https://gitlab.com/MrFry/qmining-data-editor
synced 2025-04-01 20:24:01 +02:00
added dynamic domain
This commit is contained in:
parent
39dfd7a0f4
commit
5a665bc766
10 changed files with 1537 additions and 1455 deletions
78
.eslintrc.js
78
.eslintrc.js
|
@ -1,50 +1,36 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
parser: '@babel/eslint-parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
parser: '@babel/eslint-parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
extends: [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:@next/next/recommended',
|
||||
},
|
||||
plugins: ['react'],
|
||||
extends: [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:@next/next/recommended',
|
||||
],
|
||||
rules: {
|
||||
'react/prop-types': 0,
|
||||
'no-undef': ['error'],
|
||||
eqeqeq: ['warn', 'smart'],
|
||||
'react/jsx-uses-vars': 'error',
|
||||
'react/jsx-uses-react': 'error',
|
||||
'@next/next/no-img-element': 'off',
|
||||
'no-unused-vars': 'warn',
|
||||
'no-prototype-builtins': 'off',
|
||||
'id-length': [
|
||||
'warn',
|
||||
{ exceptions: ['x', 'i', 'j', 't', 'Q', 'A', 'C', 'q', 'a', 'b', 'e'] },
|
||||
],
|
||||
globals: {
|
||||
Atomics: 'readonly',
|
||||
SharedArrayBuffer: 'readonly',
|
||||
},
|
||||
rules: {
|
||||
'react/prop-types': 0,
|
||||
'no-undef': ['error'],
|
||||
eqeqeq: ['warn', 'smart'],
|
||||
'no-unused-vars': 'warn',
|
||||
'no-prototype-builtins': 'off',
|
||||
'id-length': [
|
||||
'warn',
|
||||
{
|
||||
exceptions: [
|
||||
'x',
|
||||
'i',
|
||||
'j',
|
||||
't',
|
||||
'Q',
|
||||
'A',
|
||||
'C',
|
||||
'q',
|
||||
'a',
|
||||
'b',
|
||||
'e',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
root: true,
|
||||
},
|
||||
root: true,
|
||||
}
|
||||
|
|
|
@ -2,86 +2,95 @@ import React from 'react'
|
|||
|
||||
import Questions from './Questions.js'
|
||||
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
|
||||
const countReducer = (acc, subj) => {
|
||||
return acc + subj.Questions.length
|
||||
return acc + subj.Questions.length
|
||||
}
|
||||
|
||||
export default function QuestionSearchResult(props) {
|
||||
const { data, searchTerm, edits, onChange } = props
|
||||
const { data, searchTerm, edits, onChange } = props
|
||||
|
||||
let subjs = []
|
||||
let results = -1
|
||||
let subjs = []
|
||||
let results = -1
|
||||
|
||||
if (searchTerm || edits.length > 0) {
|
||||
subjs = data.reduce((acc, subj) => {
|
||||
const resultQuestions = subj.Questions.reduce((qacc, question, i) => {
|
||||
const unsaved = edits.some((e) => {
|
||||
if (e.subjName === subj.Name && e.index === i && e.type === 'edit') {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (unsaved) {
|
||||
qacc.push({
|
||||
q: question,
|
||||
unsaved: unsaved,
|
||||
})
|
||||
return qacc
|
||||
}
|
||||
if (searchTerm || edits.length > 0) {
|
||||
subjs = data.reduce((acc, subj) => {
|
||||
const resultQuestions = subj.Questions.reduce(
|
||||
(qacc, question, i) => {
|
||||
const unsaved = edits.some((e) => {
|
||||
if (
|
||||
e.subjName === subj.Name &&
|
||||
e.index === i &&
|
||||
e.type === 'edit'
|
||||
) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (unsaved) {
|
||||
qacc.push({
|
||||
q: question,
|
||||
unsaved: unsaved,
|
||||
})
|
||||
return qacc
|
||||
}
|
||||
|
||||
const keys = ['Q', 'A', 'data']
|
||||
keys.some((key) => {
|
||||
if (typeof question[key] !== 'string') {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
searchTerm &&
|
||||
question[key] &&
|
||||
question[key].toLowerCase().includes(searchTerm.toLowerCase())
|
||||
) {
|
||||
qacc.push({ q: question })
|
||||
return true
|
||||
}
|
||||
})
|
||||
return qacc
|
||||
}, [])
|
||||
if (resultQuestions.length > 0) {
|
||||
acc.push({
|
||||
Name: subj.Name,
|
||||
Questions: resultQuestions,
|
||||
ind: subj.ind,
|
||||
})
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
results = subjs.reduce(countReducer, 0)
|
||||
} else {
|
||||
results = data.reduce(countReducer, 0)
|
||||
}
|
||||
const keys = ['Q', 'A', 'data']
|
||||
keys.some((key) => {
|
||||
if (typeof question[key] !== 'string') {
|
||||
return false
|
||||
}
|
||||
if (
|
||||
searchTerm &&
|
||||
question[key] &&
|
||||
question[key]
|
||||
.toLowerCase()
|
||||
.includes(searchTerm.toLowerCase())
|
||||
) {
|
||||
qacc.push({ q: question })
|
||||
return true
|
||||
}
|
||||
})
|
||||
return qacc
|
||||
},
|
||||
[]
|
||||
)
|
||||
if (resultQuestions.length > 0) {
|
||||
acc.push({
|
||||
Name: subj.Name,
|
||||
Questions: resultQuestions,
|
||||
ind: subj.ind,
|
||||
})
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
results = subjs.reduce(countReducer, 0)
|
||||
} else {
|
||||
results = data.reduce(countReducer, 0)
|
||||
}
|
||||
|
||||
console.log(subjs)
|
||||
console.log(subjs)
|
||||
|
||||
const renderCount = () => {
|
||||
return (
|
||||
<div>
|
||||
{searchTerm ? '' : 'Kezdj el írni kereséshez!'} {results}{' '}
|
||||
{searchTerm ? 'találat' : 'kérdés'}{' '}
|
||||
{searchTerm ? subjs.length : data.length} tárgy
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const renderCount = () => {
|
||||
return (
|
||||
<div>
|
||||
{searchTerm ? '' : 'Kezdj el írni kereséshez!'} {results}{' '}
|
||||
{searchTerm ? 'találat' : 'kérdés'}{' '}
|
||||
{searchTerm ? subjs.length : data.length} tárgy
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (results > constants.maxQuestionsToRender) {
|
||||
return renderCount()
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<div>{renderCount()}</div>
|
||||
<div>
|
||||
<Questions subjs={subjs} onChange={onChange} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (results > constants.maxQuestionsToRender) {
|
||||
return renderCount()
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<div>{renderCount()}</div>
|
||||
<div>
|
||||
<Questions subjs={subjs} onChange={onChange} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,257 +4,283 @@ import LoadingIndicator from '../components/LoadingIndicator'
|
|||
import SearchBar from '../components/searchBar'
|
||||
import TestView from '../components/testView'
|
||||
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
import styles from './possibleAnswers.module.css'
|
||||
|
||||
const Infos = () => {
|
||||
return (
|
||||
<div className={styles.infoContainer}>
|
||||
<div>
|
||||
Itt azok a tesztek találhatók, amiknek a kitöltése után nem volt
|
||||
ellenőrző oldal. A script így nem tudja, hogy melyik a helyes megoldás.
|
||||
De ha ti igen, akkor jelöljétek be / írjátok be, és mentsétek el. Így
|
||||
mikor legközelebb találkoztok a kérdéssel a script tudni fogja a helyes
|
||||
választ. Ezzel másoknak is nagyon sokat segítetek.
|
||||
</div>
|
||||
<div>
|
||||
Jelenleg azok a tesztek is megjelennek itt, amiknek elérhető a teszt eredmény oldala, és meg is
|
||||
van hozzá a helyes válasz. A jövőben ezek ki lesznek automatikusan törölve.
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<div className={styles.infoContainer}>
|
||||
<div>
|
||||
Itt azok a tesztek találhatók, amiknek a kitöltése után nem volt
|
||||
ellenőrző oldal. A script így nem tudja, hogy melyik a helyes
|
||||
megoldás. De ha ti igen, akkor jelöljétek be / írjátok be, és
|
||||
mentsétek el. Így mikor legközelebb találkoztok a kérdéssel a
|
||||
script tudni fogja a helyes választ. Ezzel másoknak is nagyon
|
||||
sokat segítetek.
|
||||
</div>
|
||||
<div>
|
||||
Jelenleg azok a tesztek is megjelennek itt, amiknek elérhető a
|
||||
teszt eredmény oldala, és meg is van hozzá a helyes válasz. A
|
||||
jövőben ezek ki lesznek automatikusan törölve.
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const fetchPossibleAnswers = () => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}possibleAnswers`, {
|
||||
credentials: 'include',
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}possibleAnswers`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const fetchSubject = (subj, savedQuestionsFileName) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(
|
||||
`${constants.apiUrl}savedQuestions/${subj}/${savedQuestionsFileName}`,
|
||||
{
|
||||
credentials: 'include',
|
||||
}
|
||||
)
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
return new Promise((resolve) => {
|
||||
fetch(
|
||||
`${constants.apiUrl}savedQuestions/${subj}/${savedQuestionsFileName}`,
|
||||
{
|
||||
credentials: 'include',
|
||||
}
|
||||
)
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const fetchTest = (subj, test) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}savedQuestions/${subj}/${test}`, {
|
||||
credentials: 'include',
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}savedQuestions/${subj}/${test}`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function PossibleAnswers({ router, refetchDbs }) {
|
||||
const [currSubjName, setCurrSubjName] = useState(null)
|
||||
const [currTestName, setCurrTestName] = useState(null)
|
||||
const [currSubjName, setCurrSubjName] = useState(null)
|
||||
const [currTestName, setCurrTestName] = useState(null)
|
||||
|
||||
const [subjects, setSubjects] = useState([])
|
||||
const [currSubj, setCurrSubj] = useState(null)
|
||||
const [currTest, setCurrTest] = useState(null)
|
||||
const [subjects, setSubjects] = useState([])
|
||||
const [currSubj, setCurrSubj] = useState(null)
|
||||
const [currTest, setCurrTest] = useState(null)
|
||||
|
||||
const [savedQuestionsFileName, setSavedQuestionsFileName] = useState(null)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [savedQuestionsFileName, setSavedQuestionsFileName] = useState(null)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
fetchPossibleAnswers().then((resp) => {
|
||||
setSubjects(resp.subjects)
|
||||
setSavedQuestionsFileName(resp.savedQuestionsFileName)
|
||||
useEffect(() => {
|
||||
fetchPossibleAnswers().then((resp) => {
|
||||
setSubjects(resp.subjects)
|
||||
setSavedQuestionsFileName(resp.savedQuestionsFileName)
|
||||
|
||||
const subj = router.query.subj
|
||||
? decodeURIComponent(router.query.subj)
|
||||
: ''
|
||||
const test = router.query.test
|
||||
? decodeURIComponent(router.query.test)
|
||||
: ''
|
||||
const subj = router.query.subj
|
||||
? decodeURIComponent(router.query.subj)
|
||||
: ''
|
||||
const test = router.query.test
|
||||
? decodeURIComponent(router.query.test)
|
||||
: ''
|
||||
|
||||
if (subj) {
|
||||
fetchSubject(subj, resp.savedQuestionsFileName).then((resp) => {
|
||||
setCurrSubj(resp)
|
||||
setCurrSubjName(subj)
|
||||
router.push(
|
||||
`${router.pathname}?v=pa&subj=${encodeURIComponent(subj)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
if (subj && test) {
|
||||
fetchTest(subj, test).then((resp) => {
|
||||
setCurrTest(resp)
|
||||
setCurrTestName(test)
|
||||
router.push(
|
||||
`${router.pathname}?v=pa&subj=${encodeURIComponent(
|
||||
subj
|
||||
)}&test=${encodeURIComponent(test)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
const renderStuff = () => {
|
||||
if (subjects && currSubj && currTest) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={styles.backButton}
|
||||
onClick={() => {
|
||||
setCurrTest(null)
|
||||
router.back()
|
||||
}}
|
||||
>
|
||||
Vissza
|
||||
</div>
|
||||
<div>
|
||||
{currTest && (
|
||||
<TestView
|
||||
subjName={currSubjName}
|
||||
testName={currTestName}
|
||||
test={currTest}
|
||||
router={router}
|
||||
onDelete={() => {
|
||||
refetchDbs()
|
||||
setCurrTest(null)
|
||||
fetchSubject(currSubjName, savedQuestionsFileName).then(
|
||||
(resp) => {
|
||||
setCurrSubj(resp)
|
||||
}
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else if (subjects && currSubj) {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.headerContainer}>
|
||||
<div
|
||||
className={styles.backButton}
|
||||
onClick={() => {
|
||||
setCurrSubj(null)
|
||||
router.back()
|
||||
}}
|
||||
>
|
||||
Vissza
|
||||
</div>
|
||||
<div className={styles.subjName}>{currSubjName}</div>
|
||||
</div>
|
||||
<div className={styles.tableContainer}>
|
||||
<>
|
||||
<div>
|
||||
<div>Dátum</div>
|
||||
<div>Felhasználó ID</div>
|
||||
<div>Tárgy</div>
|
||||
<div>Teszt URL</div>
|
||||
</div>
|
||||
{currSubj &&
|
||||
currSubj.map((test, i) => {
|
||||
return (
|
||||
<div
|
||||
className={styles.testContainer}
|
||||
key={i}
|
||||
onClick={() => {
|
||||
setCurrTestName(test.fname)
|
||||
router.push(
|
||||
`${router.pathname}?v=pa&subj=${encodeURIComponent(
|
||||
currSubjName
|
||||
)}&test=${encodeURIComponent(test.fname)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
|
||||
fetchTest(currSubjName, test.fname).then((resp) => {
|
||||
setCurrTest(resp)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div>{new Date(test.date).toLocaleString()}</div>
|
||||
<div>{test.userid}</div>
|
||||
<div>{test.subj}</div>
|
||||
<div>{test.testUrl}</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else if (subjects) {
|
||||
return (
|
||||
<>
|
||||
<Infos />
|
||||
<SearchBar value={searchTerm} onChange={(e) => setSearchTerm(e)} />
|
||||
<div className={styles.tableContainer}>
|
||||
<>
|
||||
<div>Tárgy neve</div>
|
||||
{subjects.map((subj, i) => {
|
||||
if (
|
||||
!subj.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => {
|
||||
setCurrSubjName(subj.name)
|
||||
router.push(
|
||||
if (subj) {
|
||||
fetchSubject(subj, resp.savedQuestionsFileName).then((resp) => {
|
||||
setCurrSubj(resp)
|
||||
setCurrSubjName(subj)
|
||||
router.push(
|
||||
`${router.pathname}?v=pa&subj=${encodeURIComponent(
|
||||
subj.name
|
||||
subj
|
||||
)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
)
|
||||
if (subj && test) {
|
||||
fetchTest(subj, test).then((resp) => {
|
||||
setCurrTest(resp)
|
||||
setCurrTestName(test)
|
||||
router.push(
|
||||
`${
|
||||
router.pathname
|
||||
}?v=pa&subj=${encodeURIComponent(
|
||||
subj
|
||||
)}&test=${encodeURIComponent(test)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
fetchSubject(subj.name, savedQuestionsFileName).then(
|
||||
(resp) => {
|
||||
setCurrSubj(resp)
|
||||
}
|
||||
)
|
||||
}}
|
||||
>
|
||||
{subj.name}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
const renderStuff = () => {
|
||||
if (subjects && currSubj && currTest) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={styles.backButton}
|
||||
onClick={() => {
|
||||
setCurrTest(null)
|
||||
router.back()
|
||||
}}
|
||||
>
|
||||
Vissza
|
||||
</div>
|
||||
<div>
|
||||
{currTest && (
|
||||
<TestView
|
||||
subjName={currSubjName}
|
||||
testName={currTestName}
|
||||
test={currTest}
|
||||
router={router}
|
||||
onDelete={() => {
|
||||
refetchDbs()
|
||||
setCurrTest(null)
|
||||
fetchSubject(
|
||||
currSubjName,
|
||||
savedQuestionsFileName
|
||||
).then((resp) => {
|
||||
setCurrSubj(resp)
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else if (subjects && currSubj) {
|
||||
return (
|
||||
<>
|
||||
<div className={styles.headerContainer}>
|
||||
<div
|
||||
className={styles.backButton}
|
||||
onClick={() => {
|
||||
setCurrSubj(null)
|
||||
router.back()
|
||||
}}
|
||||
>
|
||||
Vissza
|
||||
</div>
|
||||
<div className={styles.subjName}>{currSubjName}</div>
|
||||
</div>
|
||||
<div className={styles.tableContainer}>
|
||||
<>
|
||||
<div>
|
||||
<div>Dátum</div>
|
||||
<div>Felhasználó ID</div>
|
||||
<div>Tárgy</div>
|
||||
<div>Teszt URL</div>
|
||||
</div>
|
||||
{currSubj &&
|
||||
currSubj.map((test, i) => {
|
||||
return (
|
||||
<div
|
||||
className={styles.testContainer}
|
||||
key={i}
|
||||
onClick={() => {
|
||||
setCurrTestName(test.fname)
|
||||
router.push(
|
||||
`${
|
||||
router.pathname
|
||||
}?v=pa&subj=${encodeURIComponent(
|
||||
currSubjName
|
||||
)}&test=${encodeURIComponent(
|
||||
test.fname
|
||||
)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
|
||||
fetchTest(
|
||||
currSubjName,
|
||||
test.fname
|
||||
).then((resp) => {
|
||||
setCurrTest(resp)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{new Date(
|
||||
test.date
|
||||
).toLocaleString()}
|
||||
</div>
|
||||
<div>{test.userid}</div>
|
||||
<div>{test.subj}</div>
|
||||
<div>{test.testUrl}</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else if (subjects) {
|
||||
return (
|
||||
<>
|
||||
<Infos />
|
||||
<SearchBar
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e)}
|
||||
/>
|
||||
<div className={styles.tableContainer}>
|
||||
<>
|
||||
<div>Tárgy neve</div>
|
||||
{subjects.map((subj, i) => {
|
||||
if (
|
||||
!subj.name
|
||||
.toLowerCase()
|
||||
.includes(searchTerm.toLowerCase())
|
||||
) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => {
|
||||
setCurrSubjName(subj.name)
|
||||
router.push(
|
||||
`${
|
||||
router.pathname
|
||||
}?v=pa&subj=${encodeURIComponent(
|
||||
subj.name
|
||||
)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
|
||||
fetchSubject(
|
||||
subj.name,
|
||||
savedQuestionsFileName
|
||||
).then((resp) => {
|
||||
setCurrSubj(resp)
|
||||
})
|
||||
}}
|
||||
>
|
||||
{subj.name}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return renderStuff()
|
||||
return renderStuff()
|
||||
}
|
||||
|
|
|
@ -3,312 +3,314 @@ import React, { useState, useEffect } from 'react'
|
|||
import Question from '../components/Question'
|
||||
|
||||
import styles from './questionAdder.module.css'
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
import commonStyles from '../commonStyles.module.css'
|
||||
|
||||
const handleSubmit = async (form) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!form.subj) {
|
||||
reject('nosubj')
|
||||
return
|
||||
}
|
||||
let isValid = form.quiz.every((x) => {
|
||||
return x.Q && x.A
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!form.subj) {
|
||||
reject('nosubj')
|
||||
return
|
||||
}
|
||||
let isValid = form.quiz.every((x) => {
|
||||
return x.Q && x.A
|
||||
})
|
||||
if (!isValid || form.quiz.length === 0) {
|
||||
reject('notvalid')
|
||||
return
|
||||
}
|
||||
|
||||
const t = document.getElementById('cid').value
|
||||
let cid = ''
|
||||
let version = ''
|
||||
if (t) {
|
||||
cid = t.split('|')[0]
|
||||
version = t.split('|')[1]
|
||||
}
|
||||
|
||||
// console.log(form)
|
||||
// {
|
||||
// "quiz": [
|
||||
// {
|
||||
// "Q": "aaaaaaaaaaaa",
|
||||
// "A": "bbbbbbbbbbbbbb",
|
||||
// "data": {
|
||||
// "type": "simple"
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// "selectedDb": {
|
||||
// "path": "questionDbs/elearning.uni-obuda.hu.json",
|
||||
// "name": "elearning.uni-obuda.hu"
|
||||
// },
|
||||
// "subj": "Elektronika"
|
||||
// }
|
||||
|
||||
const toSend = {
|
||||
id: cid,
|
||||
version: `WEBSITE${version ? ` (${version})` : ''}`,
|
||||
location: `https://${form.selectedDb.name}`,
|
||||
subj: form.subj,
|
||||
quiz: form.quiz,
|
||||
}
|
||||
|
||||
fetch(constants.apiUrl + 'isAdding', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(toSend),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
if (!isValid || form.quiz.length === 0) {
|
||||
reject('notvalid')
|
||||
return
|
||||
}
|
||||
|
||||
const t = document.getElementById('cid').value
|
||||
let cid = ''
|
||||
let version = ''
|
||||
if (t) {
|
||||
cid = t.split('|')[0]
|
||||
version = t.split('|')[1]
|
||||
}
|
||||
|
||||
// console.log(form)
|
||||
// {
|
||||
// "quiz": [
|
||||
// {
|
||||
// "Q": "aaaaaaaaaaaa",
|
||||
// "A": "bbbbbbbbbbbbbb",
|
||||
// "data": {
|
||||
// "type": "simple"
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// "selectedDb": {
|
||||
// "path": "questionDbs/elearning.uni-obuda.hu.json",
|
||||
// "name": "elearning.uni-obuda.hu"
|
||||
// },
|
||||
// "subj": "Elektronika"
|
||||
// }
|
||||
|
||||
const toSend = {
|
||||
id: cid,
|
||||
version: `WEBSITE${version ? ` (${version})` : ''}`,
|
||||
location: `https://${form.selectedDb.name}`,
|
||||
subj: form.subj,
|
||||
quiz: form.quiz,
|
||||
}
|
||||
|
||||
fetch(constants.apiUrl + 'isAdding', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(toSend),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const renderUsage = () => {
|
||||
return (
|
||||
<ul>
|
||||
<li>Ezek a kérdések ellenőrizve lesznek hogy megvannak-e már</li>
|
||||
<li>
|
||||
{
|
||||
"Ha több válasz van, akkor ', '-vel válaszd el őket ( 'válasz1, válasz2, válasz3' )"
|
||||
}
|
||||
</li>
|
||||
<li>
|
||||
Kérdéseknél az utolsó sor (ahol a JSON cucc van) jelenleg nem
|
||||
módosítható, csak olyan kérdéseket lehet beküldeni, amik sima
|
||||
kérdés-válaszok, szóval pl nincs benne kép. Ez később bővül majd
|
||||
</li>
|
||||
<li>
|
||||
Ha sok új kérdést küldesz be, akkor akár több percig is eltarthat a
|
||||
dolog. Akárhány kérdést be lehet egyszerre küldeni, de max 10-15 az
|
||||
ajánlott
|
||||
</li>
|
||||
<li>
|
||||
Bármilyen szöveget beküldhettek, de ne tegyétek, más felhasználóknak és
|
||||
magatoknak lesz rosz, ty!
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
return (
|
||||
<ul>
|
||||
<li>Ezek a kérdések ellenőrizve lesznek hogy megvannak-e már</li>
|
||||
<li>
|
||||
{
|
||||
"Ha több válasz van, akkor ', '-vel válaszd el őket ( 'válasz1, válasz2, válasz3' )"
|
||||
}
|
||||
</li>
|
||||
<li>
|
||||
Kérdéseknél az utolsó sor (ahol a JSON cucc van) jelenleg nem
|
||||
módosítható, csak olyan kérdéseket lehet beküldeni, amik sima
|
||||
kérdés-válaszok, szóval pl nincs benne kép. Ez később bővül majd
|
||||
</li>
|
||||
<li>
|
||||
Ha sok új kérdést küldesz be, akkor akár több percig is
|
||||
eltarthat a dolog. Akárhány kérdést be lehet egyszerre küldeni,
|
||||
de max 10-15 az ajánlott
|
||||
</li>
|
||||
<li>
|
||||
Bármilyen szöveget beküldhettek, de ne tegyétek, más
|
||||
felhasználóknak és magatoknak lesz rosz, ty!
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
const getDefaultQuestion = () => {
|
||||
return {
|
||||
Q: '',
|
||||
A: '',
|
||||
data: { type: 'simple' },
|
||||
}
|
||||
return {
|
||||
Q: '',
|
||||
A: '',
|
||||
data: { type: 'simple' },
|
||||
}
|
||||
}
|
||||
|
||||
export default function QuestionAdder({ data, selectedDb, refetchDbs }) {
|
||||
const [form, setForm] = useState({ quiz: [getDefaultQuestion()] })
|
||||
const [subjects, setSubjects] = useState(null)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [isNewSubj, setIsNewSubj] = useState(false)
|
||||
const [form, setForm] = useState({ quiz: [getDefaultQuestion()] })
|
||||
const [subjects, setSubjects] = useState(null)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [isNewSubj, setIsNewSubj] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDb) {
|
||||
setForm({
|
||||
...form,
|
||||
selectedDb: selectedDb,
|
||||
})
|
||||
}
|
||||
}, [selectedDb])
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setSubjects(
|
||||
data.map((subj) => {
|
||||
return subj.Name
|
||||
})
|
||||
)
|
||||
}
|
||||
}, [data])
|
||||
|
||||
const handleQuestionChange = (index, newVal) => {
|
||||
setForm({
|
||||
...form,
|
||||
quiz: form.quiz.map((q, i) => {
|
||||
if (i !== index) {
|
||||
return q
|
||||
} else {
|
||||
return newVal
|
||||
useEffect(() => {
|
||||
if (selectedDb) {
|
||||
setForm({
|
||||
...form,
|
||||
selectedDb: selectedDb,
|
||||
})
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
}, [selectedDb])
|
||||
|
||||
const deleteQuestion = (index) => {
|
||||
let quiz = form.quiz
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setSubjects(
|
||||
data.map((subj) => {
|
||||
return subj.Name
|
||||
})
|
||||
)
|
||||
}
|
||||
}, [data])
|
||||
|
||||
quiz.splice(index, 1)
|
||||
const handleQuestionChange = (index, newVal) => {
|
||||
setForm({
|
||||
...form,
|
||||
quiz: form.quiz.map((q, i) => {
|
||||
if (i !== index) {
|
||||
return q
|
||||
} else {
|
||||
return newVal
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
setForm({
|
||||
...form,
|
||||
quiz: quiz,
|
||||
})
|
||||
}
|
||||
const deleteQuestion = (index) => {
|
||||
let quiz = form.quiz
|
||||
|
||||
const renderStuff = () => {
|
||||
return (
|
||||
<div>
|
||||
{form.quiz.map((q, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<hr />
|
||||
<Question
|
||||
index={i}
|
||||
question={form.quiz[i] || {}}
|
||||
onChange={(newVal) => {
|
||||
handleQuestionChange(i, newVal)
|
||||
}}
|
||||
/>
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
deleteQuestion(i)
|
||||
}}
|
||||
>
|
||||
Törlés
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
<hr />
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
let quiz = form.quiz
|
||||
quiz.push(getDefaultQuestion())
|
||||
setForm({
|
||||
...form,
|
||||
quiz: quiz,
|
||||
})
|
||||
}}
|
||||
>
|
||||
Új kérdés
|
||||
</div>
|
||||
<div
|
||||
className={`${isSubmitting ? styles.issubmitting : ''}`}
|
||||
onClick={() => {
|
||||
if (isSubmitting) {
|
||||
return
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
handleSubmit(form)
|
||||
.then((res) => {
|
||||
// console.log(res)
|
||||
// {
|
||||
// "success": true,
|
||||
// "newQuestions": [
|
||||
// {
|
||||
// "newQuestions": 1,
|
||||
// "qdbName": "elearning.uni-obuda.hu"
|
||||
// }
|
||||
// ],
|
||||
// "totalNewQuestions": 1
|
||||
// }
|
||||
quiz.splice(index, 1)
|
||||
|
||||
if (res.success) {
|
||||
alert(
|
||||
`Sikeres beküldés, ${res.totalNewQuestions} új kérdés`
|
||||
setForm({
|
||||
...form,
|
||||
quiz: quiz,
|
||||
})
|
||||
}
|
||||
|
||||
const renderStuff = () => {
|
||||
return (
|
||||
<div>
|
||||
{form.quiz.map((q, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<hr />
|
||||
<Question
|
||||
index={i}
|
||||
question={form.quiz[i] || {}}
|
||||
onChange={(newVal) => {
|
||||
handleQuestionChange(i, newVal)
|
||||
}}
|
||||
/>
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
deleteQuestion(i)
|
||||
}}
|
||||
>
|
||||
Törlés
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
} else {
|
||||
alert('Hiba beküldés közben :/')
|
||||
}
|
||||
refetchDbs()
|
||||
setIsSubmitting(false)
|
||||
})
|
||||
.catch((res) => {
|
||||
if (res === 'nosubj') {
|
||||
alert('Nem választottál ki tantárgyat!') // eslint-disable-line
|
||||
}
|
||||
if (res === 'notvalid') {
|
||||
alert('Kérdés kitöltése kötelező!') // eslint-disable-line
|
||||
}
|
||||
setIsSubmitting(false)
|
||||
})
|
||||
}}
|
||||
>
|
||||
{isSubmitting ? 'Beküldés folyamatban ...' : 'Kérdések beküldése'}
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="cid" name="cid" hidden />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})}
|
||||
<hr />
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
let quiz = form.quiz
|
||||
quiz.push(getDefaultQuestion())
|
||||
setForm({
|
||||
...form,
|
||||
quiz: quiz,
|
||||
})
|
||||
}}
|
||||
>
|
||||
Új kérdés
|
||||
</div>
|
||||
<div
|
||||
className={`${isSubmitting ? styles.issubmitting : ''}`}
|
||||
onClick={() => {
|
||||
if (isSubmitting) {
|
||||
return
|
||||
}
|
||||
setIsSubmitting(true)
|
||||
handleSubmit(form)
|
||||
.then((res) => {
|
||||
// console.log(res)
|
||||
// {
|
||||
// "success": true,
|
||||
// "newQuestions": [
|
||||
// {
|
||||
// "newQuestions": 1,
|
||||
// "qdbName": "elearning.uni-obuda.hu"
|
||||
// }
|
||||
// ],
|
||||
// "totalNewQuestions": 1
|
||||
// }
|
||||
|
||||
if (res.success) {
|
||||
alert(
|
||||
`Sikeres beküldés, ${res.totalNewQuestions} új kérdés`
|
||||
)
|
||||
} else {
|
||||
alert('Hiba beküldés közben :/')
|
||||
}
|
||||
refetchDbs()
|
||||
setIsSubmitting(false)
|
||||
})
|
||||
.catch((res) => {
|
||||
if (res === 'nosubj') {
|
||||
alert('Nem választottál ki tantárgyat!') // eslint-disable-line
|
||||
}
|
||||
if (res === 'notvalid') {
|
||||
alert('Kérdés kitöltése kötelező!') // eslint-disable-line
|
||||
}
|
||||
setIsSubmitting(false)
|
||||
})
|
||||
}}
|
||||
>
|
||||
{isSubmitting
|
||||
? 'Beküldés folyamatban ...'
|
||||
: 'Kérdések beküldése'}
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="cid" name="cid" hidden />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const renderSubjSelector = () => {
|
||||
return (
|
||||
<div className={styles.subjSelectorContainer}>
|
||||
{isNewSubj ? (
|
||||
<input
|
||||
placeholder="Új tárgy neve..."
|
||||
type="text"
|
||||
className={styles.questionInput}
|
||||
onChange={(event) => {
|
||||
setForm({
|
||||
...form,
|
||||
subj: event.target.value,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<select
|
||||
onChange={(event) => {
|
||||
setForm({
|
||||
...form,
|
||||
subj: subjects[event.target.value],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option key={-1} value={-1}>
|
||||
Válassz egy tárgyat...
|
||||
</option>
|
||||
{subjects.map((subjName, i) => {
|
||||
return (
|
||||
<option key={i} value={i}>
|
||||
{subjName}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
)}
|
||||
<div
|
||||
className={commonStyles.actions}
|
||||
onClick={() => {
|
||||
setIsNewSubj(!isNewSubj)
|
||||
}}
|
||||
>
|
||||
<div>{isNewSubj ? 'Létező tárgy ...' : 'Új tárgy ...'}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
const renderSubjSelector = () => {
|
||||
return (
|
||||
<div className={styles.subjSelectorContainer}>
|
||||
{isNewSubj ? (
|
||||
<input
|
||||
placeholder="Új tárgy neve..."
|
||||
type="text"
|
||||
className={styles.questionInput}
|
||||
onChange={(event) => {
|
||||
setForm({
|
||||
...form,
|
||||
subj: event.target.value,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<select
|
||||
onChange={(event) => {
|
||||
setForm({
|
||||
...form,
|
||||
subj: subjects[event.target.value],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option key={-1} value={-1}>
|
||||
Válassz egy tárgyat...
|
||||
</option>
|
||||
{subjects.map((subjName, i) => {
|
||||
return (
|
||||
<option key={i} value={i}>
|
||||
{subjName}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
)}
|
||||
<div
|
||||
className={commonStyles.actions}
|
||||
onClick={() => {
|
||||
setIsNewSubj(!isNewSubj)
|
||||
}}
|
||||
>
|
||||
<div>{isNewSubj ? 'Létező tárgy ...' : 'Új tárgy ...'}</div>
|
||||
<div>
|
||||
<hr />
|
||||
{renderUsage()}
|
||||
{subjects ? (
|
||||
<>
|
||||
<hr />
|
||||
{renderSubjSelector()}
|
||||
{renderStuff()}
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<hr />
|
||||
{renderUsage()}
|
||||
{subjects ? (
|
||||
<>
|
||||
<hr />
|
||||
{renderSubjSelector()}
|
||||
{renderStuff()}
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,206 +4,211 @@ import LoadingIndicator from '../components/LoadingIndicator.js'
|
|||
import QuestionSearchResult from '../components/QuestionSearchResult.js'
|
||||
import SearchBar from '../components/searchBar'
|
||||
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
// import styles from './questionView.module.css'
|
||||
|
||||
const updateQuestion = (e, selectedDb) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...e,
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...e,
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const rmQuestion = (e, selectedDb) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...e,
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...e,
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function questionView(props) {
|
||||
const { selectedDb } = props
|
||||
const [data, setData] = useState(props.data)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [edits, setEdits] = useState([])
|
||||
const { selectedDb } = props
|
||||
const [data, setData] = useState(props.data)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [edits, setEdits] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
setData(props.data)
|
||||
}, [props.data])
|
||||
useEffect(() => {
|
||||
setData(props.data)
|
||||
}, [props.data])
|
||||
|
||||
const updateEdits = (e) => {
|
||||
setEdits(
|
||||
edits.map((edit) => {
|
||||
if (edit.index === e.index) {
|
||||
return e
|
||||
} else {
|
||||
return edit
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const removeFromEdits = (e) => {
|
||||
setEdits(
|
||||
edits.filter((edit, i) => {
|
||||
return i !== e.index
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const onChange = (e) => {
|
||||
const editIndex = edits.findIndex((edit) => {
|
||||
return edit.subjName === e.subjName && edit.index === e.index
|
||||
})
|
||||
if (editIndex === -1) {
|
||||
if (e.type === 'edit') {
|
||||
if (editIndex === -1) {
|
||||
setEdits([...edits, e])
|
||||
}
|
||||
}
|
||||
if (e.type === 'delete') {
|
||||
rmQuestion(e, selectedDb).then((res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres törlés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
}
|
||||
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.filter((question, i) => {
|
||||
return i !== e.index
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (e.type === 'reset') {
|
||||
// edits -> saves -> resets? => should do nothing, no reset after saving
|
||||
removeFromEdits(e)
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.map((question, i) => {
|
||||
if (i !== e.index) {
|
||||
return question
|
||||
} else {
|
||||
const ps = props.data.find((subj) => {
|
||||
return subj.Name === e.subjName
|
||||
})
|
||||
if (ps) {
|
||||
return ps.Questions[i]
|
||||
}
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
if (e.type === 'save') {
|
||||
updateQuestion(
|
||||
edits.find((edit) => {
|
||||
return edit.index === e.index
|
||||
}),
|
||||
selectedDb
|
||||
).then((res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres mentés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
}
|
||||
|
||||
removeFromEdits(e)
|
||||
})
|
||||
}
|
||||
if (e.type === 'edit') {
|
||||
updateEdits(e)
|
||||
}
|
||||
}
|
||||
|
||||
if (e.type === 'edit') {
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.map((question, i) => {
|
||||
if (i !== e.index) {
|
||||
return question
|
||||
const updateEdits = (e) => {
|
||||
setEdits(
|
||||
edits.map((edit) => {
|
||||
if (edit.index === e.index) {
|
||||
return e
|
||||
} else {
|
||||
return e.newVal
|
||||
return edit
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return (
|
||||
<div>
|
||||
<SearchBar value={searchTerm} onChange={(e) => setSearchTerm(e)} />
|
||||
<hr />
|
||||
<div>
|
||||
<QuestionSearchResult
|
||||
onChange={onChange}
|
||||
data={data}
|
||||
searchTerm={searchTerm}
|
||||
edits={edits}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
const removeFromEdits = (e) => {
|
||||
setEdits(
|
||||
edits.filter((edit, i) => {
|
||||
return i !== e.index
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const onChange = (e) => {
|
||||
const editIndex = edits.findIndex((edit) => {
|
||||
return edit.subjName === e.subjName && edit.index === e.index
|
||||
})
|
||||
if (editIndex === -1) {
|
||||
if (e.type === 'edit') {
|
||||
if (editIndex === -1) {
|
||||
setEdits([...edits, e])
|
||||
}
|
||||
}
|
||||
if (e.type === 'delete') {
|
||||
rmQuestion(e, selectedDb).then((res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres törlés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
}
|
||||
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.filter(
|
||||
(question, i) => {
|
||||
return i !== e.index
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (e.type === 'reset') {
|
||||
// edits -> saves -> resets? => should do nothing, no reset after saving
|
||||
removeFromEdits(e)
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.map((question, i) => {
|
||||
if (i !== e.index) {
|
||||
return question
|
||||
} else {
|
||||
const ps = props.data.find((subj) => {
|
||||
return subj.Name === e.subjName
|
||||
})
|
||||
if (ps) {
|
||||
return ps.Questions[i]
|
||||
}
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
if (e.type === 'save') {
|
||||
updateQuestion(
|
||||
edits.find((edit) => {
|
||||
return edit.index === e.index
|
||||
}),
|
||||
selectedDb
|
||||
).then((res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres mentés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
}
|
||||
|
||||
removeFromEdits(e)
|
||||
})
|
||||
}
|
||||
if (e.type === 'edit') {
|
||||
updateEdits(e)
|
||||
}
|
||||
}
|
||||
|
||||
if (e.type === 'edit') {
|
||||
setData(
|
||||
data.map((subj) => {
|
||||
if (subj.Name !== e.subjName) {
|
||||
return subj
|
||||
} else {
|
||||
return {
|
||||
...subj,
|
||||
Questions: subj.Questions.map((question, i) => {
|
||||
if (i !== e.index) {
|
||||
return question
|
||||
} else {
|
||||
return e.newVal
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return (
|
||||
<div>
|
||||
<SearchBar
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e)}
|
||||
/>
|
||||
<hr />
|
||||
<div>
|
||||
<QuestionSearchResult
|
||||
onChange={onChange}
|
||||
data={data}
|
||||
searchTerm={searchTerm}
|
||||
edits={edits}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,221 +5,224 @@ import Subject from '../components/Subject.js'
|
|||
import SubjectSelector from '../components/SubjectSelector.js'
|
||||
import SearchBar from '../components/searchBar'
|
||||
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
// import styles from './subjectView.module.css'
|
||||
import commonStyles from '../commonStyles.module.css'
|
||||
|
||||
const onSave = (subjName, changedQuestions, deletedQuestions, selectedDb) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subjName: subjName,
|
||||
changedQuestions: changedQuestions,
|
||||
deletedQuestions: deletedQuestions,
|
||||
type: 'subjEdit',
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'updateQuestion', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subjName: subjName,
|
||||
changedQuestions: changedQuestions,
|
||||
deletedQuestions: deletedQuestions,
|
||||
type: 'subjEdit',
|
||||
selectedDb: selectedDb,
|
||||
}),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function SubjectView(props) {
|
||||
const { data, selectedDb } = props
|
||||
const [activeSubjName, setActiveSubjName] = useState('')
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const { data, selectedDb } = props
|
||||
const [activeSubjName, setActiveSubjName] = useState('')
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
|
||||
const [unsavedIndexes, setUnsavedIndexes] = useState([])
|
||||
const [editedIndexes, setEditedIndexes] = useState([])
|
||||
const [deletedIndexes, setDeletedIndexes] = useState([])
|
||||
const [subj, setSubj] = useState(null)
|
||||
const [unsavedIndexes, setUnsavedIndexes] = useState([])
|
||||
const [editedIndexes, setEditedIndexes] = useState([])
|
||||
const [deletedIndexes, setDeletedIndexes] = useState([])
|
||||
const [subj, setSubj] = useState(null)
|
||||
|
||||
const hasChange = editedIndexes.length > 0 || deletedIndexes.length > 0
|
||||
const hasChange = editedIndexes.length > 0 || deletedIndexes.length > 0
|
||||
|
||||
useEffect(() => {
|
||||
let currSubj = data.find((subj) => {
|
||||
return subj.Name === activeSubjName
|
||||
})
|
||||
setSubj(currSubj)
|
||||
}, [activeSubjName])
|
||||
|
||||
const resetQuestion = (i) => {
|
||||
if (deletedIndexes.includes(i)) {
|
||||
setDeletedIndexes(
|
||||
deletedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
useEffect(() => {
|
||||
let currSubj = data.find((subj) => {
|
||||
return subj.Name === activeSubjName
|
||||
})
|
||||
)
|
||||
}
|
||||
setSubj(currSubj)
|
||||
}, [activeSubjName])
|
||||
|
||||
if (editedIndexes.includes(i)) {
|
||||
setEditedIndexes(
|
||||
editedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (unsavedIndexes.includes(i)) {
|
||||
setUnsavedIndexes(
|
||||
unsavedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
let currSubj = data.find((subj) => {
|
||||
return subj.Name === activeSubjName
|
||||
})
|
||||
|
||||
setSubj({
|
||||
...subj,
|
||||
Questions: subj.Questions.map((q, j) => {
|
||||
if (i === j) {
|
||||
return currSubj.Questions[i]
|
||||
} else {
|
||||
return q
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const handleQuestionChange = (newq, i) => {
|
||||
if (!unsavedIndexes.includes(i)) {
|
||||
setUnsavedIndexes([...unsavedIndexes, i])
|
||||
}
|
||||
|
||||
if (editedIndexes.includes(i)) {
|
||||
setEditedIndexes(
|
||||
editedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
setSubj({
|
||||
...subj,
|
||||
Questions: subj.Questions.map((q, j) => {
|
||||
if (i !== j) {
|
||||
return q
|
||||
} else {
|
||||
return newq
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const saveQuestion = (i) => {
|
||||
setUnsavedIndexes(
|
||||
unsavedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
setEditedIndexes([...editedIndexes, i])
|
||||
}
|
||||
|
||||
const deleteQuestion = (i) => {
|
||||
setDeletedIndexes([...deletedIndexes, i])
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
if (unsavedIndexes.length > 0) {
|
||||
alert(
|
||||
'Mentetlen módosításaid vannak, kérek mentsd, vagy állítsd vissza azokat'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (editedIndexes.length === 0 && deletedIndexes.length === 0) {
|
||||
alert('Nem módosítottál még semmit')
|
||||
return
|
||||
}
|
||||
const changedQuestions = editedIndexes.map((ei) => {
|
||||
return {
|
||||
index: ei,
|
||||
value: subj.Questions[ei],
|
||||
}
|
||||
})
|
||||
const deletedQuestions = deletedIndexes
|
||||
onSave(subj.Name, changedQuestions, deletedQuestions, selectedDb).then(
|
||||
(res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres mentés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
const resetQuestion = (i) => {
|
||||
if (deletedIndexes.includes(i)) {
|
||||
setDeletedIndexes(
|
||||
deletedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
setUnsavedIndexes([])
|
||||
setEditedIndexes([])
|
||||
setDeletedIndexes([])
|
||||
}
|
||||
)
|
||||
}
|
||||
if (editedIndexes.includes(i)) {
|
||||
setEditedIndexes(
|
||||
editedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return (
|
||||
<div>
|
||||
<SearchBar value={searchTerm} onChange={(e) => setSearchTerm(e)} />
|
||||
<hr />
|
||||
<SubjectSelector
|
||||
data={data}
|
||||
activeSubjName={activeSubjName}
|
||||
searchTerm={searchTerm}
|
||||
onSubjSelect={(subjName) => {
|
||||
if (
|
||||
!hasChange ||
|
||||
confirm(
|
||||
'Mentetlen módosításaid vannak a tárgynál, biztos bezárod?'
|
||||
)
|
||||
) {
|
||||
setActiveSubjName(subjName)
|
||||
setUnsavedIndexes([])
|
||||
setEditedIndexes([])
|
||||
setDeletedIndexes([])
|
||||
} else {
|
||||
console.log('canceld')
|
||||
if (unsavedIndexes.includes(i)) {
|
||||
setUnsavedIndexes(
|
||||
unsavedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
let currSubj = data.find((subj) => {
|
||||
return subj.Name === activeSubjName
|
||||
})
|
||||
|
||||
setSubj({
|
||||
...subj,
|
||||
Questions: subj.Questions.map((q, j) => {
|
||||
if (i === j) {
|
||||
return currSubj.Questions[i]
|
||||
} else {
|
||||
return q
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const handleQuestionChange = (newq, i) => {
|
||||
if (!unsavedIndexes.includes(i)) {
|
||||
setUnsavedIndexes([...unsavedIndexes, i])
|
||||
}
|
||||
|
||||
if (editedIndexes.includes(i)) {
|
||||
setEditedIndexes(
|
||||
editedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
setSubj({
|
||||
...subj,
|
||||
Questions: subj.Questions.map((q, j) => {
|
||||
if (i !== j) {
|
||||
return q
|
||||
} else {
|
||||
return newq
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
const saveQuestion = (i) => {
|
||||
setUnsavedIndexes(
|
||||
unsavedIndexes.filter((ind) => {
|
||||
return ind !== i
|
||||
})
|
||||
)
|
||||
setEditedIndexes([...editedIndexes, i])
|
||||
}
|
||||
|
||||
const deleteQuestion = (i) => {
|
||||
setDeletedIndexes([...deletedIndexes, i])
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
if (unsavedIndexes.length > 0) {
|
||||
alert(
|
||||
'Mentetlen módosításaid vannak, kérek mentsd, vagy állítsd vissza azokat'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (editedIndexes.length === 0 && deletedIndexes.length === 0) {
|
||||
alert('Nem módosítottál még semmit')
|
||||
return
|
||||
}
|
||||
const changedQuestions = editedIndexes.map((ei) => {
|
||||
return {
|
||||
index: ei,
|
||||
value: subj.Questions[ei],
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<hr />
|
||||
<div className={commonStyles.actions}>
|
||||
{subj && (
|
||||
<div
|
||||
onClick={() => {
|
||||
handleSave()
|
||||
}}
|
||||
>
|
||||
Tárgy módosításainak mentése
|
||||
})
|
||||
const deletedQuestions = deletedIndexes
|
||||
onSave(subj.Name, changedQuestions, deletedQuestions, selectedDb).then(
|
||||
(res) => {
|
||||
if (res.success) {
|
||||
alert('Sikeres mentés')
|
||||
} else {
|
||||
alert('Hiba mentés közben :/')
|
||||
}
|
||||
|
||||
setUnsavedIndexes([])
|
||||
setEditedIndexes([])
|
||||
setDeletedIndexes([])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return (
|
||||
<div>
|
||||
<SearchBar
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e)}
|
||||
/>
|
||||
<hr />
|
||||
<SubjectSelector
|
||||
data={data}
|
||||
activeSubjName={activeSubjName}
|
||||
searchTerm={searchTerm}
|
||||
onSubjSelect={(subjName) => {
|
||||
if (
|
||||
!hasChange ||
|
||||
confirm(
|
||||
'Mentetlen módosításaid vannak a tárgynál, biztos bezárod?'
|
||||
)
|
||||
) {
|
||||
setActiveSubjName(subjName)
|
||||
setUnsavedIndexes([])
|
||||
setEditedIndexes([])
|
||||
setDeletedIndexes([])
|
||||
} else {
|
||||
console.log('canceld')
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<hr />
|
||||
<div className={commonStyles.actions}>
|
||||
{subj && (
|
||||
<div
|
||||
onClick={() => {
|
||||
handleSave()
|
||||
}}
|
||||
>
|
||||
Tárgy módosításainak mentése
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{subj && (
|
||||
<Subject
|
||||
subj={subj}
|
||||
unsavedIndexes={unsavedIndexes}
|
||||
editedIndexes={editedIndexes}
|
||||
deletedIndexes={deletedIndexes}
|
||||
resetQuestion={resetQuestion}
|
||||
handleQuestionChange={handleQuestionChange}
|
||||
saveQuestion={saveQuestion}
|
||||
deleteQuestion={deleteQuestion}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{subj && (
|
||||
<Subject
|
||||
subj={subj}
|
||||
unsavedIndexes={unsavedIndexes}
|
||||
editedIndexes={editedIndexes}
|
||||
deletedIndexes={deletedIndexes}
|
||||
resetQuestion={resetQuestion}
|
||||
handleQuestionChange={handleQuestionChange}
|
||||
saveQuestion={saveQuestion}
|
||||
deleteQuestion={deleteQuestion}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
)
|
||||
} else {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,188 +2,199 @@ import React, { useState } from 'react'
|
|||
|
||||
import Question from '../components/Question'
|
||||
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
import styles from './testView.module.css'
|
||||
import commonStyles from '../commonStyles.module.css'
|
||||
|
||||
const rmTest = (subjName, testName) => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'rmPossibleAnswer', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subj: subjName,
|
||||
file: testName,
|
||||
}),
|
||||
return new Promise((resolve) => {
|
||||
fetch(constants.apiUrl + 'rmPossibleAnswer', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subj: subjName,
|
||||
file: testName,
|
||||
}),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function TestView(props) {
|
||||
const { subjName, testName, router, onDelete } = props
|
||||
const [test, setTest] = useState(props.test)
|
||||
const { subjName, testName, router, onDelete } = props
|
||||
const [test, setTest] = useState(props.test)
|
||||
|
||||
const renderActions = () => {
|
||||
return (
|
||||
<div className={styles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
if (confirm('Biztos véglegesen törlöd ezt az egész tesztet?')) {
|
||||
rmTest(subjName, testName).then((res) => {
|
||||
if (res.res === 'ok') {
|
||||
// alert('sikeres törlés')
|
||||
router.back()
|
||||
onDelete()
|
||||
} else {
|
||||
alert('hiba törlés közben!')
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
Teszt törlése
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
if (
|
||||
confirm(
|
||||
'Biztos beküldöd? Beküldés után törlődik a teszt, de a Kérdések/Tárgyak nézetnél megtalálhatóak lesznek'
|
||||
)
|
||||
) {
|
||||
const questions = test.questions.map((q) => {
|
||||
return {
|
||||
Q: q.Q,
|
||||
A: q.A,
|
||||
data: {
|
||||
...q.data,
|
||||
...(q.possibleAnswers && {
|
||||
possibleAnswers: q.possibleAnswers,
|
||||
}),
|
||||
},
|
||||
}
|
||||
})
|
||||
const toSend = {
|
||||
id: 'WEBSITE',
|
||||
version: 'WEBSITE',
|
||||
location: `https://${test.testUrl}`,
|
||||
subj: test.subj,
|
||||
quiz: questions,
|
||||
}
|
||||
|
||||
fetch(constants.apiUrl + 'isAdding', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(toSend),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
alert(
|
||||
`Sikeres beküldés, ${res.totalNewQuestions} új kérdés`
|
||||
)
|
||||
rmTest(subjName, testName).then((res) => {
|
||||
if (res.res === 'ok') {
|
||||
router.back()
|
||||
onDelete()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
alert('Hiba beküldés közben :/')
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
Teszt mentése
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.headerContainer}>
|
||||
<div className={styles.header}>
|
||||
<div>Tárgy neve</div>
|
||||
<div>{test.subj}</div>
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Teszt URL</div>
|
||||
<div>{test.testUrl}</div>
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Beküldő felhasználó ID</div>
|
||||
<div>{test.userid}</div>{' '}
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Beküldés ideje</div>
|
||||
<div>{new Date(test.date).toLocaleString()}</div>{' '}
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{renderActions()}
|
||||
<div className={styles.questionsContainer}>
|
||||
{test.questions.map((question, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<hr key={`${i}hr`} />
|
||||
<div key={i}>
|
||||
<Question
|
||||
index={i}
|
||||
onChange={(newQ) => {
|
||||
setTest({
|
||||
...test,
|
||||
questions: test.questions.map((q, j) => {
|
||||
if (j === i) {
|
||||
return newQ
|
||||
}
|
||||
return q
|
||||
}),
|
||||
})
|
||||
}}
|
||||
question={question}
|
||||
/>
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
const renderActions = () => {
|
||||
return (
|
||||
<div className={styles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
setTest({
|
||||
...test,
|
||||
questions: test.questions.filter((q, j) => {
|
||||
return j !== i
|
||||
}),
|
||||
})
|
||||
if (
|
||||
confirm(
|
||||
'Biztos véglegesen törlöd ezt az egész tesztet?'
|
||||
)
|
||||
) {
|
||||
rmTest(subjName, testName).then((res) => {
|
||||
if (res.res === 'ok') {
|
||||
// alert('sikeres törlés')
|
||||
router.back()
|
||||
onDelete()
|
||||
} else {
|
||||
alert('hiba törlés közben!')
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
Kérdés törlése
|
||||
</div>
|
||||
>
|
||||
Teszt törlése
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{test.questions.length > 2 ? (
|
||||
<>
|
||||
<hr />
|
||||
{renderActions()}
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
<div
|
||||
onClick={() => {
|
||||
if (
|
||||
confirm(
|
||||
'Biztos beküldöd? Beküldés után törlődik a teszt, de a Kérdések/Tárgyak nézetnél megtalálhatóak lesznek'
|
||||
)
|
||||
) {
|
||||
const questions = test.questions.map((q) => {
|
||||
return {
|
||||
Q: q.Q,
|
||||
A: q.A,
|
||||
data: {
|
||||
...q.data,
|
||||
...(q.possibleAnswers && {
|
||||
possibleAnswers: q.possibleAnswers,
|
||||
}),
|
||||
},
|
||||
}
|
||||
})
|
||||
const toSend = {
|
||||
id: 'WEBSITE',
|
||||
version: 'WEBSITE',
|
||||
location: `https://${test.testUrl}`,
|
||||
subj: test.subj,
|
||||
quiz: questions,
|
||||
}
|
||||
|
||||
fetch(constants.apiUrl + 'isAdding', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(toSend),
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json()
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
alert(
|
||||
`Sikeres beküldés, ${res.totalNewQuestions} új kérdés`
|
||||
)
|
||||
rmTest(subjName, testName).then(
|
||||
(res) => {
|
||||
if (res.res === 'ok') {
|
||||
router.back()
|
||||
onDelete()
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
alert('Hiba beküldés közben :/')
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
Teszt mentése
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.headerContainer}>
|
||||
<div className={styles.header}>
|
||||
<div>Tárgy neve</div>
|
||||
<div>{test.subj}</div>
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Teszt URL</div>
|
||||
<div>{test.testUrl}</div>
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Beküldő felhasználó ID</div>
|
||||
<div>{test.userid}</div>{' '}
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<div>Beküldés ideje</div>
|
||||
<div>{new Date(test.date).toLocaleString()}</div>{' '}
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{renderActions()}
|
||||
<div className={styles.questionsContainer}>
|
||||
{test.questions.map((question, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<hr key={`${i}hr`} />
|
||||
<div key={i}>
|
||||
<Question
|
||||
index={i}
|
||||
onChange={(newQ) => {
|
||||
setTest({
|
||||
...test,
|
||||
questions: test.questions.map(
|
||||
(q, j) => {
|
||||
if (j === i) {
|
||||
return newQ
|
||||
}
|
||||
return q
|
||||
}
|
||||
),
|
||||
})
|
||||
}}
|
||||
question={question}
|
||||
/>
|
||||
<div className={commonStyles.actions}>
|
||||
<div
|
||||
onClick={() => {
|
||||
setTest({
|
||||
...test,
|
||||
questions:
|
||||
test.questions.filter(
|
||||
(q, j) => {
|
||||
return j !== i
|
||||
}
|
||||
),
|
||||
})
|
||||
}}
|
||||
>
|
||||
Kérdés törlése
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{test.questions.length > 2 ? (
|
||||
<>
|
||||
<hr />
|
||||
{renderActions()}
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
19
src/constants.js
Normal file
19
src/constants.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
// eslint-disable-next-line no-undef
|
||||
const useLocalhost = process && process.env.NODE_ENV === 'development'
|
||||
// eslint-disable-next-line no-undef
|
||||
const domain = process && process.env.DOMAIN
|
||||
|
||||
if (!domain && !useLocalhost) {
|
||||
throw new Error('Domain is not defined! Please set DOMAIN env variable!')
|
||||
}
|
||||
|
||||
const constants = {
|
||||
domain: domain || 'localhost',
|
||||
siteUrl: useLocalhost ? 'http://localhost:8080/' : `https://${domain}/`,
|
||||
apiUrl: useLocalhost
|
||||
? 'http://localhost:8080/api/'
|
||||
: `https://${domain}/api/`,
|
||||
maxQuestionsToRender: 250,
|
||||
}
|
||||
|
||||
export default constants
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"siteUrl": "https://qmining.frylabs.net/",
|
||||
"apiUrl": "https://api.frylabs.net/",
|
||||
"maxQuestionsToRender": 250
|
||||
}
|
|
@ -11,302 +11,328 @@ import LoadingIndicator from '../components/LoadingIndicator'
|
|||
|
||||
import styles from './index.module.css'
|
||||
import commonStyles from '../commonStyles.module.css'
|
||||
import constants from '../constants.json'
|
||||
import constants from '../constants.js'
|
||||
|
||||
const Infos = ({ onClick, renderOKButton }) => {
|
||||
return (
|
||||
<div className={commonStyles.infoContainer}>
|
||||
<div className={commonStyles.infoHeader}>Kérdés szerkesztő</div>
|
||||
<div>
|
||||
Ezen az oldalon az éles adatbázisban levő kérdéseket tudod szerkeszteni,
|
||||
vagy azokhoz tudsz adni.{' '}
|
||||
<b>
|
||||
A törléshez és módosításokhoz nem kér megerősítést, ezek azonnal
|
||||
megtörténnek, és nem visszavonhatóak.
|
||||
</b>
|
||||
</div>
|
||||
<div>
|
||||
<i>Néhány dolog, amit kérlek tarts be szerkesztés közben:</i>
|
||||
<div style={{ textAlign: 'left', width: '700px' }}>
|
||||
<ul>
|
||||
<li>
|
||||
Ne rontsd el a kérdéseket sok törléssel / rossz válasz
|
||||
megadásával. Sok más felhasználónak lesz rossz, és visszakereshető
|
||||
/ tiltható a módosító
|
||||
</li>
|
||||
<li>
|
||||
Arra is vigyázz, hogy véletlen se történjen ilyesmi, vagy ha mégis
|
||||
valami baj történt, akkor azt{' '}
|
||||
<a href={`${constants.siteUrl}irc`}>jelezd</a>. Van sok biztonsági
|
||||
mentés
|
||||
</li>
|
||||
<li>
|
||||
Ahhoz, hogy a script megtalálja a helyes választ a kérdés
|
||||
szövegének <b>pontosan</b> olyannak kell lennie, mint a teszt
|
||||
közben (elírásokkal, .... -okkal, meg mindennel)
|
||||
</li>
|
||||
</ul>
|
||||
return (
|
||||
<div className={commonStyles.infoContainer}>
|
||||
<div className={commonStyles.infoHeader}>Kérdés szerkesztő</div>
|
||||
<div>
|
||||
Ezen az oldalon az éles adatbázisban levő kérdéseket tudod
|
||||
szerkeszteni, vagy azokhoz tudsz adni.{' '}
|
||||
<b>
|
||||
A törléshez és módosításokhoz nem kér megerősítést, ezek
|
||||
azonnal megtörténnek, és nem visszavonhatóak.
|
||||
</b>
|
||||
</div>
|
||||
<div>
|
||||
<i>Néhány dolog, amit kérlek tarts be szerkesztés közben:</i>
|
||||
<div style={{ textAlign: 'left', width: '700px' }}>
|
||||
<ul>
|
||||
<li>
|
||||
Ne rontsd el a kérdéseket sok törléssel / rossz
|
||||
válasz megadásával. Sok más felhasználónak lesz
|
||||
rossz, és visszakereshető / tiltható a módosító
|
||||
</li>
|
||||
<li>
|
||||
Arra is vigyázz, hogy véletlen se történjen ilyesmi,
|
||||
vagy ha mégis valami baj történt, akkor azt{' '}
|
||||
<a href={`${constants.siteUrl}irc`}>jelezd</a>. Van
|
||||
sok biztonsági mentés
|
||||
</li>
|
||||
<li>
|
||||
Ahhoz, hogy a script megtalálja a helyes választ a
|
||||
kérdés szövegének <b>pontosan</b> olyannak kell
|
||||
lennie, mint a teszt közben (elírásokkal, ....
|
||||
-okkal, meg mindennel)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
Ha akármi kérdés van{' '}
|
||||
<a
|
||||
href={`${constants.siteUrl}contact`}
|
||||
target={'_blank'}
|
||||
rel={'noreferrer'}
|
||||
>
|
||||
itt lehet üzenetet küldeni
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</div>
|
||||
{renderOKButton && (
|
||||
<div className={commonStyles.infoReadButton} onClick={onClick}>
|
||||
OK
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
Ha akármi kérdés van{' '}
|
||||
<a
|
||||
href={`${constants.siteUrl}contact`}
|
||||
target={'_blank'}
|
||||
rel={'noreferrer'}
|
||||
>
|
||||
itt lehet üzenetet küldeni
|
||||
</a>
|
||||
.
|
||||
</div>
|
||||
</div>
|
||||
{renderOKButton && (
|
||||
<div className={commonStyles.infoReadButton} onClick={onClick}>
|
||||
OK
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const fetchDbs = () => {
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}getDbs`, {
|
||||
credentials: 'include',
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}getDbs`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const fetchData = (selectedDb) => {
|
||||
return new Promise((resolve) => {
|
||||
const toFetch = `${constants.apiUrl}${selectedDb.path}`
|
||||
fetch(toFetch, {
|
||||
credentials: 'include',
|
||||
return new Promise((resolve) => {
|
||||
const toFetch = `${constants.apiUrl}${selectedDb.path}`
|
||||
fetch(toFetch, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
.then((resp) => {
|
||||
return resp.json()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const views = {
|
||||
welcome: 'w',
|
||||
subject: 's',
|
||||
question: 'q',
|
||||
questionAdder: 'qa',
|
||||
possibleAnswers: 'pa',
|
||||
welcome: 'w',
|
||||
subject: 's',
|
||||
question: 'q',
|
||||
questionAdder: 'qa',
|
||||
possibleAnswers: 'pa',
|
||||
}
|
||||
|
||||
export default function Index({ router }) {
|
||||
const [infoRead, setInfoRead] = useState(false)
|
||||
const [data, setData] = useState(null)
|
||||
const [qdbs, setQdbs] = useState(null)
|
||||
const [selectedDb, setSelectedDb] = useState(null)
|
||||
const [view, setView] = useState(views.welcome)
|
||||
const [infoRead, setInfoRead] = useState(false)
|
||||
const [data, setData] = useState(null)
|
||||
const [qdbs, setQdbs] = useState(null)
|
||||
const [selectedDb, setSelectedDb] = useState(null)
|
||||
const [view, setView] = useState(views.welcome)
|
||||
|
||||
const [error, setError] = useState(null)
|
||||
const [error, setError] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDb) {
|
||||
loadData()
|
||||
} else {
|
||||
setData(null)
|
||||
}
|
||||
}, [selectedDb])
|
||||
useEffect(() => {
|
||||
if (selectedDb) {
|
||||
loadData()
|
||||
} else {
|
||||
setData(null)
|
||||
}
|
||||
}, [selectedDb])
|
||||
|
||||
useEffect(() => {
|
||||
fetchDbs().then((resp) => {
|
||||
setQdbs(resp)
|
||||
useEffect(() => {
|
||||
fetchDbs().then((resp) => {
|
||||
setQdbs(resp)
|
||||
|
||||
const view = router.query.v
|
||||
? decodeURIComponent(router.query.v)
|
||||
: views.welcome
|
||||
setView(view)
|
||||
})
|
||||
}, [])
|
||||
const view = router.query.v
|
||||
? decodeURIComponent(router.query.v)
|
||||
: views.welcome
|
||||
setView(view)
|
||||
})
|
||||
}, [])
|
||||
|
||||
const loadData = () => {
|
||||
setData(null)
|
||||
if (!selectedDb) {
|
||||
alert('Válassz egy adatbázist!')
|
||||
return
|
||||
}
|
||||
const loadData = () => {
|
||||
setData(null)
|
||||
if (!selectedDb) {
|
||||
alert('Válassz egy adatbázist!')
|
||||
return
|
||||
}
|
||||
|
||||
fetchData(selectedDb)
|
||||
.then((resp) => {
|
||||
setData(resp)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
console.error('Error while fetching data')
|
||||
setError('Error while fetching data')
|
||||
})
|
||||
}
|
||||
|
||||
const refetchDbs = () => {
|
||||
if (selectedDb) {
|
||||
fetchData(selectedDb).then((resp) => {
|
||||
setData(resp)
|
||||
})
|
||||
}
|
||||
fetchDbs().then((resp) => {
|
||||
setQdbs(resp)
|
||||
})
|
||||
}
|
||||
|
||||
const renderView = () => {
|
||||
if (view === views.subject) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Tárgyak - Data Editor | Frylabs.net</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
{data && <SubjectView selectedDb={selectedDb} data={data} />}
|
||||
</>
|
||||
)
|
||||
} else if (view === views.question) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Kérdések - Data Editor | Frylabs.net</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
{data && <QuestionView selectedDb={selectedDb} data={data} />}
|
||||
</>
|
||||
)
|
||||
} else if (view === views.questionAdder) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Kérdés beküldés - Data Editor | Frylabs.net</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
hideLockedDbs
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
<QuestionAdder
|
||||
data={data}
|
||||
selectedDb={selectedDb}
|
||||
refetchDbs={refetchDbs}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
} else if (view === views.possibleAnswers) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Kitöltetlen tesztek - Data Editor | Frylabs.net</title>
|
||||
</Head>
|
||||
<PossibleAnswers refetchDbs={refetchDbs} router={router} />
|
||||
</>
|
||||
)
|
||||
} else if (view === views.welcome) {
|
||||
return <Infos renderOKButton={false} />
|
||||
} else {
|
||||
return <div>No view!</div>
|
||||
}
|
||||
}
|
||||
|
||||
function renderViewSelector() {
|
||||
return (
|
||||
<div className={styles.viewButtonContainer}>
|
||||
<div
|
||||
className={view === views.question ? styles.activeView : undefined}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.question}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
setView(views.question)
|
||||
}}
|
||||
>
|
||||
Kérdések
|
||||
</div>
|
||||
<div
|
||||
title={
|
||||
'Választott adatbázisban lévő tárgyak megjelenítése, és tárgyakon belüli kérdések szerkesztése'
|
||||
}
|
||||
className={view === views.subject ? styles.activeView : undefined}
|
||||
onClick={() => {
|
||||
router.replace(`${router.pathname}?v=${views.subject}`, undefined, {
|
||||
shallow: true,
|
||||
fetchData(selectedDb)
|
||||
.then((resp) => {
|
||||
setData(resp)
|
||||
})
|
||||
setView(views.subject)
|
||||
}}
|
||||
>
|
||||
Tárgyak
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
view === views.questionAdder ? styles.activeView : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.questionAdder}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
console.error('Error while fetching data')
|
||||
setError('Error while fetching data')
|
||||
})
|
||||
}
|
||||
|
||||
const refetchDbs = () => {
|
||||
if (selectedDb) {
|
||||
fetchData(selectedDb).then((resp) => {
|
||||
setData(resp)
|
||||
})
|
||||
}
|
||||
fetchDbs().then((resp) => {
|
||||
setQdbs(resp)
|
||||
})
|
||||
}
|
||||
|
||||
const renderView = () => {
|
||||
if (view === views.subject) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Tárgyak - Data Editor | {constants.domain}
|
||||
</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
{data && (
|
||||
<SubjectView selectedDb={selectedDb} data={data} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
setView(views.questionAdder)
|
||||
setSelectedDb(null)
|
||||
}}
|
||||
>
|
||||
Kérdés beküldés
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
view === views.possibleAnswers ? styles.activeView : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.possibleAnswers}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
} else if (view === views.question) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Kérdések - Data Editor | {constants.domain}
|
||||
</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
{data && (
|
||||
<QuestionView selectedDb={selectedDb} data={data} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
setView(views.possibleAnswers)
|
||||
}}
|
||||
>
|
||||
Kitöltetlen tesztek
|
||||
} else if (view === views.questionAdder) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Kérdés beküldés - Data Editor | {constants.domain}
|
||||
</title>
|
||||
</Head>
|
||||
<DbSelector
|
||||
hideLockedDbs
|
||||
qdbs={qdbs}
|
||||
selectedDb={selectedDb}
|
||||
onChange={setSelectedDb}
|
||||
/>
|
||||
<QuestionAdder
|
||||
data={data}
|
||||
selectedDb={selectedDb}
|
||||
refetchDbs={refetchDbs}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
} else if (view === views.possibleAnswers) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
Kitöltetlen tesztek - Data Editor |{' '}
|
||||
{constants.domain}
|
||||
</title>
|
||||
</Head>
|
||||
<PossibleAnswers refetchDbs={refetchDbs} router={router} />
|
||||
</>
|
||||
)
|
||||
} else if (view === views.welcome) {
|
||||
return <Infos renderOKButton={false} />
|
||||
} else {
|
||||
return <div>No view!</div>
|
||||
}
|
||||
}
|
||||
|
||||
function renderViewSelector() {
|
||||
return (
|
||||
<div className={styles.viewButtonContainer}>
|
||||
<div
|
||||
className={
|
||||
view === views.question ? styles.activeView : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.question}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
setView(views.question)
|
||||
}}
|
||||
>
|
||||
Kérdések
|
||||
</div>
|
||||
<div
|
||||
title={
|
||||
'Választott adatbázisban lévő tárgyak megjelenítése, és tárgyakon belüli kérdések szerkesztése'
|
||||
}
|
||||
className={
|
||||
view === views.subject ? styles.activeView : undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.subject}`,
|
||||
undefined,
|
||||
{
|
||||
shallow: true,
|
||||
}
|
||||
)
|
||||
setView(views.subject)
|
||||
}}
|
||||
>
|
||||
Tárgyak
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
view === views.questionAdder
|
||||
? styles.activeView
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.questionAdder}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
setView(views.questionAdder)
|
||||
setSelectedDb(null)
|
||||
}}
|
||||
>
|
||||
Kérdés beküldés
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
view === views.possibleAnswers
|
||||
? styles.activeView
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
router.replace(
|
||||
`${router.pathname}?v=${views.possibleAnswers}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
setView(views.possibleAnswers)
|
||||
}}
|
||||
>
|
||||
Kitöltetlen tesztek
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div>{error}</div>
|
||||
}
|
||||
|
||||
if (!infoRead) {
|
||||
return <Infos onClick={() => setInfoRead(true)} renderOKButton />
|
||||
}
|
||||
|
||||
if (!qdbs) {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{renderViewSelector()}
|
||||
{renderView()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div>{error}</div>
|
||||
}
|
||||
|
||||
if (!infoRead) {
|
||||
return <Infos onClick={() => setInfoRead(true)} renderOKButton />
|
||||
}
|
||||
|
||||
if (!qdbs) {
|
||||
return <LoadingIndicator />
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{renderViewSelector()}
|
||||
{renderView()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue