Added question adder

This commit is contained in:
mrfry 2021-01-11 14:49:58 +01:00
parent 07b34762c3
commit 2d6211a80a
4 changed files with 456 additions and 6 deletions

View file

@ -0,0 +1,323 @@
import React, { useState, useEffect } from 'react'
import Head from 'next/head'
import LoadingIndicator from '../components/LoadingIndicator'
import styles from './questionAdder.module.css'
import constants from '../constants.json'
const getDefaultQuestion = () => {
return {
Q: '',
A: '',
data: { type: 'simple' },
}
}
export default function QuestionAdder() {
const [form, setForm] = useState({ quiz: [getDefaultQuestion()] })
const [subjects, setSubjects] = useState(undefined)
const [isSubmitting, setIsSubmitting] = useState(false)
const [isNewSubj, setIsNewSubj] = useState(false)
useEffect(() => {
console.info('Fetching subject names')
fetch(`${constants.apiUrl}dataCount?detailed=true`, {
credentials: 'include',
})
.then((resp) => {
return resp.json()
})
.then((data) => {
let res = data.reduce((acc, x) => {
return [
...acc,
...x.subjs.map((subj) => {
return subj.name
}),
]
}, [])
res = res.sort()
setSubjects(res)
})
}, [])
const onChange = (newData, index) => {
let quiz = form.quiz
quiz[index] = newData
setForm({
...form,
quiz: quiz,
})
}
const renderQuestionInput = (params) => {
const { index, onChange } = params
const currData = form.quiz[index]
const { Q, A, data } = form.quiz[index] || {}
return (
<div className={styles.questionContainer}>
<div className={styles.inputContainer}>
<input
placeholder="Kérdés..."
type="text"
onChange={(err) =>
onChange({ ...currData, Q: err.target.value }, index)
}
value={Q || ''}
className={styles.questionInput}
/>
</div>
<div className={styles.inputContainer}>
<input
placeholder="Válasz..."
type="text"
onChange={(err) =>
onChange({ ...currData, A: err.target.value }, index)
}
value={A || ''}
className={styles.questionInput}
/>
</div>
<div className={styles.inputContainer}>
<input
type="text"
onChange={() => {
// TODO: handle JSON
// try {
// let newData = JSON.parse(e.target.value)
// onChange({ ...currData, data: newData }, index)
// } catch (e) {
// }
}}
value={JSON.stringify(data) || ''}
className={styles.questionInput}
/>
<span
className={styles.deleteButton}
onClick={() => deleteQuestion(index)}
>
Kérdés törlése
</span>
</div>
<hr />
</div>
)
}
const deleteQuestion = (index) => {
let quiz = form.quiz
quiz.splice(index, 1)
setForm({
...form,
quiz: quiz,
})
}
const handleSubmit = async () => {
if (!form.subj) {
alert('Nem választottál ki tantárgyat!') // eslint-disable-line
return
}
let isValid = form.quiz.every((x) => {
return x.Q && x.A
})
if (!isValid || form.quiz.length === 0) {
alert('Kérdés kitöltése kötelező!') // eslint-disable-line
return
}
const t = document.getElementById('cid').value
let cid = ''
let version = ''
if (t) {
cid = t.split('|')[0]
version = t.split('|')[1]
}
setIsSubmitting(true)
const rawResponse = await fetch(constants.apiUrl + 'isAdding', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
...form,
id: cid,
version: 'WEBSITE',
scriptVersion: version,
}),
})
rawResponse
.json()
.then((resp) => {
console.log(resp)
if (resp.success) {
alert(
'Sikeres beküldés, ' +
resp.newQuestions.reduce((acc, res) => {
return acc + res.newQuestions
}, 0) +
' új kérdés'
) // eslint-disable-line
setIsSubmitting(false)
} else {
alert('Hiba beküldés közben :/') // eslint-disable-line
setIsSubmitting(false)
}
})
.catch((err) => {
alert('Hiba beküldés közben :/') // eslint-disable-line
console.log(err)
setIsSubmitting(false)
})
}
const renderStuff = () => {
return (
<div>
{form.quiz.map((q, i) => {
return (
<div key={i}>
{renderQuestionInput({
index: i,
onChange,
})}
</div>
)
})}
<div className={styles.newQuestionButton}>
<div
onClick={() => {
let quiz = form.quiz
quiz.push(getDefaultQuestion())
setForm({
...form,
quiz: quiz,
})
}}
>
Új kérdés
</div>
</div>
{isSubmitting ? (
<div className={styles.issubmitting}>
Kérdések feldolgozása folyamatban, ha sokat küldtél, akkor több perc
is lehet
</div>
) : (
<div className={styles.buttonContainer}>
<button className={styles.button} onClick={handleSubmit}>
Kérdések beküldése
</button>
</div>
)}
<input type="text" id="cid" name="cid" hidden />
</div>
)
}
const renderSubjSelector = () => {
// TODO: handle if new subject
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
className={styles.subjSelector}
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>
)}
<span
className={styles.newSubj}
onClick={() => {
setIsNewSubj(!isNewSubj)
}}
>
{isNewSubj ? 'Létező tárgy ...' : 'Új tárgy ...'}
</span>
</div>
)
}
const renderUsage = () => {
return (
<ul className={styles.usage}>
<li>Ezen az oldalon kérdéseket tudsz beküldeni manuálisan.</li>
<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 (
<div>
<Head>
<title>Qmining - Kérdés beküldés | Frylabs.net</title>
</Head>
{subjects ? (
<>
{renderUsage()}
<hr />
{renderSubjSelector()}
{renderStuff()}
</>
) : (
<LoadingIndicator />
)}
</div>
)
}

View file

@ -0,0 +1,116 @@
.questionInput {
flex-grow: 1;
font-size: 16px;
background-color: var(--background-color);
color: white;
border: none;
padding: 8px;
margin: 4px;
border: 1px solid;
border-color: var(--background-color);
}
.questionContainer {
margin-top: 30px;
margin-bottom: 30px;
margin-right: 10px;
margin-left: 10px;
}
.inputContainer {
width: 100%;
display: flex;
}
.buttonContainer {
text-align: center;
width: 200px;
margin: 0 auto;
padding: 10px;
}
.deleteButton {
display: flex;
align-items: center;
background-color: #333;
padding: 6px;
font-size: 16px;
color: white;
cursor: pointer;
border: 1px solid;
border-color: var(--background-color);
}
.deleteButton:hover {
background-color: #666;
}
.questionInput:hover {
border: 1px solid;
}
.button {
cursor: pointer;
background-color: var(--text-color);
border: none;
padding: 10px 30px;
color: white;
width: 200px;
}
.subjSelectorContainer {
width: 100%;
display: flex;
}
.subjSelector {
flex-grow: 1;
background-color: var(--background-color);
}
.newSubj {
display: flex;
justify-content: center;
background-color: #333;
width: 150px;
margin: 0px 4px;
padding: 10px;
cursor: pointer;
font-size: 14px;
color: white;
}
.newSubj:hover {
background-color: #666;
}
.usage li {
margin: 5px;
}
.usage {
font-size: 15px;
color: white;
}
.issubmitting {
text-align: center;
color: white;
}
.newQuestionButton {
display: flex;
justify-content: center;
}
.newQuestionButton div {
background-color: #333;
color: white;
cursor: pointer;
padding: 10px 20px;
}
.newQuestionButton div:hover {
background-color: #666;
}

View file

@ -4,11 +4,9 @@
color: white; color: white;
background-color: #222426; background-color: #222426;
border: none; border: none;
font-size: 18px;
flex-grow: 1; flex-grow: 1;
} }
.searchContainer { .searchContainer {
width: 100%; width: 100%;
display: flex; display: flex;
@ -18,7 +16,6 @@
width: 80px; width: 80px;
background-color: var(--background-color); background-color: var(--background-color);
color: white; color: white;
font-size: 23px;
cursor: pointer; cursor: pointer;
border: none; border: none;
} }

View file

@ -3,6 +3,7 @@ import fetch from 'unfetch'
import SubjectView from '../components/subjectView' import SubjectView from '../components/subjectView'
import QuestionView from '../components/questionView' import QuestionView from '../components/questionView'
import QuestionAdder from '../components/questionAdder.js'
import LoadingIndicator from '../components/LoadingIndicator' import LoadingIndicator from '../components/LoadingIndicator'
import styles from './index.module.css' import styles from './index.module.css'
@ -12,6 +13,7 @@ const views = {
subject: 'SUBJECT', subject: 'SUBJECT',
question: 'QUESTION', question: 'QUESTION',
welcome: 'WELCOME', welcome: 'WELCOME',
questionAdder: 'QADDER',
} }
// TODO: Add question on subjects view // TODO: Add question on subjects view
@ -195,6 +197,8 @@ export default function Index() {
deleteQuestion={deleteQuestion} deleteQuestion={deleteQuestion}
/> />
) )
} else if (view === views.questionAdder) {
return <QuestionAdder />
} else if (view === views.welcome) { } else if (view === views.welcome) {
return ( return (
<div className={styles.welcome}> <div className={styles.welcome}>
@ -262,7 +266,7 @@ export default function Index() {
</span> </span>
<span> <span>
<input <input
placeholder="Jelszó feltöltéshez" placeholder="Jelszó kérdések módosításhoz"
type="text" type="text"
value={password} value={password}
onChange={(event) => { onChange={(event) => {
@ -272,10 +276,10 @@ export default function Index() {
</span> </span>
<span <span
onClick={() => { onClick={() => {
if (password) { if (password && selectedDb) {
SendDataToServer() SendDataToServer()
} else { } else {
alert('Hibás jelszó!') // eslint-disable-line alert('Nincs jelszó, vagy nem választottál ki adatbázist!') // eslint-disable-line
} }
}} }}
> >
@ -295,6 +299,9 @@ export default function Index() {
Kérdés nézet Kérdés nézet
</span> </span>
<span <span
title={
'Választott adatbázisban lévő tárgyak megjelenítése, és tárgyakon belüli kérdések szerkesztése'
}
onClick={() => { onClick={() => {
if (selectedDb) { if (selectedDb) {
setView(views.subject) setView(views.subject)
@ -305,6 +312,13 @@ export default function Index() {
> >
Tárgy nézet Tárgy nézet
</span> </span>
<span
onClick={() => {
setView(views.questionAdder)
}}
>
Kérdés beküldés
</span>
</div> </div>
{renderView()} {renderView()}
</div> </div>