Merge, and reinstall in manual

This commit is contained in:
mrfry 2020-12-19 16:11:18 +01:00
commit a13fee6f84
15 changed files with 474 additions and 182 deletions

20
src/components/sidebar.js Normal file
View file

@ -0,0 +1,20 @@
import React from 'react'
import styles from './sidebar.module.css'
export default function Sidebar(props) {
const { onClose } = props
return (
<div className={styles.container}>
<div
className={styles.closeBorder}
onClick={() => {
onClose()
}}
>
{'>'}
</div>
<div className={styles.content}>{props.children}</div>
</div>
)
}

View file

@ -0,0 +1,29 @@
.container {
background-color: var(--background-color);
border-left: 3px solid #99f;
top: 0;
right: 0px;
height: 100%;
width: 400px;
max-width: 100%;
position: fixed;
display: flex;
}
.closeBorder {
padding: 5px;
cursor: pointer;
display: flex;
flex-flow: column;
justify-content: center;
color: white;
}
.closeBorder:hover {
background-color: #333;
}
.content {
width: 100%;
}

View file

@ -3,19 +3,15 @@ import React from 'react'
import styles from './todoCard.module.css' import styles from './todoCard.module.css'
export default function TodoCard(props) { export default function TodoCard(props) {
const { categories, onClick, userId, clickable } = props const { categories, onClick, userId } = props
const { name, description, category, points, votes, id } = props.cardData const { name, category, points, votes, id } = props.cardData
const voted = votes.includes(userId) const voted = votes.includes(userId)
return ( return (
<div <div
className={`${styles.card} ${clickable && styles.clickable} ${voted && className={`${styles.card} ${voted && styles.voted}`}
styles.voted}`}
title={description}
onClick={() => { onClick={() => {
if (clickable) { onClick(props.cardData)
onClick(id)
}
}} }}
> >
<div className={styles.description}> <div className={styles.description}>

View file

@ -3,17 +3,14 @@
border-radius: 2px; border-radius: 2px;
padding: 5px; padding: 5px;
margin: 6px 3px; margin: 6px 3px;
cursor: pointer;
} }
.voted { .voted {
border: 2px solid #cf9; border: 2px solid #cf9;
} }
.clickable { .card:hover {
cursor: pointer;
}
.clickable:hover {
background-color: #333; background-color: #333;
border: 2px solid #f99; border: 2px solid #f99;
} }

View file

@ -3,14 +3,16 @@ import React from 'react'
import styles from './todoRow.module.css' import styles from './todoRow.module.css'
export default function TodoRow(props) { export default function TodoRow(props) {
const { categories, userId } = props const { categories, userId, onClick } = props
const { name, description, category, votes, id } = props.rowData const { name, category, votes, id } = props.rowData
const voted = votes.includes(userId) const voted = votes.includes(userId)
return ( return (
<div <div
onClick={() => {
onClick(props.rowData)
}}
className={`${styles.row} ${voted && styles.voted}`} className={`${styles.row} ${voted && styles.voted}`}
title={description}
> >
<div className={styles.id}>{`#${id}`}</div> <div className={styles.id}>{`#${id}`}</div>
<div className={styles.description}>{name}</div> <div className={styles.description}>{name}</div>

View file

@ -4,6 +4,12 @@
border-radius: 2px; border-radius: 2px;
padding: 5px; padding: 5px;
margin: 6px 3px; margin: 6px 3px;
cursor: pointer;
}
.row:hover {
background-color: #333;
border: 2px solid #f99;
} }
.row > div { .row > div {

View file

@ -0,0 +1,63 @@
import React from 'react'
import styles from './todoSidebar.module.css'
export default function Todos({ card, userId, categories, columns, voteOn }) {
const { name, description, category, points, votes, id } = card
const voteable = columns[card.state].clickable
// TODO: hide vote button if not voteable
return (
<div className={styles.container}>
<div className={styles.name}>
<span className={styles.id}>#{id}</span>
{name}
<span
style={{
margin: '0px 5px',
fontSize: '10px',
backgroundColor: categories[category].color,
color: 'white',
borderRadius: '2px',
padding: '0px 2px',
}}
>
{categories[category].name}
</span>
</div>
<hr />
<div className={styles.row} title={'Minél több a pont, annál nehezebb'}>
<div>Nehézség:</div>
<div>{points}</div>
</div>
<div
className={`${styles.row} ${votes.includes(userId) &&
styles.votedtext}`}
title={'Hány felhasználó szavazott a feladatra'}
>
<div>Szavazatok:</div>
<div>{votes.length}</div>
</div>
<hr />
{description && (
<>
<div className={styles.title}>Leírás</div>
<div dangerouslySetInnerHTML={{ __html: description }} />
<hr />
</>
)}
<div className={styles.category}></div>
{voteable && (
<div
className={`${styles.button} ${votes.includes(userId) &&
styles.voted}`}
onClick={() => {
voteOn(card)
}}
>
{votes.includes(userId) ? 'Szavazat visszavonása' : 'Szavazás'}
</div>
)}
</div>
)
}

View file

@ -0,0 +1,54 @@
.container {
display: flex;
flex-flow: column;
margin: 5px;
}
.container > hr {
width: 100%;
}
.title {
color: #99f;
font-size: 18px;
}
.name {
color: #99f;
font-size: 20px;
margin: 20px 0px;
}
.category {
word-break: break-all;
font-size: 10px;
}
.id {
font-size: 16px;
margin: 0px 3px;
color: #999;
}
.row {
display: flex;
justify-content: space-between;
}
.button {
border: 2px solid #99f;
border-radius: 3px;
text-align: center;
cursor: pointer;
}
.button:hover {
background-color: #333;
}
.votedtext {
color: #cf9;
}
.voted {
border: 2px solid #cf9;
}

View file

@ -5,7 +5,7 @@ import TodoRow from './todoRow.js'
import styles from './todoTable.module.css' import styles from './todoTable.module.css'
export default function TodoBoard(props) { export default function TodoBoard(props) {
const { tables, cards, userId, categories } = props const { tables, cards, userId, categories, onClick } = props
return ( return (
<div className={styles.tableContainer}> <div className={styles.tableContainer}>
@ -23,6 +23,7 @@ export default function TodoBoard(props) {
{tableCards.map((card, i) => { {tableCards.map((card, i) => {
return ( return (
<TodoRow <TodoRow
onClick={onClick}
key={i} key={i}
type={key} type={key}
rowData={card} rowData={card}

View file

@ -1,8 +1,11 @@
.tableContainer { .tableContainer {
overflow-y: hidden;
overflow-x: auto;
margin: 5px 0px; margin: 5px 0px;
} }
.table { .table {
min-width: 500px;
justify-content: center; justify-content: center;
} }

View file

@ -3,7 +3,11 @@ import React, { useState, useEffect } from 'react'
import LoadingIndicator from '../LoadingIndicator.js' import LoadingIndicator from '../LoadingIndicator.js'
import TodoBoard from './todoBoard.js' import TodoBoard from './todoBoard.js'
import TodoTable from './todoTable.js' import TodoTable from './todoTable.js'
import TodoSidebar from './todoSidebar.js'
import Sidebar from '../sidebar.js'
// import styles from './todos.module.css'
import constants from '../../constants.json' import constants from '../../constants.json'
const byVotes = (a, b) => { const byVotes = (a, b) => {
@ -13,11 +17,10 @@ const byVotes = (a, b) => {
export default function Todos() { export default function Todos() {
const [loaded, setLoaded] = useState(false) const [loaded, setLoaded] = useState(false)
const [columns, setColumns] = useState(null) const [columns, setColumns] = useState(null)
const [boardCards, setBoardCards] = useState(null) const [cards, setCards] = useState(null)
const [tables, setTables] = useState(null)
const [tableCards, setTableCards] = useState(null)
const [categories, setCategories] = useState(null) const [categories, setCategories] = useState(null)
const [userId, setUserId] = useState(null) const [userId, setUserId] = useState(null)
const [sidebarCard, setSidebarCard] = useState(null)
useEffect(() => { useEffect(() => {
console.info('Fetching todos') console.info('Fetching todos')
@ -36,23 +39,35 @@ export default function Todos() {
setCategories(data.todos.categories) setCategories(data.todos.categories)
setUserId(data.userId) setUserId(data.userId)
setCards(data.todos.cards)
setColumns(data.todos.columns)
setLoaded(true)
}
const onClick = (card) => {
setSidebarCard(card.id)
}
if (!loaded) {
return <LoadingIndicator />
}
let bCards = [] let bCards = []
let tCards = [] let tCards = []
data.todos.cards.forEach((card) => { cards.forEach((card) => {
if (data.todos.columns[card.state].type === 'table') { if (columns[card.state].type === 'table') {
tCards.push(card) tCards.push(card)
} else { } else {
bCards.push(card) bCards.push(card)
} }
}) })
bCards = bCards.sort(byVotes)
setTableCards(tCards.sort(byVotes)) tCards = tCards.sort(byVotes)
setBoardCards(bCards.sort(byVotes))
let cols = {} let cols = {}
let tables = {} let tables = {}
Object.keys(data.todos.columns).forEach((key) => { Object.keys(columns).forEach((key) => {
const col = data.todos.columns[key] const col = columns[key]
if (col.type !== 'table') { if (col.type !== 'table') {
cols = { cols = {
...cols, ...cols,
@ -65,14 +80,24 @@ export default function Todos() {
} }
} }
}) })
setColumns(cols)
setTables(tables)
setLoaded(true) return (
} <div>
{sidebarCard && (
const onCardClick = (id) => { <Sidebar
fetch(`${constants.apiUrl}voteTodo?id=${id}`, { onClose={() => {
setSidebarCard(null)
}}
>
<TodoSidebar
card={cards.find((card) => {
return card.id === sidebarCard
})}
userId={userId}
categories={categories}
columns={columns}
voteOn={(card) => {
fetch(`${constants.apiUrl}todos?id=${card.id}`, {
credentials: 'include', credentials: 'include',
}) })
.then((resp) => { .then((resp) => {
@ -81,27 +106,31 @@ export default function Todos() {
.then((data) => { .then((data) => {
setTodos(data) setTodos(data)
}) })
} }}
/>
if (!loaded) { </Sidebar>
return <LoadingIndicator /> )}
} <div
style={{
return ( // width: '100%',
<div> marginRight: sidebarCard ? 380 : 0,
}}
>
<TodoBoard <TodoBoard
columns={columns} columns={cols}
cards={boardCards} cards={bCards}
userId={userId} userId={userId}
categories={categories} categories={categories}
onCardClick={onCardClick} onCardClick={onClick}
/> />
<TodoTable <TodoTable
tables={tables} tables={tables}
cards={tableCards} cards={tCards}
userId={userId} userId={userId}
categories={categories} categories={categories}
onClick={onClick}
/> />
</div> </div>
</div>
) )
} }

View file

@ -25,6 +25,9 @@ a {
} }
.sidebar { .sidebar {
display: flex;
flex-direction: column;
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 200px; width: 200px;
@ -52,6 +55,11 @@ a {
color: white; color: white;
} }
.userInfo {
margin-bottom: 15px;
margin-top: auto;
}
.content { .content {
margin-left: 200px; margin-left: 200px;
padding: 1px 16px; padding: 1px 16px;
@ -130,6 +138,17 @@ a {
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
} }
.rtfmImage {
display: flex;
justify-content: center;
width: 100%;
}
.manualUsage {
display: flex;
flex-direction: column;
}
} }
.questionContainer { .questionContainer {
@ -198,3 +217,12 @@ a {
.donate { .donate {
background-color: #222a26; background-color: #222a26;
} }
.rtfmImage {
justify-content: center;
margin: 0px 10px;
}
.manualUsage {
display: flex;
}

View file

@ -66,10 +66,11 @@ export default function contribute() {
<title>Qmining - Todos | Frylabs.net</title> <title>Qmining - Todos | Frylabs.net</title>
</Head> </Head>
<div className={styles.description}> <div className={styles.description}>
Egy kártyára kattintva szavazhatsz. Minél több szavazat érkezik egy Egy kártyára kattintva nézheted meg a részleteket, vagy szavazhatsz.
kártyára, annál magasabb lesz a pioritása. Jobb alsó szám minél több, Minél több szavazat érkezik egy kártyára, annál magasabb lesz a
annál nehezebb a feladat. Tartsd egeret kártyán részletesebb leírásért pioritása. Jobb alsó szám minél több, annál nehezebb a feladat. A Done
(ha van hozzá) oszlopban lévő feladatok kész vannak, de különböző okok miat még nem
lettek kiadva frissítésként. Ami az In Prod táblázatban van az van kint.
</div> </div>
<Todos /> <Todos />
<div className={styles.description}> <div className={styles.description}>

View file

@ -3,7 +3,7 @@ import React from 'react'
import Sleep from '../components/sleep' import Sleep from '../components/sleep'
import Head from 'next/head' import Head from 'next/head'
export default function Manual(props) { export default function Manual() {
return <div>{renderMaual()}</div> return <div>{renderMaual()}</div>
} }
@ -16,6 +16,8 @@ function renderMaual() {
<center> <center>
<h1>Manual</h1> <h1>Manual</h1>
</center> </center>
<hr />
<hr />
<Sleep /> <Sleep />
<center> <center>
Ez a userscript Moodle/Elearnig/KMOOC tesztek megoldása során segítséget Ez a userscript Moodle/Elearnig/KMOOC tesztek megoldása során segítséget
@ -27,20 +29,23 @@ function renderMaual() {
Valószínűleg semmi baj nem lesz, de én szóltam. Ha ez iránt aggódsz, Valószínűleg semmi baj nem lesz, de én szóltam. Ha ez iránt aggódsz,
olvasd el a kockázatok részt olvasd el a kockázatok részt
</center> </center>
<hr />
<hr />
<center> <center>
<h1>Userscript használata</h1> <h1>Userscript használata</h1>
</center> </center>
<hr /> <hr />
<table <hr />
style={{ tableLayout: 'fixed', verticalAlign: 'top', width: '100%' }} <div className={'manualUsage'}>
> <div>
<tbody>
<tr>
<td>
<ul> <ul>
<li> <li>
Tölts le egy userscript futtató kiegészítőt a böngésződhöz:{' '} Tölts le egy userscript futtató kiegészítőt a böngésződhöz:{' '}
<a href="https://www.tampermonkey.net/" target="_blank"> <a
href="https://www.tampermonkey.net/"
target="_blank"
rel="noreferrer"
>
Tampermonkey Tampermonkey
</a> </a>
</li> </li>
@ -48,6 +53,7 @@ function renderMaual() {
<a <a
href="http://qmining.frylabs.net/install?man" href="http://qmining.frylabs.net/install?man"
target="_blank" target="_blank"
rel="noreferrer"
> >
Weboldalról Weboldalról
</a>{' '} </a>{' '}
@ -66,8 +72,8 @@ function renderMaual() {
</li> </li>
<li> <li>
Teszt ellenőrzés oldalon a script beküldi a szervernek a Teszt ellenőrzés oldalon a script beküldi a szervernek a
helyes válaszokat, az lementi az új kérdéseket, amik helyes válaszokat, az lementi az új kérdéseket, amik ezután
ezután azonnal elérhetők lesznek azonnal elérhetők lesznek
</li> </li>
</ul> </ul>
</li> </li>
@ -79,6 +85,7 @@ function renderMaual() {
<a <a
href="http://qmining.frylabs.net/allqr.txt?man" href="http://qmining.frylabs.net/allqr.txt?man"
target="_blank" target="_blank"
rel="noreferrer"
> >
{' '} {' '}
Összes kérdés TXT Összes kérdés TXT
@ -89,6 +96,7 @@ function renderMaual() {
<a <a
href="https://qmining.frylabs.net/allQuestions.html" href="https://qmining.frylabs.net/allQuestions.html"
target="_blank" target="_blank"
rel="noreferrer"
> >
Összes kérdés oldal Összes kérdés oldal
</a> </a>
@ -98,21 +106,26 @@ function renderMaual() {
<p /> Egyéb funkciók: <p /> Egyéb funkciók:
<ul> <ul>
<li> <li>
Ha esetleg videókat nézel, akkor spaceval lehet play/pausolni, Ha esetleg videókat nézel, akkor spaceval lehet play/pausolni, és
és jobbra/balra gombbal ugrani a videóban. jobbra/balra gombbal ugrani a videóban.
</li> </li>
</ul> </ul>
</td> </div>
<td width="40%" style={{ textAlign: 'center' }}> <div className={'rtfmImage'}>
<img style={{ maxWidth: '100%' }} src="img/rtfm.jpg" alt="img" /> <img
</td> style={{ maxWidth: '100%', minWidth: '200px' }}
</tr> src="img/rtfm.jpg"
</tbody> alt="img"
</table> />
</div>
</div>
<hr />
<hr />
<center> <center>
<h1>Jelszavak</h1> <h1>Jelszavak</h1>
</center> </center>
<hr /> <hr />
<hr />
Ha ezt olvasod valszeg már van neked egy. Azért lett bevezetve, hogy Ha ezt olvasod valszeg már van neked egy. Azért lett bevezetve, hogy
nagyjából zárt legyen a felhasználók köre nagyjából zárt legyen a felhasználók köre
<ul> <ul>
@ -121,19 +134,27 @@ function renderMaual() {
Elvileg elég csak 1 szer beírnod, és nem kell többet, de{' '} Elvileg elég csak 1 szer beírnod, és nem kell többet, de{' '}
<b>mentsd le biztos helyre a jelszót, hogy később is meglegyen!</b> Ha <b>mentsd le biztos helyre a jelszót, hogy később is meglegyen!</b> Ha
többször kell akkor az bug,{' '} többször kell akkor az bug,{' '}
<a href="http://qmining.frylabs.net/feedback?man" target="_blank"> <a
href="http://qmining.frylabs.net/feedback?man"
target="_blank"
rel="noreferrer"
>
és szólj és szólj
</a> </a>
</li> </li>
<li> <li>
<b> <b>
Jelenleg nincs 'elfelejtett jelszó' funkció, ha elfelejted akkor az Jelenleg nincs elfelejtett jelszó funkció, ha elfelejted akkor az
örökre eltűnik! örökre eltűnik!
</b> </b>
</li> </li>
<li> <li>
Ha van jelszavad akkor bizonyos határok között{' '} Ha van jelszavad akkor bizonyos határok között{' '}
<a href="https://qmining.frylabs.net/pwRequest?man" target="_blank"> <a
href="https://qmining.frylabs.net/pwRequest?man"
target="_blank"
rel="noreferrer"
>
te is tudsz generálni másoknak te is tudsz generálni másoknak
</a> </a>
(ncore style). (ncore style).
@ -148,10 +169,13 @@ function renderMaual() {
megmaradjon megmaradjon
</li> </li>
</ul> </ul>
<hr />
<hr />
<center> <center>
<h1>Gyakran előforduló kérdések</h1> <h1>Gyakran előforduló kérdések</h1>
</center> </center>
<hr /> <hr />
<hr />
<ul> <ul>
<li> <li>
<b> <b>
@ -172,42 +196,20 @@ function renderMaual() {
amíg újra nem töltöd az oldalt, vagy másikra ugrasz. amíg újra nem töltöd az oldalt, vagy másikra ugrasz.
</li> </li>
<p /> <p />
<li>
<b>Mi ez a ... ?</b>
<br />
<img style={{ maxWidth: '100%' }} src="img/imgq.jpg" alt="img" />
</li>
<li> <li>
<b>Gombok, %-ok, számok</b> <b>Gombok, %-ok, számok</b>
<br /> <br />
<img style={{ maxWidth: '100%' }} src="img/6.png" alt="img" /> <img style={{ maxWidth: '100%' }} src="img/6.png" alt="img" />
</li> </li>
<li>
<b id="sitesave">Weboldal lementése</b>
<br />
Hogy a hibákat a saját gépemen reprodukálni tudjam, és könnyen ki
bírjam javítani sokszor jól jön ha egy lementett weboldalt megkapok.
Így lehet letölteni egy oldalt:
<img
style={{ maxWidth: '100%' }}
src="img/websitesave.png"
alt="img"
/>
<br />
<a href="http://qmining.frylabs.net/feedback?man" target="_blank">
Ide tudod feltölteni
</a>
<br />
Mivel nincs hozzáférésem semmilyen egyetemi oldalhoz, így csak így
tudom hatékonyan tesztelni a scriptet. Ezért hatalmas segítség ha
feltöltöd azt az oldalt amin hibával találkozol.
</li>
<p /> <p />
</ul> </ul>
<hr /> <hr />
<hr />
<center> <center>
<h1>Kockázatok</h1> <h1>Kockázatok</h1>
</center> </center>
<hr />
<hr />
<ul> <ul>
<li> <li>
<b>Bármikor észrevehetik hogy használod a scriptet</b> <b>Bármikor észrevehetik hogy használod a scriptet</b>
@ -219,7 +221,7 @@ function renderMaual() {
Ha arra nem veszik a fáradságot, hogy a kérdéseket lecseréljék akkor Ha arra nem veszik a fáradságot, hogy a kérdéseket lecseréljék akkor
valószínűleg arra se hogy userscript futását detektáló kódot rakjanak valószínűleg arra se hogy userscript futását detektáló kódot rakjanak
a weboldalra. A{' '} a weboldalra. A{' '}
<a href="https://moodle.org/" target="_blank"> <a href="https://moodle.org/" target="_blank" rel="noreferrer">
Moodle Moodle
</a>{' '} </a>{' '}
egy nyílt forráskódú, valószínűleg self-hosted rendszer. Valószínűleg egy nyílt forráskódú, valószínűleg self-hosted rendszer. Valószínűleg
@ -240,7 +242,11 @@ function renderMaual() {
<b>Bármikor leállhat a szerver</b> <b>Bármikor leállhat a szerver</b>
<br /> <br />
És akkor nem bírod megnézni a válaszokat. Erre van az{' '} És akkor nem bírod megnézni a válaszokat. Erre van az{' '}
<a href="http://qmining.frylabs.net/allqr.txt?man" target="_blank"> <a
href="http://qmining.frylabs.net/allqr.txt?man"
target="_blank"
rel="noreferrer"
>
{' '} {' '}
összes kérdés TXT összes kérdés TXT
</a> </a>
@ -252,6 +258,63 @@ function renderMaual() {
</li> </li>
</ul> </ul>
<hr /> <hr />
<hr />
<center>
<h1>Egyéb</h1>
</center>
<hr />
<hr />
<h2 id="sitesave">Weboldal lementése</h2>
Hogy a hibákat a saját gépemen reprodukálni tudjam, és könnyen ki bírjam
javítani sokszor jól jön ha egy lementett weboldalt megkapok. Így lehet
letölteni egy oldalt:
<img style={{ maxWidth: '100%' }} src="img/websitesave.png" alt="img" />
<br />
<a
href="http://qmining.frylabs.net/feedback?man"
target="_blank"
rel="noreferrer"
>
Ide tudod feltölteni
</a>
<br />
Mivel nincs hozzáférésem semmilyen egyetemi oldalhoz, így csak így tudom
hatékonyan tesztelni a scriptet. Ezért hatalmas segítség ha feltöltöd azt
az oldalt amin hibával találkozol.
<hr />
<h2 id="scriptreinstall">Script újratelepítése</h2>
Jelenleg két helyről lehet telepíteni a scriptet: greasyforkról és a
weboldalamról. A greasyforkos telepítési lehetőség meg fog szűnni, így ha
onnan telepítetted, akkor nem lesznek frissítések elérhetők (amik nagyon
fontosak (de tényleg)). Ezért a következő rövid manővert kellene
végrehajtani, hogy minden zökkenőmentesen menjen:
<ul>
<li>Böngésző bővítményeidnél kattints a tampermonkey-ra</li>
<li>Válaszd ki alulról második opciót, ami dashboard néven fut</li>
<li>
Ekkor új tabban felugranak telepített scriptjeid. Keresd meg a
Moodle/Elearning/KMOOC test help-et, és a sor végén kattints a kuka
gombra
</li>
<li>Ha megkérdezi mondd neki, hogy biztos törölni akarod</li>
<li>
Ezután simán kattints{' '}
<a
href="http://qmining.frylabs.net/install?man"
target="_blank"
rel="noreferrer"
>
ide a script újratelepítéséhez a weboldalamról
</a>
</li>
<li>
Kész! Lehet megkérdezi újra, hogy elérheti-e a szervert, de azt csak
egyszer. Szokásos módon engedélyezd, hogy le bírja kérni a helyes
válaszokat
</li>
</ul>
Ezzel semmi adat nem vész el, régi jelszó ugyanolyan marad (csak ne
felejtsd azt el)
</div> </div>
) )
} }