diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/Notes/components/Export.js | 12 | ||||
-rw-r--r-- | apps/Notes/components/Import.js | 15 | ||||
-rw-r--r-- | apps/Notes/components/List.js | 18 | ||||
-rw-r--r-- | apps/Notes/components/ListItem.js | 8 | ||||
-rw-r--r-- | apps/Notes/components/NoteEdit.js | 16 | ||||
-rw-r--r-- | apps/Notes/components/NoteView.js | 16 | ||||
-rw-r--r-- | apps/Notes/helpers/copyToClipboard.js | 6 | ||||
-rw-r--r-- | apps/Notes/helpers/export.js | 2 | ||||
-rw-r--r-- | apps/Notes/helpers/import.js | 2 | ||||
-rw-r--r-- | apps/Notes/helpers/noteActions.js | 32 | ||||
-rw-r--r-- | apps/Settings/api.js | 10 | ||||
-rw-r--r-- | apps/Settings/components/Settings.js | 64 | ||||
-rw-r--r-- | apps/Settings/styles/Settings.module.scss | 18 |
13 files changed, 128 insertions, 91 deletions
diff --git a/apps/Notes/components/Export.js b/apps/Notes/components/Export.js index e7966e4..0838cea 100644 --- a/apps/Notes/components/Export.js +++ b/apps/Notes/components/Export.js @@ -1,10 +1,12 @@ import styles from '../Notes.module.scss' import React, {useState} from 'react' +import useSettings from 'hooks/useSettings' import useNotes from '../hooks/useNotes' import {handleSelect, handleSelectAll, handleExport} from '../helpers/export' const Export = ({setAction}) => { const {notes} = useNotes() + const {t} = useSettings() const [ids, setIds] = useState(notes.map(n => n.noteId)) const sortFn = (a, b) => new Date(b.updated_at) - new Date(a.updated_at) @@ -13,17 +15,17 @@ const Export = ({setAction}) => { return ( <section> <div className='window__submenu'> - <div onClick={() => {setAction('')}}>Back</div> + <div onClick={() => {setAction('')}}>{t('back')}</div> </div> <div className={`window__scroll ${styles.export}`}> - <h3>Click to export your notes:</h3> + <h3>{t('notes_click_to_export')}</h3> <input className="window__button" type="submit" - value="Export" + value={t('export')} onClick={e => handleExport(e, ids, notes)} /> - <p>Notes to export:</p> + <p>{t('notes_to_export')}</p> <div className={styles.export__select}> <input type="checkbox" @@ -31,7 +33,7 @@ const Export = ({setAction}) => { onChange={e => handleSelectAll(e, notes, setIds)} checked={notes.length === ids.length} /> - <label htmlFor='selectAll'>Select all</label> + <label htmlFor='selectAll'>{t('select_all')}</label> </div> <ul> {notes.sort(sortFn).map(note => ( diff --git a/apps/Notes/components/Import.js b/apps/Notes/components/Import.js index 700acb4..ad2b831 100644 --- a/apps/Notes/components/Import.js +++ b/apps/Notes/components/Import.js @@ -1,10 +1,11 @@ import styles from '../Notes.module.scss' import React, {useState} from 'react' -import fetchJson from 'lib/fetchJson' +import useSettings from 'hooks/useSettings' import useNotes from '../hooks/useNotes' import {state, color, handleImport, handleChange} from '../helpers/import' const Import = ({setAction}) => { + const {t} = useSettings() const [files, setFiles] = useState() const [done, setDone] = useState([]) const {mutateNotes} = useNotes() @@ -12,14 +13,14 @@ const Import = ({setAction}) => { return ( <section className={styles.import}> <div className='window__submenu'> - <div onClick={() => {setAction('')}}>Back</div> + <div onClick={() => {setAction('')}}>{t('back')}</div> </div> <div className='window__scroll'> <form onSubmit={e => handleImport(e, files, mutateNotes, setDone)}> - Import new notes: + {t('notes_import')} <div> <label className="window__button"> - Choose files + {t('choose_files')} <input name="import" type="file" @@ -31,14 +32,14 @@ const Import = ({setAction}) => { </div> {files && ( <> - <p>Notes to import:</p> + <p>{t('notes_to_import')}</p> <ul> {[...files].map((f, i) => <li style={color(done[i])} key={f.name}>{f.name} {state(done[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> + ? <input type="submit" value={t('import')} className="window__button" /> + : <p>{t('import_finished')}<br/><br/>{t('notes_import_go_back')}</p> } </> )} diff --git a/apps/Notes/components/List.js b/apps/Notes/components/List.js index 1fd03af..9655d74 100644 --- a/apps/Notes/components/List.js +++ b/apps/Notes/components/List.js @@ -1,6 +1,7 @@ import styles from '../Notes.module.scss' import React, {useState, useEffect} from 'react' -import useUser from 'lib/useUser' +import useUser from 'hooks/useUser' +import useSettings from 'hooks/useSettings' import useNotes from '../hooks/useNotes' import useSort from '../hooks/useSort' import ListItem from './ListItem' @@ -13,6 +14,7 @@ const List = () => { const [loading, setLoading] = useState(false) const {notes, error} = useNotes() const [sortedBy, sortBy, sortFn] = useSort(3) + const {t} = useSettings() const {user} = useUser({ redirectToLogin: true, redirectToVerify: true, @@ -32,16 +34,16 @@ const List = () => { action === '' ? ( <> <div className='window__submenu'> - <div onClick={() => setAction('addNote')}>New note</div> - <div onClick={() => setAction('importNotes')}>Import</div> - <div onClick={() => setAction('exportNotes')}>Export</div> + <div onClick={() => setAction('addNote')}>{t('notes_new')}</div> + <div onClick={() => setAction('importNotes')}>{t('import')}</div> + <div onClick={() => setAction('exportNotes')}>{t('export')}</div> </div> <table className={styles.notesList}> <thead> <tr> - <th onClick={() => sortBy(1)}>Title {sortedBy(1)}</th> - <th onClick={() => sortBy(2)}>Created {sortedBy(2)}</th> - <th onClick={() => sortBy(3)}>Modified {sortedBy(3)}</th> + <th onClick={() => sortBy(1)}>{t('title')} {sortedBy(1)}</th> + <th onClick={() => sortBy(2)}>{t('created')} {sortedBy(2)}</th> + <th onClick={() => sortBy(3)}>{t('modified')} {sortedBy(3)}</th> </tr> </thead> <tbody> @@ -57,7 +59,7 @@ const List = () => { /> ))) : ( <tr> - <td>Your notes list is empty.</td> + <td>{t('notes_list_empty')}</td> </tr> )} </tbody> diff --git a/apps/Notes/components/ListItem.js b/apps/Notes/components/ListItem.js index 4a404db..4a2d6f6 100644 --- a/apps/Notes/components/ListItem.js +++ b/apps/Notes/components/ListItem.js @@ -1,8 +1,9 @@ import styles from '../Notes.module.scss' import React from 'react' import {getNote, exportNote, removeNote} from '../helpers/noteActions.js' -import useNotes from '../hooks/useNotes' +import useSettings from 'hooks/useSettings' import usePopup from 'hooks/usePopup' +import useNotes from '../hooks/useNotes' import {faEdit, faDownload, faTrash } from '@fortawesome/free-solid-svg-icons' import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' @@ -13,13 +14,14 @@ const datestring = date => { }; const ListItem = ({note, setAction, setFetchedNote, setLoading}) => { + const {t} = useSettings() const {setPopup} = usePopup() const {mutateNotes} = useNotes() const handleNoteAction = async (a, note, e) => { if (e) e.stopPropagation() setLoading(true) - await getNote(note, setFetchedNote, setPopup, () => setAction(a)) + await getNote(note, setFetchedNote, t, setPopup, () => setAction(a)) } return ( @@ -36,7 +38,7 @@ const ListItem = ({note, setAction, setFetchedNote, setLoading}) => { <span onClick={e => {e.stopPropagation(); exportNote(note)}}> <FontAwesomeIcon icon={faDownload} /> </span> - <span onClick={e => removeNote(e, note._id, mutateNotes, setPopup, setAction)}> + <span onClick={e => removeNote(e, note._id, mutateNotes, t, setPopup, setAction)}> <FontAwesomeIcon icon={faTrash} /> </span> </td> diff --git a/apps/Notes/components/NoteEdit.js b/apps/Notes/components/NoteEdit.js index 40a33c0..f9cc3f2 100644 --- a/apps/Notes/components/NoteEdit.js +++ b/apps/Notes/components/NoteEdit.js @@ -1,24 +1,26 @@ import styles from '../Notes.module.scss' import React from 'react' -import useNotes from '../hooks/useNotes' import usePopup from 'hooks/usePopup' +import useSettings from 'hooks/useSettings' +import useNotes from '../hooks/useNotes' import {addNote, updateNote} from '../helpers/noteActions.js' const NoteEdit = ({setAction, fetchedNote}) => { - const {mutateNotes} = useNotes() + const {t} = useSettings() const {setPopup} = usePopup() + const {mutateNotes} = useNotes() const handleSubmit = e => { e.preventDefault() fetchedNote - ? updateNote(e, fetchedNote, mutateNotes, setAction, setPopup) - : addNote(e, mutateNotes, setAction, setPopup) + ? updateNote(e, fetchedNote, mutateNotes, setAction, t, setPopup) + : addNote(e, mutateNotes, setAction, t, setPopup) } return ( <div className={styles.noteEdit}> - <h2>{fetchedNote ? 'Edit note:' : 'Add new note:'}</h2> + <h2>{fetchedNote ? t('notes_edit') : t('notes_add_new')}</h2> <form onSubmit={handleSubmit}> <input name='title' @@ -38,12 +40,12 @@ const NoteEdit = ({setAction, fetchedNote}) => { className='window__button' onClick={() => {setAction(fetchedNote ? 'showNote' : '')}} > - Cancel + {t('cancel')} </span> <input className='window__button' type="submit" - value={fetchedNote ? 'Save note' : 'Add note'} + value={fetchedNote ? t('notes_save') : t('notes_add')} /> </div> </form> diff --git a/apps/Notes/components/NoteView.js b/apps/Notes/components/NoteView.js index 6926b09..02937f8 100644 --- a/apps/Notes/components/NoteView.js +++ b/apps/Notes/components/NoteView.js @@ -1,12 +1,14 @@ import styles from '../Notes.module.scss' import React from 'react'; -import useNotes from '../hooks/useNotes' +import useSettings from 'hooks/useSettings' import usePopup from 'hooks/usePopup' +import useNotes from '../hooks/useNotes' import {removeNote, exportNote} from '../helpers/noteActions.js' import copyToClipboard from '../helpers/copyToClipboard.js' import Splash from 'components/Splash' const NoteView = ({fetchedNote, setFetchedNote, setAction}) => { + const {t} = useSettings() const {setPopup} = usePopup() const {mutateNotes} = useNotes() @@ -21,19 +23,17 @@ const NoteView = ({fetchedNote, setFetchedNote, setAction}) => { return ( <section className={styles.noteView}> <div className='window__submenu'> - <div onClick={() => {setFetchedNote(); setAction('')}}>Back</div> - <div onClick={() => copyToClipboard(content, setPopup)}>Copy</div> - <div onClick={() => {setAction('editNote')}}>Edit</div> - <div onClick={() => exportNote(fetchedNote)}>Export</div> - <div onClick={e => {removeNote(e, _id, mutateNotes, setPopup, setAction)}}>Remove</div> + <div onClick={() => {setFetchedNote(); setAction('')}}>{t('back')}</div> + <div onClick={() => copyToClipboard(content, t, setPopup)}>{t('copy')}</div> + <div onClick={() => {setAction('editNote')}}>{t('edit')}</div> + <div onClick={() => exportNote(fetchedNote)}>{t('export')}</div> + <div onClick={e => {removeNote(e, _id, mutateNotes, t, setPopup, setAction)}}>{t('remove')}</div> </div> <div className='window__scroll'> <h2>{title}</h2> <p>{content}</p> </div> - <style jsx>{` - `}</style> </section> ) } diff --git a/apps/Notes/helpers/copyToClipboard.js b/apps/Notes/helpers/copyToClipboard.js index 608d299..afaf7f6 100644 --- a/apps/Notes/helpers/copyToClipboard.js +++ b/apps/Notes/helpers/copyToClipboard.js @@ -1,15 +1,15 @@ -const copyToClipboard = (text, setPopup) => { +const copyToClipboard = (text, t, setPopup) => { navigator .clipboard.writeText(text) .then(() => { setPopup({ - content: 'Note content was copied to clipboard', + content: t('notes_copy_success'), time: 2000, }) }) .catch(() => { setPopup({ - content: 'Could not copy to clipboard', + content: t('notes_copy_error'), time: 2000, error: true }) diff --git a/apps/Notes/helpers/export.js b/apps/Notes/helpers/export.js index 011dc18..80fa100 100644 --- a/apps/Notes/helpers/export.js +++ b/apps/Notes/helpers/export.js @@ -1,4 +1,4 @@ -import fetchJson from 'lib/fetchJson' +import fetchJson from 'helpers/fetchJson' import JSZip from 'jszip' import saveFile from 'helpers/saveFile' import filename from '../helpers/fileName' diff --git a/apps/Notes/helpers/import.js b/apps/Notes/helpers/import.js index b05a458..c0c3714 100644 --- a/apps/Notes/helpers/import.js +++ b/apps/Notes/helpers/import.js @@ -1,4 +1,4 @@ -import fetchJson from 'lib/fetchJson' +import fetchJson from 'helpers/fetchJson' import {faCheck, faTimes} from '@fortawesome/free-solid-svg-icons' import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' diff --git a/apps/Notes/helpers/noteActions.js b/apps/Notes/helpers/noteActions.js index 4b47011..f67e7a4 100644 --- a/apps/Notes/helpers/noteActions.js +++ b/apps/Notes/helpers/noteActions.js @@ -1,8 +1,8 @@ -import fetchJson from 'lib/fetchJson' -import filename from '../helpers/fileName' +import fetchJson from 'helpers/fetchJson' import saveFile from 'helpers/saveFile' +import filename from '../helpers/fileName' -export const getNote = async (note, setFetchedNote, setPopup, callback) => { +export const getNote = async (note, setFetchedNote, t, setPopup, callback) => { try { const {content} = await fetchJson(`/api/note/${note.noteId}`) setFetchedNote({ ...note, content}) @@ -10,14 +10,14 @@ export const getNote = async (note, setFetchedNote, setPopup, callback) => { } catch (err) { setFetchedNote() setPopup({ - content: 'Could not open note', + content: t('notes_open_error'), time: 2000, error: true, }) } } -export const addNote = async (e, mutateNotes, setAction, setPopup) => { +export const addNote = async (e, mutateNotes, setAction, t, setPopup) => { const content = e.currentTarget.content.value const title = e.currentTarget.title.value @@ -30,20 +30,20 @@ export const addNote = async (e, mutateNotes, setAction, setPopup) => { }) ) setPopup({ - content: 'New note added', + content: t('notes_added'), time: 2000, }) setAction('') } catch (e) { setPopup({ - content: 'Could not save note', + content: t(notes_added_error), time: 2000, error: true, }) } } -export const updateNote = async (e, note, mutateNotes, setAction, setPopup) => { +export const updateNote = async (e, note, mutateNotes, setAction, t, setPopup) => { const content = e.currentTarget.content.value const title = e.currentTarget.title.value const {_id, noteId} = note @@ -57,20 +57,20 @@ export const updateNote = async (e, note, mutateNotes, setAction, setPopup) => { }) ) setPopup({ - content: 'Note updated', + content: t('notes_updated'), time: 2000, }) setAction('') } catch (e) { setPopup({ - content: 'Could not update note', + content: t('notes_updated_error'), time: 2000, error: true, }) } } -export const removeNote = (e, _id, mutateNotes, setPopup, setAction) => { +export const removeNote = (e, _id, mutateNotes, t, setPopup, setAction) => { e.stopPropagation() const remove = async () => { @@ -83,13 +83,13 @@ export const removeNote = (e, _id, mutateNotes, setPopup, setAction) => { }) ) setPopup({ - content: 'Note was removed', + content: t('notes_removed'), time: 2000, }) setAction('') } catch (err) { setPopup({ - content: 'Could not remove note', + content: t('notes_removed_error'), time: 2000, error: true, }) @@ -97,9 +97,9 @@ export const removeNote = (e, _id, mutateNotes, setPopup, setAction) => { } setPopup({ - content: 'Do you want to remove note?', - yes: { label: 'Remove', action: remove }, - no: { label: 'Cancel', action: async () => {} }, + content: t('notes_remove_confirm'), + yes: { label: t('remove'), action: remove }, + no: { label: t('cancel'), action: async () => {} }, error: true, }) } diff --git a/apps/Settings/api.js b/apps/Settings/api.js new file mode 100644 index 0000000..559486f --- /dev/null +++ b/apps/Settings/api.js @@ -0,0 +1,10 @@ +import fetchJson from 'helpers/fetchJson' + +export const saveSettings = async (data) => { + fetchJson('/api/settings', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data), + }) +} + diff --git a/apps/Settings/components/Settings.js b/apps/Settings/components/Settings.js index 2d7f238..c09a1bd 100644 --- a/apps/Settings/components/Settings.js +++ b/apps/Settings/components/Settings.js @@ -1,64 +1,64 @@ import styles from '../styles/Settings.module.scss' -import React, {useContext} from 'react' -import fetchJson from 'lib/fetchJson' -import useUser from 'lib/useUser' -import usePopup from 'hooks/usePopup' -import Context from 'context'; +import React from 'react' import {close} from 'helpers/windowActions' +import useUser from 'hooks/useUser' +import usePopup from 'hooks/usePopup' +import useSettings from 'hooks/useSettings' +import useApps from 'hooks/useApps' +import {saveSettings} from '../api' const Settings = () => { const {setPopup} = usePopup() - const {settings: {theme, language}, setSettings, setApps} = useContext(Context) + const {setApps} = useApps() + const {settings: {theme, language}, setSettings, t} = useSettings() const {user} = useUser() const handleSave = e => { e.preventDefault; - try { - fetchJson('/api/settings', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({_id: user._id, theme, language}), - }) + saveSettings({_id: user._id, theme, language}) + .then(() => { setPopup({ - content: 'Settings saved', + content: t('settings_saved'), time: 2000, }) close('Settings', setApps) - } catch (err) { + }) + .catch(() => { setpopup({ - content: 'could not save settings', + content: t('settings_save_error'), time: 2000, error: true, }) - } + }) } return ( <div className={styles.settings}> - <div>Language:</div> + <div>{t('language')}</div> <div> - <span className={styles.settings__active}>English</span> + {['en', 'pl', 'es', 'de'].map(l => ( + <span + key={l} + className={language === l ? styles.settings__langactive : ''} + onClick={()=>{setSettings(prev => ({...prev, language: l}))}} + >{l.toUpperCase()}</span> + ))} </div> - <div>Theme: </div> + <div>{t('color_theme')}</div> <div> - <span - onClick={()=>{setSettings({language, theme:'green'})}} - className={theme === 'green' ? styles.settings__active : ''} - /> - <span - onClick={()=>{setSettings({language, theme:'blue'})}} - className={theme === 'blue' ? styles.settings__active : ''} - /> - <span - onClick={()=>{setSettings({language, theme:'black'})}} - className={theme === 'black' ? styles.settings__active : ''} - /> + {['green', 'blue', 'black'].map(c => ( + <span + key={c} + onClick={()=>{setSettings(prev => ({...prev, theme: c}))}} + className={theme === c ? styles.settings__active : ''} + /> + ))} </div> <input type="button" className="window__button" - value="Save" + value={t('save')} onClick={handleSave} /> </div> diff --git a/apps/Settings/styles/Settings.module.scss b/apps/Settings/styles/Settings.module.scss index 9edef38..0944dcc 100644 --- a/apps/Settings/styles/Settings.module.scss +++ b/apps/Settings/styles/Settings.module.scss @@ -14,6 +14,24 @@ margin-top: .5em; } + &:nth-of-type(2) { + span { + padding: 0 .75em; + transition: .3s color; + display: inline-block; + color: var(--color-decor); + + &:hover { + color: #666; + } + } + + .settings__langactive { + color: var(--color-text); + font-weight: 600; + } + } + &:nth-of-type(3) { margin-top: 3em; } |