aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Notes/components/Import.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Notes/components/Import.js')
-rw-r--r--apps/Notes/components/Import.js104
1 files changed, 102 insertions, 2 deletions
diff --git a/apps/Notes/components/Import.js b/apps/Notes/components/Import.js
index 6182ca6..71c08d6 100644
--- a/apps/Notes/components/Import.js
+++ b/apps/Notes/components/Import.js
@@ -1,10 +1,85 @@
+import React, {useState} from 'react'
+import fetchJson from 'lib/fetchJson'
+import useNotes from '../hooks/useNotes'
+import {faCheck, faTimes} from '@fortawesome/free-solid-svg-icons'
+import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
+
const Import = ({action, setAction}) => {
+ const [files, setFiles] = useState()
+ const [done, setDone] = useState([])
+ const {mutateNotes} = useNotes()
+
+ const state = i => done[i] && <span><FontAwesomeIcon icon={done[i] === 1 ? faCheck : faTimes} /></span>
+
+ const readFileAsText = (file) => new Promise((resolve,reject) => {
+ let fr = new FileReader()
+
+ fr.onload = () => resolve(fr.result)
+ fr.onerror = () => reject(fr)
+
+ fr.readAsText(file)
+ })
+
+ const handleImport = async e => {
+ e.preventDefault();
+
+ Array.from(files).forEach(async (file, i) => {
+ const title = file.name.replace(/\.[^/.]+$/, "")
+ const content = await readFileAsText(file);
+
+ try {
+ const notes = await fetchJson('/api/notes', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({title, content}),
+ })
+ if (i === files.length - 1) await mutateNotes(notes)
+ setDone((prev) => ({...prev, [i]: 1}))
+ } catch (e) {
+ setDone((prev) => ({...prev, [i]: 0}))
+ }
+ })
+ }
+
+ const handleChange = e => {
+ setFiles(e.currentTarget.files)
+ setDone([])
+ }
+
return (
<section>
<div className='window__submenu'>
<div onClick={() => { setAction('') }}>Back</div>
- <div>From txt</div>
- <div>From JSON</div>
+ </div>
+ <div className='window__scroll'>
+ <form onSubmit={handleImport}>
+ Import new notes:
+ <div>
+ <label className="window__button">
+ Choose files
+ <input
+ name="import"
+ type="file"
+ multiple="multiple"
+ accept="text/plain"
+ onChange={handleChange}
+ />
+ </label>
+ </div>
+ {files && (
+ <>
+ <p>Notes to import:</p>
+ <ul>
+ {[...files].map((f, i) => <li key={f.name}>{f.name} {state(i)}</li>)}
+ </ul>
+ {
+ done.length === 0
+ ? <input type="submit" value="Import" className="window__button" />
+ : <p>Import finished.<br/><br/>Go back to notes list or choose other notes to import.</p>
+ }
+ </>
+ )}
+ </form>
</div>
<style jsx>{`
section {
@@ -17,6 +92,31 @@ const Import = ({action, setAction}) => {
left: 0;
animation: fade-in .3s;
}
+
+ form {
+ padding: 1em;
+ }
+
+ input[type=file] {
+ display: none;
+ }
+
+ label {
+ display: inline-block;
+ cursor: pointer;
+ }
+
+ ul {
+ list-style: disc inside none;
+ }
+
+ li {
+ padding: .25em;
+ }
+
+ p {
+ padding: 1em 0;
+ }
`}</style>
</section>
)