mirror of
https://gitlab.com/MrFry/qmining-page
synced 2025-04-01 20:23:44 +02:00
New feedback page #7
This commit is contained in:
parent
a78ac0f8f2
commit
978dfcd382
5 changed files with 299 additions and 64 deletions
|
@ -10,32 +10,20 @@ body {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feedbackArea {
|
|
||||||
color: var(--text-color);
|
|
||||||
background-color: var(--background-color);
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebarLink {
|
.sidebarLink {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.motdHeader {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.motd {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -1,67 +1,251 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import fetch from 'unfetch'
|
||||||
|
|
||||||
import IrcButton from '../components/IrcButton.js'
|
import IrcButton from '../components/IrcButton.js'
|
||||||
|
|
||||||
import constants from '../constants.json'
|
import styles from './feedback.module.css'
|
||||||
|
// import constants from '../constants.json'
|
||||||
|
|
||||||
|
const results = {
|
||||||
|
success: 'SUCCESS',
|
||||||
|
error: 'ERROR',
|
||||||
|
notSent: 'NOTSENT',
|
||||||
|
invalid: 'INVALID'
|
||||||
|
}
|
||||||
|
|
||||||
export default function Feedback (props) {
|
export default function Feedback (props) {
|
||||||
// TODO: textarea style to css
|
const [form, setForm] = useState({})
|
||||||
// TODO: response to user that msg is sucessfully sent
|
const [file, setFile] = useState(undefined)
|
||||||
const renderTestSender = () => {
|
const [result, setResult] = useState(results.notSent)
|
||||||
|
const [fileResult, setFileResult] = useState(results.notSent)
|
||||||
|
|
||||||
|
const onChange = (e) => {
|
||||||
|
setForm({
|
||||||
|
...form,
|
||||||
|
[e.target.name]: e.target.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderTextInputArea = (params) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={styles.inputArea}>
|
||||||
Hibát kiváltó teszt feltöltése
|
<div className={styles.textTitle}>
|
||||||
<br />
|
{params.text}
|
||||||
|
</div>
|
||||||
<form action={constants.apiUrl + 'badtestsender'} encType='multipart/form-data' method='post'>
|
<textarea
|
||||||
<input type='file' name='dasfile' />
|
onChange={e => params.onChange(e)}
|
||||||
<input type='submit' value='Upload' />
|
value={form[params.name] || ''}
|
||||||
</form>
|
className={styles.feedback}
|
||||||
|
name={params.name}
|
||||||
<p />
|
/>
|
||||||
Ha egy kérdésre mindig helytelenül talál választ a userscript (vagy egyéb hibát észlelsz), akkor
|
|
||||||
azon az oldalon nyomj egy ctrl-s -t. Ez lementi a weboldalt úgy ahogy van egy mappába, és egy
|
|
||||||
html fájlba. Ezt a kettőt ha berakod egy .zip-be, és ide feltöltöd, akkor ránézek mi lehet a
|
|
||||||
hiba, és kijavítom. <b> Max 10 MB! </b> Ha több, elég a .html. Bónusz ha mellékelsz egy
|
|
||||||
readme-t, hogy mit csináljak.
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderFeedback = () => {
|
const onFileChangeHandler = (e) => {
|
||||||
|
setFile(e.target.files[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderFileUploader = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={styles.inputArea}>
|
||||||
<form action={constants.apiUrl + 'postfeedback'} method='post'>
|
<div className={styles.textTitle}>
|
||||||
<div>Észrevételek: (közeledő teszt miatti kérdés-karbantartás, bug, feature vagy egyéb dolog, ami nyomja a lelked)</div>
|
Fájl csatolása
|
||||||
<textarea
|
</div>
|
||||||
className='feedbackArea'
|
<input
|
||||||
type='text'
|
className={styles.fileInput}
|
||||||
name='message_field'
|
type='file'
|
||||||
style={{
|
name='file'
|
||||||
width: '100%',
|
onChange={onFileChangeHandler}
|
||||||
boxSizing: 'border-box',
|
/>
|
||||||
height: '400px'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div>Főoldalon kint lesz a válasz. Ha bug-ot találtál, akkor annak kijavítását nagyban
|
|
||||||
megkönnyíti ha azt a kérdés oldalt ahol a hibát találtad és a teszt eredmény oldalt feltöltöd
|
|
||||||
a lenti fájl feltöltővel! </div>
|
|
||||||
<button>Küldés</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!form.description) {
|
||||||
|
setResult(results.invalid)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawResponse = await fetch('http://localhost:8080/postfeedback', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(form)
|
||||||
|
})
|
||||||
|
rawResponse.json()
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.success) {
|
||||||
|
setResult(results.success)
|
||||||
|
} else {
|
||||||
|
console.log(resp)
|
||||||
|
setResult(results.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
setResult(results.error)
|
||||||
|
console.log(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
const formData = new FormData() // eslint-disable-line
|
||||||
|
formData.append('file', file)
|
||||||
|
|
||||||
|
const rawFileResponse = await fetch('http://localhost:8080/postfeedbackfile', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
rawFileResponse.json()
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.success) {
|
||||||
|
setFileResult(results.success)
|
||||||
|
} else {
|
||||||
|
console.log(resp)
|
||||||
|
setFileResult(results.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
setFileResult(results.error)
|
||||||
|
console.log('FILE', e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderResult = () => {
|
||||||
|
if (results === result.success) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
sucess
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (results === result.error) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
error
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (results === result.invalid) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
invalid
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// action={constants.apiUrl + 'badtestsender'} encType='multipart/form-data' method='post'
|
||||||
|
const renderForm = (props) => {
|
||||||
|
return (
|
||||||
|
<div className={styles.feedback} >
|
||||||
|
{props.noDesc
|
||||||
|
? <div className={styles.errorMsg}>
|
||||||
|
Mező kitöltése kötelező!
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
{renderTextInputArea({
|
||||||
|
text: 'Rövid leírás',
|
||||||
|
name: 'description',
|
||||||
|
onChange: onChange
|
||||||
|
})}
|
||||||
|
{renderTextInputArea({
|
||||||
|
text: 'Lépések amikkel előáll a hiba',
|
||||||
|
name: 'steps',
|
||||||
|
onChange: onChange
|
||||||
|
})}
|
||||||
|
{renderTextInputArea({
|
||||||
|
text: 'Elvárt működés',
|
||||||
|
name: 'expected',
|
||||||
|
onChange: onChange
|
||||||
|
})}
|
||||||
|
{renderTextInputArea({
|
||||||
|
text: 'Ami történik helyette',
|
||||||
|
name: 'current',
|
||||||
|
onChange: onChange
|
||||||
|
})}
|
||||||
|
{renderFileUploader()}
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
id='cid'
|
||||||
|
name='cid'
|
||||||
|
value={form.cid}
|
||||||
|
onChange={onChange}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className={styles.button}
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
Küldés
|
||||||
|
</button>
|
||||||
|
{renderResult()}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('result', result, 'fileResult', fileResult)
|
||||||
|
const renderStuff = () => {
|
||||||
|
if (result === results.notSent && fileResult === results.notSent) {
|
||||||
|
console.log('both not sent')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
{renderForm({})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (result === results.invalid) {
|
||||||
|
console.log('result is invalid')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
{renderForm({ noDesc: true })}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (result === results.success && !file) {
|
||||||
|
console.log('text sucess, no file')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
Visszajelzés elküldve c:
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (result === results.error && fileResult === results.success) {
|
||||||
|
console.log('file sucess only')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
Hiba küldés közben :c
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (result === results.success && fileResult === results.error) {
|
||||||
|
console.log('text sucess only')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
Visszajelzés elküldve, de fájlt nem sikerült elküldeni :c
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (result === results.success && fileResult === results.success) {
|
||||||
|
console.log('both sucess')
|
||||||
|
return (
|
||||||
|
<div className={styles.textTitle}>
|
||||||
|
Visszajelzés elküldve c:
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
console.log('else')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<IrcButton />
|
<IrcButton />
|
||||||
<p />
|
<p />
|
||||||
<hr />
|
<hr />
|
||||||
<p />
|
<p />
|
||||||
{renderFeedback()}
|
{renderStuff()}
|
||||||
<p />
|
|
||||||
<hr />
|
|
||||||
<p />
|
|
||||||
{renderTestSender()}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
33
src/pages/feedback.module.css
Normal file
33
src/pages/feedback.module.css
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
.feedback {
|
||||||
|
color: var(--text-color);
|
||||||
|
background-color: var(--background-color);
|
||||||
|
font-size: 18px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textTitle {
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background-color: var(--text-color);
|
||||||
|
border: none;
|
||||||
|
padding: 10px 30px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.textInputArea {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fileInput {
|
||||||
|
margin: 10px;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorMsg {
|
||||||
|
color: red;
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import fetch from 'unfetch'
|
||||||
|
|
||||||
import LoadingIndicator from '../components/LoadingIndicator'
|
import LoadingIndicator from '../components/LoadingIndicator'
|
||||||
|
|
||||||
|
import styles from './index.module.css'
|
||||||
import links from '../data/links.json'
|
import links from '../data/links.json'
|
||||||
import constants from '../constants.json'
|
import constants from '../constants.json'
|
||||||
|
|
||||||
|
@ -46,7 +47,13 @@ export default function Index (props) {
|
||||||
{key}:
|
{key}:
|
||||||
</div>
|
</div>
|
||||||
<div className='uquestion'>
|
<div className='uquestion'>
|
||||||
{q.q}
|
{q.q.split('\n').map((x, i) => {
|
||||||
|
return (
|
||||||
|
<div key={i}>
|
||||||
|
{x}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='uanswer'>
|
<div className='uanswer'>
|
||||||
|
@ -71,11 +78,11 @@ export default function Index (props) {
|
||||||
const renderMotd = () => {
|
const renderMotd = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='motdHeader'>
|
<div className={styles.motdHeader}>
|
||||||
MOTD:
|
MOTD:
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className='motd'
|
className={styles.motd}
|
||||||
dangerouslySetInnerHTML={{ __html: motd }}
|
dangerouslySetInnerHTML={{ __html: motd }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,7 +104,9 @@ export default function Index (props) {
|
||||||
<a
|
<a
|
||||||
href={link.href}
|
href={link.href}
|
||||||
>
|
>
|
||||||
{link.text}
|
<div className={styles.button}>
|
||||||
|
{link.text}
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
|
21
src/pages/index.module.css
Normal file
21
src/pages/index.module.css
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
.button {
|
||||||
|
background-color: #9999ff;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 15px 32px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motdHeader {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.motd {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue