diff --git a/src/components/Button.js b/src/components/Button.js index 8395434..944060d 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -1,3 +1,4 @@ +import React from 'react' import styles from './button.module.css' export default function Button(props) { @@ -5,7 +6,7 @@ export default function Button(props) {
-
{props.text}
+
{props.text}
diff --git a/src/components/button.module.css b/src/components/button.module.css index 2f6e5e4..20d1ad0 100644 --- a/src/components/button.module.css +++ b/src/components/button.module.css @@ -1,4 +1,4 @@ -.ircLink { +.button { background-color: #9999ff; border: none; color: white; diff --git a/src/pages/allQuestions.js b/src/pages/allQuestions.js index ae4196f..3b8ce78 100644 --- a/src/pages/allQuestions.js +++ b/src/pages/allQuestions.js @@ -78,6 +78,7 @@ export default function AllQuestions({ router }) { const [selectedDb, setSelectedDb] = useState('') const [data, setData] = useState(null) const [fetchingData, setFetchingData] = useState(false) + const subjectCount = data ? data.length : 0 const questionCount = data ? data.reduce(countReducer, 0) : 0 @@ -296,6 +297,8 @@ export default function AllQuestions({ router }) { )} + ) : fetchingData ? ( + ) : null} ) diff --git a/src/pages/contact.js b/src/pages/contact.js index bfaae40..e36c2bf 100644 --- a/src/pages/contact.js +++ b/src/pages/contact.js @@ -43,7 +43,8 @@ export default function Contact() {
Üzenet küldése
- 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.
diff --git a/src/pages/contribute.js b/src/pages/contribute.js index 06f9c61..155be01 100644 --- a/src/pages/contribute.js +++ b/src/pages/contribute.js @@ -42,17 +42,6 @@ export default function contribute() {
A kurzort az oszlopcímekre mozgatva, további információkat olvashatsz a kategóriák tulajdonságairól.

- { - 'Ha olyan teendőt látsz, amiben tudnál és szeretnél is segíteni, akkor írj ' - } - - {'IRC'} - - -n és megbeszéljük.
diff --git a/src/pages/index.js b/src/pages/index.js index da93824..f0031b6 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -10,7 +10,7 @@ import Composer from '../components/composer' import styles from './index.module.css' import constants from '../constants.json' -const forumPostPerPage = 2 +const forumPostPerPage = 5 const frontpageForumName = 'frontpage' function fetchForum(from) { diff --git a/src/pages/userFiles.js b/src/pages/userFiles.js new file mode 100644 index 0000000..c49c249 --- /dev/null +++ b/src/pages/userFiles.js @@ -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 ( +
+
Fájl csatolása
+ +
+ ) +} + +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 ( +
+ {currDir && ( +
+
{ + 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 +
+
+ )} +
+
{ + const name = e.target.getAttribute('name') + if (name) { + if (sortBy === name) { + setSortDirection(!sortDirection) + } else { + setSortDirection(true) + } + setSortBy(name) + } + }} + > +
Fájl név
+
Feltöltés dátuma
+
Méret
+
Feltöltő user
+
+
+
+
{ + setAddingNew(currDir ? 'file' : 'dir') + }} + > +
{currDir ? 'Új fájl feltöltése...' : 'Új tárgy...'}
+
+ {dirs.length !== 0 && ( + <> + {dirs.sort(dirSorter).map((dir) => { + const { name, date, path, size, user } = dir + return ( +
{ + if (path) { + window.open(`${constants.apiUrl}${path}`, '_blank') + } else { + router.push( + `${router.pathname}?dir=${encodeURIComponent(name)}`, + undefined, + { shallow: true } + ) + } + }} + > +
{name}
+
{new Date(date).toDateString()}
+
+ {currDir + ? (size / 1000000).toFixed(2).toString() + ' MB' + : size + ' fájl'} +
+
+ {user && + user !== -1 && + (userId === user ? ( +
{ + e.stopPropagation() + if (confirm(`Biztos törlöd '${name}'-t ?`)) { + deleteFile(currDir, name).then(() => { + listUserDir(currDir).then((res) => { + setDirs(res.files) + }) + }) + } + }} + > + Törlés +
+ ) : ( + `#${user}` + ))} +
+
+ ) + })} + + )} +
+
+ ) + } + + return ( +
+ + Study Docs - Qmining | Frylabs.net + +
+

Study Docs

+
+
+ Ide tárgyanként lehet feltölteni +
+ {dirs ? renderDirList(dirs) : } + {addingNew && ( + { + setAddingNew(null) + }} + > +
+ {addingNew === 'file' ? ( + <> + { + setFile(e.target.files[0]) + }} + /> +
{ + uploadFile(currDir, file).then(() => { + listUserDir(currDir).then((res) => { + setDirs(res.files) + setAddingNew(null) + }) + }) + }} + > +
Feltöltés
+
+ + ) : ( + <> +
Új tárgy neve
+
+ { + setNewSubjName(e.target.value) + }} + /> +
+
{ + newSubj(newSubjName).then(() => { + listUserDir().then((res) => { + setDirs(res.dirs) + setAddingNew(null) + }) + }) + }} + > +
OK
+
+ + )} +
+
+ )} +
+ ) +} diff --git a/src/pages/userFiles.module.css b/src/pages/userFiles.module.css new file mode 100644 index 0000000..1abb5a0 --- /dev/null +++ b/src/pages/userFiles.module.css @@ -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; +}