Subject and question browser merge, handling multiple dbs

This commit is contained in:
mrfry 2020-12-26 14:50:39 +01:00
parent 57f0730f3e
commit fb3bf29fc4
11 changed files with 232 additions and 178 deletions

View file

@ -1,7 +1,6 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import Questions from './Questions.js' import Questions from './Questions.js'
import Sleep from '../components/sleep'
import constants from '../constants.json' import constants from '../constants.json'
@ -62,7 +61,6 @@ class QuestionSearchResult extends PureComponent {
} }
</div> </div>
)} )}
<Sleep />
</div> </div>
) )
} }

View file

@ -10,6 +10,7 @@ import BB from './b.js'
export default function Layout(props) { export default function Layout(props) {
let href = props.route let href = props.route
const [sidebarOpen, setSidebarOpen] = useState(true) const [sidebarOpen, setSidebarOpen] = useState(true)
const [userId, setUserId] = useState(null)
if (href === '/' || href === '') { if (href === '/' || href === '') {
href = 'index' href = 'index'
@ -23,6 +24,22 @@ export default function Layout(props) {
} }
} }
useEffect(() => {
closeSideBar()
fetch(`${constants.apiUrl}infos`, {
credentials: 'include',
Accept: 'application/json',
'Content-Type': 'application/json',
})
.then((resp) => {
return resp.json()
})
.then((data) => {
setUserId(data.uid)
})
}, [])
useEffect(() => { useEffect(() => {
closeSideBar() closeSideBar()
}, []) }, [])
@ -66,7 +83,7 @@ export default function Layout(props) {
</a> </a>
</Link> </Link>
</div> </div>
<div className="userInfo">User # TODO</div> <div className="userInfo">User #{userId}</div>
</> </>
) : null} ) : null}
</div> </div>

View file

@ -1,5 +1,5 @@
{ {
"siteUrl": "https://qmining.frylabs.net/", "siteUrl": "http://localhost:8080/",
"apiUrl": "http://localhost:8080/", "apiUrl": "http://localhost:8080/",
"mobileWindowWidth": 700, "mobileWindowWidth": 700,
"maxQuestionsToRender": 250 "maxQuestionsToRender": 250

View file

@ -9,11 +9,7 @@
}, },
"allQuestions": { "allQuestions": {
"href": "/allQuestions", "href": "/allQuestions",
"text": "Kérdés keresés" "text": "Kérdések és tárgyak"
},
"subjectBrowser": {
"href": "/subjectBrowser",
"text": "Tárgyak"
}, },
"addQuestion": { "addQuestion": {
"href": "/addQuestion", "href": "/addQuestion",

View file

@ -226,3 +226,22 @@ a {
.manualUsage { .manualUsage {
display: flex; display: flex;
} }
select {
cursor: pointer;
width: 100%;
max-width: 100%;
appearance: none;
border: 1px solid #99f;
box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04);
line-height: 35px;
border-radius: 3px;
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
linear-gradient(to bottom, #222426 0%, #222426 100%);
background-repeat: no-repeat, repeat;
background-position: right 0.7em top 50%, 0 0;
background-size: 0.65em auto, 100%;
color: white;
}

View file

@ -63,12 +63,10 @@
.subjSelector { .subjSelector {
flex-grow: 1; flex-grow: 1;
background-color: var(--background-color); background-color: var(--background-color);
font-size: 24px;
color: white;
height: 50px;
} }
.newSubj { .newSubj {
width: 150px;
padding: 10px; padding: 10px;
cursor: pointer; cursor: pointer;
font-size: 20px; font-size: 20px;

View file

@ -3,6 +3,9 @@ import Head from 'next/head'
import LoadingIndicator from '../components/LoadingIndicator.js' import LoadingIndicator from '../components/LoadingIndicator.js'
import QuestionSearchResult from '../components/QuestionSearchResult.js' import QuestionSearchResult from '../components/QuestionSearchResult.js'
import Subject from '../components/Subject.js'
import SubjectSelector from '../components/SubjectSelector.js'
import Sleep from '../components/sleep'
import styles from './allQuestions.module.css' import styles from './allQuestions.module.css'
@ -28,17 +31,25 @@ function fetchData(db) {
credentials: 'include', credentials: 'include',
}) })
.then((resp) => { .then((resp) => {
resp.json() return resp.json()
}) })
.then((data) => { .then((resp) => {
resolve({ resolve({
dbName: db.name, dbName: db.name,
data: data, data: resp,
}) })
}) })
}) })
} }
function fetchAllData(dbs) {
const promises = dbs.map((db) => {
return fetchData(db)
})
return Promise.all(promises)
}
function fetchDbs() { function fetchDbs() {
return new Promise((resolve) => { return new Promise((resolve) => {
console.info('Fetching data') console.info('Fetching data')
@ -49,53 +60,63 @@ function fetchDbs() {
return resp.json() return resp.json()
}) })
.then((data) => { .then((data) => {
console.log(data)
resolve(data) resolve(data)
}) })
}) })
} }
export default function AllQuestions({ router }) { export default function AllQuestions({ router }) {
const [asd, setAsd] = useState(false)
const [data, setData] = useState(null) const [data, setData] = useState(null)
const [dbs, setDbs] = useState(null) const [dbs, setDbs] = useState(null)
const [searchTerm, setSearchTerm] = useState('') const [searchTerm, setSearchTerm] = useState('')
const [activeSubjName, setActiveSubjName] = useState('')
useEffect(() => { useEffect(() => {
router.replace(`${router.asPath.replace('.html', '')}`, undefined, { router.replace(`${router.asPath.replace('.html', '')}`, undefined, {
shallow: true, shallow: true,
}) })
// TODO: fix dis
const querySearch = router.query.question const querySearch = router.query.question
? decodeURIComponent(router.query.question) ? decodeURIComponent(router.query.question)
: '' : ''
console.log(querySearch)
fetchDbs().then((res) => { fetchDbs().then((res) => {
setDbs(res) setDbs(res)
console.log(res)
}) })
// fetchData().then((result) => {
// setData(result)
// setSearchTerm(querySearch)
// })
}, []) }, [])
const renderDbSelector = () => {
if (dbs) {
return ( return (
<div>
<Head>
<title>Qmining - Kérdés keresés | Frylabs.net</title>
</Head>
{dbs ? (
<> <>
<select <select
onChange={(e) => { className={styles.select}
console.log(e.target.value) defaultValue={-1}
onChange={(event) => {
const key = event.target.value
if (key === 'none') {
console.log(key)
} else if (key === 'all') {
fetchAllData(dbs).then((res) => {
setData(mergeData(res))
console.log(res)
})
} else {
fetchData(dbs[key]).then((res) => {
setData(res.data)
})
}
}} }}
> >
<option value={'none'} key={'none'}> <option disabled value={-1}>
{'...'} {' -- Válassz egy kérdés adatbázist -- '}
</option> </option>
{dbs.map((db) => { {dbs.map((db, i) => {
return ( return (
<option value={db.path} key={db.path}> <option value={i} key={db.path}>
{db.name} {db.name}
</option> </option>
) )
@ -105,7 +126,75 @@ export default function AllQuestions({ router }) {
</option> </option>
</select> </select>
</> </>
) : null} )
} else {
return null
}
}
const renderSubjectBrowser = () => {
let currSubj = data
? data.find((subj) => {
return subj.Name === activeSubjName
})
: {}
return (
<div>
<Head>
<title>Qmining - Tárgyak | Frylabs.net</title>
</Head>
{data ? (
<>
<div className={styles.searchContainer}>
<input
autoFocus
placeholder="Keresés..."
className={styles.searchBar}
type="text"
value={searchTerm}
onChange={(event) => {
setSearchTerm(event.target.value)
}}
/>
<button
onClick={() => {
setSearchTerm('')
}}
className={styles.clearButton}
>
X
</button>
</div>
<hr />
<SubjectSelector
data={data}
activeSubjName={activeSubjName}
searchTerm={searchTerm}
onSubjSelect={(subjName) => {
setActiveSubjName(subjName)
}}
/>
<hr />
<div>{/*{qCount} kérdés, {sCount} tárgy */}</div>
<Sleep />
<div>
<Subject subj={currSubj} />
</div>
</>
) : (
<LoadingIndicator />
)}
</div>
)
}
const renderQuestionBrowser = () => {
return (
<div>
<Head>
<title>Qmining - Kérdés keresés | Frylabs.net</title>
</Head>
{data ? ( {data ? (
<> <>
<div className={styles.searchContainer}> <div className={styles.searchContainer}>
@ -139,6 +228,30 @@ export default function AllQuestions({ router }) {
<QuestionSearchResult data={data} searchTerm={searchTerm} /> <QuestionSearchResult data={data} searchTerm={searchTerm} />
</div> </div>
</> </>
) : null}
</div>
)
}
return (
<div>
{dbs && renderDbSelector()}
<div className={styles.typeSelector}>
<div
className={!asd ? styles.activeTypeSelector : ''}
onClick={() => setAsd(false)}
>
Kérdések
</div>
<div
className={asd ? styles.activeTypeSelector : ''}
onClick={() => setAsd(true)}
>
Tárgyak
</div>
</div>
{dbs ? (
<div>{asd ? renderSubjectBrowser() : renderQuestionBrowser()}</div>
) : ( ) : (
<LoadingIndicator /> <LoadingIndicator />
)} )}

View file

@ -20,3 +20,28 @@
cursor: pointer; cursor: pointer;
border: none; border: none;
} }
.typeSelector {
margin: 10px 0px;
height: 50px;
display: flex;
}
.typeSelector div {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
font-size: 18px;
color: #fff;
cursor: pointer;
}
.typeSelector div:hover {
background-color: #333;
}
.activeTypeSelector {
background-color: #444;
}

View file

@ -97,15 +97,13 @@ export default function RankList() {
setRanklist(null) setRanklist(null)
getListFromServer(since) getListFromServer(since)
.then((data) => { .then((data) => {
console.log(data)
setRanklist(data.list || []) setRanklist(data.list || [])
setSum(data.sum || {}) setSum(data.sum || {})
if (data.selfuserId) { if (data.selfuserId) {
setSelfUserId(data.selfuserId) setSelfUserId(data.selfuserId)
} }
}) })
.catch((error) => { .catch(() => {
console.error(error)
setRanklist(null) setRanklist(null)
}) })
} }

View file

@ -1,87 +0,0 @@
import React, { useState, useEffect } from 'react'
import fetch from 'unfetch'
import Head from 'next/head'
import LoadingIndicator from '../components/LoadingIndicator.js'
import Subject from '../components/Subject.js'
import SubjectSelector from '../components/SubjectSelector.js'
import Sleep from '../components/sleep'
import styles from './subjectBrowser.module.css'
export default function SubjectBrowser({ getData }) {
const [data, setData] = useState(null)
const [activeSubjName, setActiveSubjName] = useState('')
const [searchTerm, setSearchTerm] = useState('')
const [sCount, setSCount] = useState(0)
const [qCount, setQCount] = useState(0)
useEffect(() => {
getData().then((result) => {
setData(result)
setSCount(result.length)
setQCount(
result.reduce((acc, subj) => {
return acc + subj.Questions.length
}, 0)
)
})
}, [])
let currSubj = data
? data.find((subj) => {
return subj.Name === activeSubjName
})
: {}
return (
<div>
<Head>
<title>Qmining - Tárgyak | Frylabs.net</title>
</Head>
{data ? (
<>
<div className={styles.searchContainer}>
<input
autoFocus
placeholder="Keresés..."
className={styles.searchBar}
type="text"
value={searchTerm}
onChange={(e) => {
setSearchTerm(e.target.value)
}}
/>
<button
onClick={() => {
setSearchTerm('')
}}
className={styles.clearButton}
>
X
</button>
</div>
<SubjectSelector
data={data}
activeSubjName={activeSubjName}
searchTerm={searchTerm}
onSubjSelect={(subjName) => {
setActiveSubjName(subjName)
}}
/>
<hr />
<div>
{qCount} kérdés, {sCount} tárgy
</div>
<Sleep />
<div>
<Subject subj={currSubj} />
</div>
</>
) : (
<LoadingIndicator />
)}
</div>
)
}

View file

@ -1,23 +0,0 @@
.searchBar {
margin: 10px;
color: white;
background-color: #222426;
border: none;
font-size: 18px;
flex-grow: 1;
}
.searchContainer {
width: 100%;
display: flex;
}
.clearButton {
width: 80px;
background-color: var(--background-color);
color: white;
font-size: 23px;
cursor: pointer;
border: none;
}