aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Notes
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Notes')
-rw-r--r--apps/Notes/Notes.module.scss16
-rw-r--r--apps/Notes/components/Actions.js9
-rw-r--r--apps/Notes/components/Export.js83
-rw-r--r--apps/Notes/components/Import.js2
-rw-r--r--apps/Notes/components/List.js9
-rw-r--r--apps/Notes/components/ListItem.js1
-rw-r--r--apps/Notes/helpers/fileName.js3
-rw-r--r--apps/Notes/helpers/noteActions.js10
-rw-r--r--apps/Notes/hooks/useNotes.js1
9 files changed, 116 insertions, 18 deletions
diff --git a/apps/Notes/Notes.module.scss b/apps/Notes/Notes.module.scss
index babffa2..2e3c68f 100644
--- a/apps/Notes/Notes.module.scss
+++ b/apps/Notes/Notes.module.scss
@@ -232,6 +232,22 @@
}
}
+.export {
+ padding: 1em;
+
+ p {
+ padding-top: 2em;
+ padding-bottom: 1em;
+ }
+
+ &__select {
+ display: inline-block;
+ border-bottom: 1px dashed #666;
+ padding-bottom: .25em;
+ margin-bottom: .5em;
+ }
+}
+
.loader,
.connection {
display: flex;
diff --git a/apps/Notes/components/Actions.js b/apps/Notes/components/Actions.js
index 8f08103..1f5d680 100644
--- a/apps/Notes/components/Actions.js
+++ b/apps/Notes/components/Actions.js
@@ -1,6 +1,7 @@
import NoteView from './NoteView'
import NoteEdit from './NoteEdit'
import Import from './Import'
+import Export from './Export'
const Actions = ({
action, setAction, fetchedNote, setFetchedNote
@@ -26,9 +27,13 @@ const Actions = ({
fetchedNote={fetchedNote}
/>
)
- case 'importNote': return (
+ case 'importNotes': return (
<Import
- action={action}
+ setAction={setAction}
+ />
+ )
+ case 'exportNotes': return (
+ <Export
setAction={setAction}
/>
)
diff --git a/apps/Notes/components/Export.js b/apps/Notes/components/Export.js
new file mode 100644
index 0000000..f281d1a
--- /dev/null
+++ b/apps/Notes/components/Export.js
@@ -0,0 +1,83 @@
+import styles from '../Notes.module.scss'
+import React, {useState} from 'react'
+import useNotes from '../hooks/useNotes'
+import fetchJson from 'lib/fetchJson'
+import JSZip from 'jszip'
+import saveFile from 'helpers/saveFile'
+import filename from '../helpers/fileName'
+// import {state, color, handleImport, handleChange} from '../helpers/import'
+
+const Export = ({setAction}) => {
+ const {notes} = useNotes()
+ const [ids, setIds] = useState(notes.map(n => n.noteId))
+ // const [files, setFiles] = useState()
+ // const [done, setDone] = useState([])
+
+ const handleSelect = id => {
+ ids.includes(id)
+ ? setIds(ids.filter(i => i !== id))
+ : setIds([...ids, id])
+ }
+
+ const handleSelectAll = e => {
+ if (e.target.checked) {
+ setIds(notes.map(n => n.noteId))
+ } else {
+ setIds([])
+ }
+ }
+
+ const handleExport = e => {
+ e.preventDefault()
+ const zip = new JSZip()
+
+ Promise.all(ids.map(async id => {
+ const title = notes.find(n => n.noteId === id).title
+ const {content} = await fetchJson(`/api/note/${id}`)
+ zip.folder('notes').file(filename(title), content, {binary: true})
+ })).then(() => {
+ zip.generateAsync({type:"blob"})
+ .then(c => saveFile(c, 'notes.zip', 'application/zip'))
+ })
+ }
+
+ if (!notes) return null
+
+ return (
+ <section>
+ <div className='window__submenu'>
+ <div onClick={() => {setAction('')}}>Back</div>
+ </div>
+ <div className={`window__scroll ${styles.export}`}>
+ <h3>Click to export your notes:</h3>
+ <input
+ className="window__button"
+ type="submit"
+ value="Export"
+ onClick={handleExport}
+ />
+ <p>Notes to export:</p>
+ <div className={`${styles.export__select}`}>
+ <input type="checkbox" name='selectAll' onChange={handleSelectAll} checked={notes.length === ids.length} />
+ <label htmlFor='selectAll'>Select all</label>
+ </div>
+ {notes.map(note => (
+ <div key={note.noteId}>
+ <input
+ type="checkbox"
+ name={note.noteId}
+ value={note.noteId}
+ checked={ids.includes(note.noteId)}
+ onChange={() => handleSelect(note.noteId)}
+ />
+ <label htlmfor={note.noteId}>
+ {note.title}
+ </label><br/>
+ </div>
+ ))}
+ </div>
+ </section>
+ )
+}
+
+export default Export
diff --git a/apps/Notes/components/Import.js b/apps/Notes/components/Import.js
index 2e2e5c7..700acb4 100644
--- a/apps/Notes/components/Import.js
+++ b/apps/Notes/components/Import.js
@@ -4,7 +4,7 @@ import fetchJson from 'lib/fetchJson'
import useNotes from '../hooks/useNotes'
import {state, color, handleImport, handleChange} from '../helpers/import'
-const Import = ({action, setAction}) => {
+const Import = ({setAction}) => {
const [files, setFiles] = useState()
const [done, setDone] = useState([])
const {mutateNotes} = useNotes()
diff --git a/apps/Notes/components/List.js b/apps/Notes/components/List.js
index e4060d5..0f6221e 100644
--- a/apps/Notes/components/List.js
+++ b/apps/Notes/components/List.js
@@ -1,9 +1,8 @@
import styles from '../Notes.module.scss'
-import React, {useState, useEffect, useRef} from 'react'
+import React, {useState} from 'react'
import useUser from 'lib/useUser'
import useNotes from '../hooks/useNotes'
import useSort from '../hooks/useSort'
-import {Layout} from 'components'
import ListItem from './ListItem'
import Actions from './Actions'
import Splash from './Splash'
@@ -13,7 +12,7 @@ const List = () => {
const [action, setAction] = useState('')
const {notes, error} = useNotes()
const [sortedBy, sortBy, sortFn] = useSort(2)
- const {user, mutateUser} = useUser({
+ const {user} = useUser({
redirectToLogin: true,
redirectToVerify: true,
})
@@ -31,8 +30,8 @@ const List = () => {
<>
<div className='window__submenu'>
<div onClick={() => setAction('addNote')}>New note</div>
- <div onClick={() => setAction('importNote')}>Import</div>
- <div onClick={() => {}}>Export</div>
+ <div onClick={() => setAction('importNotes')}>Import</div>
+ <div onClick={() => setAction('exportNotes')}>Export</div>
</div>
<table className={styles.notesList}>
<thead>
diff --git a/apps/Notes/components/ListItem.js b/apps/Notes/components/ListItem.js
index 47dea3b..caa22e9 100644
--- a/apps/Notes/components/ListItem.js
+++ b/apps/Notes/components/ListItem.js
@@ -1,6 +1,5 @@
import styles from '../Notes.module.scss'
import React, { useContext } from 'react'
-import fetchJson from 'lib/fetchJson'
import {getNote, exportNote, removeNote} from '../helpers/noteActions.js'
import useNotes from '../hooks/useNotes'
import Context from 'context';
diff --git a/apps/Notes/helpers/fileName.js b/apps/Notes/helpers/fileName.js
new file mode 100644
index 0000000..f5d4a8e
--- /dev/null
+++ b/apps/Notes/helpers/fileName.js
@@ -0,0 +1,3 @@
+const filename = (t) => t.toLowerCase().replaceAll(' ', '-')+'.txt'
+
+export default filename
diff --git a/apps/Notes/helpers/noteActions.js b/apps/Notes/helpers/noteActions.js
index f90e1c7..9588150 100644
--- a/apps/Notes/helpers/noteActions.js
+++ b/apps/Notes/helpers/noteActions.js
@@ -1,4 +1,5 @@
import fetchJson from 'lib/fetchJson'
+import filename from '../helpers/fileName'
export const getNote = async (note, setFetchedNote, setPopup, callback) => {
try {
@@ -108,12 +109,5 @@ export const exportNote = async note => {
? note
: await fetchJson(`/api/note/${note.noteId}`)
- const a = document.createElement('a');
- const file = new Blob([content], {type: 'text/plain'});
-
- a.href= URL.createObjectURL(file);
- a.download = title.toLowerCase().replaceAll(' ', '-')+'.txt';
- a.click();
-
- URL.revokeObjectURL(a.href);
+ saveFile(content, filename(title), 'text/plain')
}
diff --git a/apps/Notes/hooks/useNotes.js b/apps/Notes/hooks/useNotes.js
index 9d79034..586ceeb 100644
--- a/apps/Notes/hooks/useNotes.js
+++ b/apps/Notes/hooks/useNotes.js
@@ -1,5 +1,4 @@
import useSWR from 'swr'
-import fetchJson from 'lib/fetchJson'
export default function useNotes(){
const { data: notes, error, mutate: mutateNotes } = useSWR('/api/notes')