mirror of
https://gitlab.com/MrFry/qmining-page
synced 2025-04-01 20:23:44 +02:00
npm packages update
This commit is contained in:
parent
ed507dc39f
commit
32522097c0
51 changed files with 3247 additions and 5187 deletions
365
src/pages/allQuestions.jsx
Normal file
365
src/pages/allQuestions.jsx
Normal file
|
@ -0,0 +1,365 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
import Header from '../components/header'
|
||||
import LoadingIndicator from '../components/LoadingIndicator'
|
||||
import QuestionSearchResult from '../components/QuestionSearchResult'
|
||||
import Subject from '../components/Subject'
|
||||
import SubjectSelector from '../components/SubjectSelector'
|
||||
import ExternalLinkIcon from '../components/externalLinkIcon'
|
||||
import SearchBar from '../components/searchBar'
|
||||
|
||||
import styles from './allQuestions.module.css'
|
||||
|
||||
import constants from '../constants.json'
|
||||
|
||||
const countReducer = (acc, subj) => {
|
||||
return acc + subj.Questions.length
|
||||
}
|
||||
|
||||
function mergeData(data) {
|
||||
return data.reduce((acc, db) => {
|
||||
return [
|
||||
...acc,
|
||||
...db.data.map((subj) => {
|
||||
return {
|
||||
...subj,
|
||||
Name: `${subj.Name} [ DB: ${db.dbName} ]`,
|
||||
}
|
||||
}),
|
||||
]
|
||||
}, [])
|
||||
}
|
||||
|
||||
function fetchData(db) {
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}${db.path}`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return respon()
|
||||
})
|
||||
.then((resp) => {
|
||||
resolve({
|
||||
dbName: db.name,
|
||||
data: resp,
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function fetchAllData(dbs) {
|
||||
const promises = dbs.map((db) => {
|
||||
return fetchData(db)
|
||||
})
|
||||
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
function fetchDbs() {
|
||||
return new Promise((resolve) => {
|
||||
fetch(`${constants.apiUrl}getDbs`, {
|
||||
credentials: 'include',
|
||||
})
|
||||
.then((resp) => {
|
||||
return respon()
|
||||
})
|
||||
.then((data) => {
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function AllQuestions({ router, globalState, setGlobalState }) {
|
||||
const [subjectsShowing, setSubjectsShowing] = useState(false)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [activeSubjName, setActiveSubjName] = useState('')
|
||||
const [dbs, setDbs] = useState(null)
|
||||
const [selectedDb, setSelectedDb] = useState(-1)
|
||||
const [data, setData] = useState(null)
|
||||
const [fetchingData, setFetchingData] = useState(false)
|
||||
|
||||
const subjectCount = data ? data.length : 0
|
||||
const questionCount = data ? data.reduce(countReducer, 0) : 0
|
||||
|
||||
useEffect(() => {
|
||||
router.replace(`${router.asPath.replace('.html', '')}`, undefined, {
|
||||
shallow: true,
|
||||
})
|
||||
if (globalState.qdbs) {
|
||||
setDbs(globalState.qdbs)
|
||||
} else {
|
||||
fetchDbs().then((res) => {
|
||||
setDbs(res)
|
||||
setGlobalState({
|
||||
qdbs: res,
|
||||
})
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const db = router.query.db ? decodeURIComponent(router.query.db) : ''
|
||||
|
||||
if (db) {
|
||||
setSelectedDb(db)
|
||||
}
|
||||
}, [router.query.db])
|
||||
|
||||
useEffect(() => {
|
||||
const querySearch = router.query.question
|
||||
? decodeURIComponent(router.query.question)
|
||||
: ''
|
||||
|
||||
if (querySearch) {
|
||||
setSearchTerm(querySearch)
|
||||
}
|
||||
}, [router.query.question])
|
||||
|
||||
useEffect(() => {
|
||||
if (dbs && selectedDb && (selectedDb === 'all' || dbs[selectedDb])) {
|
||||
if (selectedDb === 'all') {
|
||||
const hasAll =
|
||||
globalState.dbs &&
|
||||
dbs.every((db) => {
|
||||
return (
|
||||
Object.keys(globalState.dbs).findIndex((key) => {
|
||||
return db.name === key
|
||||
}) !== -1
|
||||
)
|
||||
})
|
||||
|
||||
if (hasAll) {
|
||||
const asd = Object.keys(globalState.dbs).map((key) => {
|
||||
return {
|
||||
dbName: key,
|
||||
data: globalState.dbs[key],
|
||||
}
|
||||
})
|
||||
setData(mergeData(asd))
|
||||
setFetchingData(false)
|
||||
} else {
|
||||
fetchAllData(dbs).then((res) => {
|
||||
setData(mergeData(res))
|
||||
setFetchingData(false)
|
||||
|
||||
let cacheRes = {}
|
||||
res.forEach((db) => {
|
||||
cacheRes = {
|
||||
...cacheRes,
|
||||
[db.dbName]: db.data,
|
||||
}
|
||||
})
|
||||
setGlobalState({
|
||||
dbs: cacheRes,
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const selected = dbs[selectedDb]
|
||||
if (globalState.dbs && globalState.dbs[selected.name]) {
|
||||
setData(globalState.dbs[selected.name])
|
||||
setFetchingData(false)
|
||||
} else {
|
||||
fetchData(dbs[selectedDb]).then((res) => {
|
||||
setData(res.data)
|
||||
setFetchingData(false)
|
||||
|
||||
setGlobalState({
|
||||
dbs: {
|
||||
...globalState.dbs,
|
||||
[res.dbName]: res.data,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [selectedDb, dbs])
|
||||
|
||||
const renderDbSelector = () => {
|
||||
if (dbs) {
|
||||
return (
|
||||
<>
|
||||
<div className={'pageHeader'}>
|
||||
<h1>Kérdések és tárgyak</h1>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div className={'description'}>
|
||||
Ezen az oldalon tudsz manuálisan keresni a kérdések és a tárgyak
|
||||
között, vagy ellenőrizni, hogy egy adott tárgy szerepel-e a
|
||||
kérdés- és tárgyadatbázisban. Ezen kívül a kérdéseket le is
|
||||
töltheted offline használatra. (txt formátumban)
|
||||
</div>
|
||||
<div className={'buttonContainer'}>
|
||||
<div
|
||||
onClick={() => {
|
||||
window.open(`${constants.siteUrl}dataeditor`, '_blank')
|
||||
}}
|
||||
>
|
||||
Kérdés szerkesztő
|
||||
<ExternalLinkIcon size={15} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'selectContainer'}>
|
||||
<select
|
||||
value={selectedDb}
|
||||
onChange={(event) => {
|
||||
const key = event.target.value
|
||||
setData(null)
|
||||
setSelectedDb(key)
|
||||
if (parseInt(key) === -1) {
|
||||
router.replace(
|
||||
`${router.pathname}?question=${encodeURIComponent(
|
||||
searchTerm
|
||||
)}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
return
|
||||
}
|
||||
setFetchingData(true)
|
||||
|
||||
router.replace(
|
||||
`${router.pathname}?question=${encodeURIComponent(
|
||||
searchTerm
|
||||
)}&db=${key}`,
|
||||
undefined,
|
||||
{ shallow: true }
|
||||
)
|
||||
}}
|
||||
>
|
||||
<option value={-1}>{' Válassz egy adatbázist!'}</option>
|
||||
{dbs.map((db, i) => {
|
||||
return (
|
||||
<option value={i} key={db.path}>
|
||||
{db.name}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
<option value={'all'} key={'all'}>
|
||||
{'Összes kérdés'}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const renderSubjectBrowser = () => {
|
||||
let currSubj = data
|
||||
? data.find((subj) => {
|
||||
return subj.Name === activeSubjName
|
||||
})
|
||||
: {}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data ? (
|
||||
<>
|
||||
<SearchBar
|
||||
searchTerm={searchTerm}
|
||||
onChange={(e) => {
|
||||
setSearchTerm(e)
|
||||
}}
|
||||
/>
|
||||
<hr />
|
||||
<SubjectSelector
|
||||
data={data}
|
||||
activeSubjName={activeSubjName}
|
||||
searchTerm={searchTerm}
|
||||
onSubjSelect={(subjName) => {
|
||||
setActiveSubjName(subjName)
|
||||
}}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<hr />
|
||||
<Subject subj={currSubj} />
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const renderQuestionBrowser = () => {
|
||||
return (
|
||||
<div>
|
||||
{data ? (
|
||||
<>
|
||||
<SearchBar
|
||||
searchTerm={searchTerm}
|
||||
onChange={(e) => {
|
||||
setSearchTerm(e)
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<QuestionSearchResult data={data} searchTerm={searchTerm} />
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header title={'Kérdések és tárgyak'} />
|
||||
{dbs ? <>{renderDbSelector()}</> : <LoadingIndicator />}
|
||||
{dbs && data ? (
|
||||
<>
|
||||
<div className={styles.info}>
|
||||
{`Összesen ${questionCount.toLocaleString()} kérdés, ${subjectCount} tárgyból`}
|
||||
</div>
|
||||
<div className={'buttonContainer'}>
|
||||
<div
|
||||
className={!subjectsShowing ? 'activeButton' : ''}
|
||||
onClick={() => setSubjectsShowing(false)}
|
||||
>
|
||||
Kérdések
|
||||
</div>
|
||||
<div
|
||||
className={subjectsShowing ? 'activeButton' : ''}
|
||||
onClick={() => setSubjectsShowing(true)}
|
||||
>
|
||||
Tárgyak
|
||||
</div>
|
||||
<a
|
||||
onClick={() => {
|
||||
if (selectedDb === 'all') {
|
||||
window.open(`${constants.apiUrl}allqr.txt`, '_blank')
|
||||
} else {
|
||||
window.open(
|
||||
`${constants.apiUrl}allqr.txt?db=${dbs[selectedDb].name}`,
|
||||
'_blank'
|
||||
)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{'Kérdések letöltése'}
|
||||
<ExternalLinkIcon size={15} />
|
||||
</a>
|
||||
</div>
|
||||
{fetchingData ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<div>
|
||||
{subjectsShowing
|
||||
? renderSubjectBrowser()
|
||||
: renderQuestionBrowser()}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : fetchingData ? (
|
||||
<div>
|
||||
Kérdések betöltése, nagy adatbázisoknál ez sokáig tarthat ...
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue