Initial commit, with fully working project :p

This commit is contained in:
MrFry 2020-03-25 13:25:41 +01:00
commit 53b4158967
21 changed files with 894 additions and 0 deletions

23
src/pages/_app.js Normal file
View file

@ -0,0 +1,23 @@
// import App from 'next/app'
import '../defaultStyles.css'
function MyApp ({ Component, pageProps, router }) {
return (
<Component {...pageProps} />
)
}
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
export default MyApp

22
src/pages/_document.js Normal file
View file

@ -0,0 +1,22 @@
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps (ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render () {
return (
<Html>
<Head />
<body bgcolor='#212127'>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument

136
src/pages/index.js Normal file
View file

@ -0,0 +1,136 @@
import React, { useState, useEffect } from 'react'
import fetch from 'unfetch'
import SubjectView from '../components/subjectView'
import QuestionView from '../components/questionView'
import LoadingIndicator from '../components/LoadingIndicator'
import styles from './index.module.css'
import constants from '../constants.json'
const views = {
subject: 'SUBJECT',
question: 'QUESTION'
}
// TODO:
// Add question on subjects view
// question.data editor
// save data to server / load it from there
// save: save question count and subj count
// save deleted/removed questions ?
// edit \n-s in questions / answers
export default function Index (props) {
const [data, setData] = useState(null)
const [view, setView] = useState(views.subject)
const setIndexes = (d) => {
d.Subjects.forEach((subj, i) => {
subj.ind = i
subj.Questions.forEach((question, j) => {
question.ind = j
})
})
return d
}
useEffect(() => {
console.info('Fetching data')
fetch(`${constants.apiUrl}data.json`)
.then((resp) => {
return resp.json()
})
.then((resp) => {
if (data) {
console.warn('Tried to refetch data when it was still set!')
} else {
setData(setIndexes(resp))
}
})
}, [])
const deleteQuestion = (subjInd, questionInd) => {
data.Subjects[subjInd].Questions.splice(questionInd, 1)
setData({
...setIndexes(data)
})
}
const onChange = (subjInd, questionInd, newVal) => {
data.Subjects[subjInd].Questions[questionInd] = newVal
setData({
...data
})
}
const renderView = () => {
if (view === views.subject) {
return (
<SubjectView
onChange={onChange}
data={data}
deleteQuestion={deleteQuestion}
/>
)
} else if (view === views.question) {
return (
<QuestionView
onChange={onChange}
data={data}
deleteQuestion={deleteQuestion}
/>
)
} else {
return (
<div>
No view!
</div>
)
}
}
const downloadFile = async (data) => {
const json = JSON.stringify(data)
const blob = new Blob([json], { type: 'application/json' }) // eslint-disable-line
const href = await URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = href
link.download = 'data.json'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
if (!data) {
return (
<LoadingIndicator />
)
}
return (
<div>
<div className={styles.buttonContainer}>
<span
className={styles.tabButton}
onClick={() => { setView(views.subject) }}>
Subject view
</span>
<span
className={styles.tabButton}
onClick={() => { setView(views.question) }}>
Question view
</span>
<span
className={styles.downloadButton}
onClick={() => {
downloadFile(data)
}}
>
Download result
</span>
</div>
{renderView()}
</div>
)
}

View file

@ -0,0 +1,33 @@
.tabButton {
display: inline-block;
margin: 5px;
padding: 5px;
height: 45px;
font-size: 30px;
width: 25%;
text-align: center;
border-color: var(--background-color);
border: 1px solid;
}
.downloadButton {
display: inline-block;
margin: 5px;
padding: 5px;
height: 45px;
font-size: 30px;
width: 26%;
text-align: center;
border-color: var(--background-color);
border: 1px solid;
word-wrap: none;
}
.tabButton:hover {
border-color: white;
}
.buttonContainer {
text-align: center;
width: 100%;
}