mirror of
https://gitlab.com/MrFry/qmining-page
synced 2025-04-01 20:23:44 +02:00
Minor chages including class name rename, max entries to load on front page
This commit is contained in:
parent
b88a4d9c9e
commit
a91fa4a7fe
8 changed files with 417 additions and 15 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import React from 'react'
|
||||||
import styles from './button.module.css'
|
import styles from './button.module.css'
|
||||||
|
|
||||||
export default function Button(props) {
|
export default function Button(props) {
|
||||||
|
@ -5,7 +6,7 @@ export default function Button(props) {
|
||||||
<div>
|
<div>
|
||||||
<center>
|
<center>
|
||||||
<a href={props.href}>
|
<a href={props.href}>
|
||||||
<div className={styles.ircLink}>{props.text}</div>
|
<div className={styles.button}>{props.text}</div>
|
||||||
</a>
|
</a>
|
||||||
</center>
|
</center>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.ircLink {
|
.button {
|
||||||
background-color: #9999ff;
|
background-color: #9999ff;
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
|
@ -78,6 +78,7 @@ export default function AllQuestions({ router }) {
|
||||||
const [selectedDb, setSelectedDb] = useState('')
|
const [selectedDb, setSelectedDb] = useState('')
|
||||||
const [data, setData] = useState(null)
|
const [data, setData] = useState(null)
|
||||||
const [fetchingData, setFetchingData] = useState(false)
|
const [fetchingData, setFetchingData] = useState(false)
|
||||||
|
|
||||||
const subjectCount = data ? data.length : 0
|
const subjectCount = data ? data.length : 0
|
||||||
const questionCount = data ? data.reduce(countReducer, 0) : 0
|
const questionCount = data ? data.reduce(countReducer, 0) : 0
|
||||||
|
|
||||||
|
@ -296,6 +297,8 @@ export default function AllQuestions({ router }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
) : fetchingData ? (
|
||||||
|
<LoadingIndicator />
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -43,7 +43,8 @@ export default function Contact() {
|
||||||
<div>
|
<div>
|
||||||
<div className={'subtitle'}>Üzenet küldése</div>
|
<div className={'subtitle'}>Üzenet küldése</div>
|
||||||
<div className={styles.text}>
|
<div className={styles.text}>
|
||||||
Weboldalon keresztüli üzenetküldés az adminnak (feedback)
|
Weboldalon keresztüli üzenetküldés az adminnak (feedback). Válasz bal
|
||||||
|
alsó levelesládába (📬) érkezik majd.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<FeedbackArea from={'contact'} />
|
<FeedbackArea from={'contact'} />
|
||||||
|
|
|
@ -42,17 +42,6 @@ export default function contribute() {
|
||||||
<br /> A kurzort az oszlopcímekre mozgatva, további információkat
|
<br /> A kurzort az oszlopcímekre mozgatva, további információkat
|
||||||
olvashatsz a kategóriák tulajdonságairól.
|
olvashatsz a kategóriák tulajdonságairól.
|
||||||
</p>
|
</p>
|
||||||
{
|
|
||||||
'Ha olyan teendőt látsz, amiben tudnál és szeretnél is segíteni, akkor írj '
|
|
||||||
}
|
|
||||||
<a
|
|
||||||
href="http://qmining.frylabs.net/irc?contribute"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{'IRC'}
|
|
||||||
</a>
|
|
||||||
-n és megbeszéljük.
|
|
||||||
</div>
|
</div>
|
||||||
<center>
|
<center>
|
||||||
<div className={`buttonContainer ${styles.newTaskButton}`}>
|
<div className={`buttonContainer ${styles.newTaskButton}`}>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Composer from '../components/composer'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import constants from '../constants.json'
|
import constants from '../constants.json'
|
||||||
|
|
||||||
const forumPostPerPage = 2
|
const forumPostPerPage = 5
|
||||||
const frontpageForumName = 'frontpage'
|
const frontpageForumName = 'frontpage'
|
||||||
|
|
||||||
function fetchForum(from) {
|
function fetchForum(from) {
|
||||||
|
|
330
src/pages/userFiles.js
Normal file
330
src/pages/userFiles.js
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import Head from 'next/head'
|
||||||
|
|
||||||
|
import LoadingIndicator from '../components/LoadingIndicator'
|
||||||
|
import Modal from '../components/modal'
|
||||||
|
|
||||||
|
import styles from './userFiles.module.css'
|
||||||
|
import constants from '../constants.json'
|
||||||
|
|
||||||
|
function listUserDir(subdir) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
fetch(
|
||||||
|
`${constants.apiUrl}listUserDir${subdir ? `?subdir=${subdir}` : ''}`,
|
||||||
|
{
|
||||||
|
credentials: 'include',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
|
return resp.json()
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
resolve(res)
|
||||||
|
} else {
|
||||||
|
alert(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function FileUploader({ onChange }) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>Fájl csatolása</div>
|
||||||
|
<input type="file" name="file" onChange={onChange} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteFile(currDir, name) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
fetch(constants.apiUrl + 'deleteUserFile', {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
dir: currDir,
|
||||||
|
fname: name,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json()
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
resolve(res)
|
||||||
|
} else {
|
||||||
|
alert(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function newSubj(name) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
fetch(constants.apiUrl + 'newUserDir', {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
name: name,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json()
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
resolve(res)
|
||||||
|
} else {
|
||||||
|
alert(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadFile(dir, file) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const formData = new FormData() // eslint-disable-line
|
||||||
|
formData.append('file', file)
|
||||||
|
formData.append('dir', dir)
|
||||||
|
|
||||||
|
fetch(constants.apiUrl + 'uploadUserFile', {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json()
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function UserFiles({ router, globalData }) {
|
||||||
|
const userId = globalData.userId
|
||||||
|
const [dirs, setDirs] = useState()
|
||||||
|
const [sortBy, setSortBy] = useState('name')
|
||||||
|
const [sortDirection, setSortDirection] = useState(true)
|
||||||
|
const [addingNew, setAddingNew] = useState()
|
||||||
|
const [newSubjName, setNewSubjName] = useState()
|
||||||
|
const [file, setFile] = useState()
|
||||||
|
|
||||||
|
const currDir = router.query.dir ? decodeURIComponent(router.query.dir) : ''
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const dir = router.query.dir ? decodeURIComponent(router.query.dir) : ''
|
||||||
|
setDirs(null)
|
||||||
|
|
||||||
|
if (router.query.dir) {
|
||||||
|
listUserDir(dir).then((res) => {
|
||||||
|
setDirs(res.files)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
listUserDir().then((res) => {
|
||||||
|
setDirs(res.dirs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [router.query.dir])
|
||||||
|
|
||||||
|
const dirSorter = (a, b) => {
|
||||||
|
if (a[sortBy] < b[sortBy]) {
|
||||||
|
return sortDirection ? -1 : 1
|
||||||
|
} else if (a[sortBy] > b[sortBy]) {
|
||||||
|
return sortDirection ? 1 : -1
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderDirList = (dirs) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{currDir && (
|
||||||
|
<div className={`buttonContainer ${styles.backButton}`}>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
router.back()
|
||||||
|
// FIXME: consistend going back with browser back button
|
||||||
|
// back button works like broser back button, unless it would result in site leave
|
||||||
|
// history: nothing > opened site/usrFiles?dir=...
|
||||||
|
// history: site > site/userFiles > site/usrFiles?dir=...
|
||||||
|
router.push(`${router.pathname}`, undefined, { shallow: true })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Vissza
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={`${styles.tableContainer} ${styles.header}`}>
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
const name = e.target.getAttribute('name')
|
||||||
|
if (name) {
|
||||||
|
if (sortBy === name) {
|
||||||
|
setSortDirection(!sortDirection)
|
||||||
|
} else {
|
||||||
|
setSortDirection(true)
|
||||||
|
}
|
||||||
|
setSortBy(name)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div name="name">Fájl név</div>
|
||||||
|
<div name="date">Feltöltés dátuma</div>
|
||||||
|
<div name="size">Méret</div>
|
||||||
|
<div name="user">Feltöltő user</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`${styles.tableContainer} ${styles.rows}`}>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
setAddingNew(currDir ? 'file' : 'dir')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>{currDir ? 'Új fájl feltöltése...' : 'Új tárgy...'}</div>
|
||||||
|
</div>
|
||||||
|
{dirs.length !== 0 && (
|
||||||
|
<>
|
||||||
|
{dirs.sort(dirSorter).map((dir) => {
|
||||||
|
const { name, date, path, size, user } = dir
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
title={name}
|
||||||
|
key={name}
|
||||||
|
onClick={() => {
|
||||||
|
if (path) {
|
||||||
|
window.open(`${constants.apiUrl}${path}`, '_blank')
|
||||||
|
} else {
|
||||||
|
router.push(
|
||||||
|
`${router.pathname}?dir=${encodeURIComponent(name)}`,
|
||||||
|
undefined,
|
||||||
|
{ shallow: true }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>{name}</div>
|
||||||
|
<div>{new Date(date).toDateString()}</div>
|
||||||
|
<div>
|
||||||
|
{currDir
|
||||||
|
? (size / 1000000).toFixed(2).toString() + ' MB'
|
||||||
|
: size + ' fájl'}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{user &&
|
||||||
|
user !== -1 &&
|
||||||
|
(userId === user ? (
|
||||||
|
<div
|
||||||
|
className={styles.deleteButton}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if (confirm(`Biztos törlöd '${name}'-t ?`)) {
|
||||||
|
deleteFile(currDir, name).then(() => {
|
||||||
|
listUserDir(currDir).then((res) => {
|
||||||
|
setDirs(res.files)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Törlés
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
`#${user}`
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Head>
|
||||||
|
<title>Study Docs - Qmining | Frylabs.net</title>
|
||||||
|
</Head>
|
||||||
|
<div className="pageHeader">
|
||||||
|
<h1>Study Docs</h1>
|
||||||
|
</div>
|
||||||
|
<div className={styles.description}>
|
||||||
|
Ide tárgyanként lehet feltölteni
|
||||||
|
</div>
|
||||||
|
{dirs ? renderDirList(dirs) : <LoadingIndicator />}
|
||||||
|
{addingNew && (
|
||||||
|
<Modal
|
||||||
|
closeClick={() => {
|
||||||
|
setAddingNew(null)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={styles.uploadContainer}>
|
||||||
|
{addingNew === 'file' ? (
|
||||||
|
<>
|
||||||
|
<FileUploader
|
||||||
|
onChange={(e) => {
|
||||||
|
setFile(e.target.files[0])
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="buttonContainer"
|
||||||
|
onClick={() => {
|
||||||
|
uploadFile(currDir, file).then(() => {
|
||||||
|
listUserDir(currDir).then((res) => {
|
||||||
|
setDirs(res.files)
|
||||||
|
setAddingNew(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>Feltöltés</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div>Új tárgy neve</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
onChange={(e) => {
|
||||||
|
setNewSubjName(e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="buttonContainer"
|
||||||
|
onClick={() => {
|
||||||
|
newSubj(newSubjName).then(() => {
|
||||||
|
listUserDir().then((res) => {
|
||||||
|
setDirs(res.dirs)
|
||||||
|
setAddingNew(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>OK</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
78
src/pages/userFiles.module.css
Normal file
78
src/pages/userFiles.module.css
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
.tableContainer {
|
||||||
|
user-select: none;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableContainer > div {
|
||||||
|
padding: 15px 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableContainer > div > div {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableContainer > div > div:nth-child(1) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableContainer > div > div:nth-child(2) {
|
||||||
|
flex: 0 240px;
|
||||||
|
}
|
||||||
|
.tableContainer > div > div:nth-child(3) {
|
||||||
|
flex: 0 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableContainer > div > div:nth-child(4) {
|
||||||
|
flex: 0 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows > div {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows > div:nth-child(2n + 1) {
|
||||||
|
background-color: var(--dark-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows > div:hover {
|
||||||
|
background-color: var(--hoover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header > div > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header > div > div:hover {
|
||||||
|
background-color: var(--hoover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadContainer > div {
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2px;
|
||||||
|
border: 1px solid var(--hoover-color);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton:hover {
|
||||||
|
background-color: var(--dark-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backButton {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue