import * as React from 'react' import Head from 'next/head' import styled from 'styled-components' import Editor from '../components/Editor/Editor' import * as Storage from '../services/Storage' import generateId from '../utilities/Id' import Link from 'next/link' import { formatDate } from '../utilities/Date' import { useRouter } from 'next/router' import { XCircle } from 'react-feather' const Navbar = styled('aside')({ width: 360, height: '100%', position: 'fixed', top: 0, left: -360, backgroundColor: 'yellow', '@media (min-width: 1080px)': { width: `${100 / 3}%`, left: 0, }, }) const Main = styled('main')({ margin: '2rem 0', '@media (min-width: 1080px)': { paddingLeft: `${100 / 3}%`, boxSizing: 'border-box', }, }) const Container = styled('div')({ width: '100%', margin: '0 auto', padding: '0 1rem', boxSizing: 'border-box', '@media (min-width: 720px)': { maxWidth: 720, }, }) const NavbarContainer = styled('span')({ display: 'block', width: '100%', margin: '0 0 0 auto', padding: '0 1rem', boxSizing: 'border-box', maxWidth: 360, }) const TitleInput = styled('input')({ border: 0, background: 'transparent', padding: 0, display: 'block', width: '100%', font: 'inherit', fontSize: '3rem', fontWeight: 'bold', outline: 0, marginBottom: '2rem', }) const NoteLink = styled('a')({ display: 'flex', textDecoration: 'none', color: 'inherit', height: '4rem', alignItems: 'center', position: 'relative', }) const NoteLinkTitle = styled('strong')({ display: 'block', }) const LinkContainer = styled('div')({ position: 'relative', }) const NoteActions = styled('div')({ display: 'flex', position: 'absolute', alignItems: 'stretch', top: 0, right: 0, height: '100%', }) const NoteAction = styled('button')({ height: '100%', width: '4rem', background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', outline: 0, }) const NoteLinkBackground = styled('span')({ opacity: 0.125, backgroundColor: 'currentColor', top: 0, left: 0, width: '100%', height: '100%', position: 'absolute', }) type NoteInstance = { id: string, title: string, content?: object, updatedAt: string, } const Notes = ({ id: idProp }) => { const [id, setId, ] = React.useState(idProp) const [title, setTitle, ] = React.useState('') const [notes, setNotes, ] = React.useState(null) const [folders, setFolders, ] = React.useState(null) const stateRef = React.useRef({ id, title: '', updatedAt: new Date().toISOString(), }) const timeoutRef = React.useRef(null) const router = useRouter() const autoSave = () => { if (timeoutRef.current !== null) { window.clearTimeout(timeoutRef.current) } timeoutRef.current = window.setTimeout(async () => { const newNote = await Storage.saveNote({ ...stateRef.current, title, updatedAt: new Date().toISOString(), }) if (router.query.id !== id) { await router.push(`/notes/${id}`, undefined, { shallow: true }) } setNotes(oldNotes => { let notes if (oldNotes.some((a) => a.id === id)) { notes = oldNotes.map(n => n.id === id ? newNote : n) } else { notes = [newNote, ...oldNotes] } return notes.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)) }) timeoutRef.current = null }, 3000) } const handleEditorChange = e => { stateRef.current.content = e autoSave() } const handleTitleChange = e => { setTitle(e.target.value) autoSave() } React.useEffect(() => { const loadNotes = async () => { const theNotes = await Storage.loadNotes() setNotes(theNotes) } loadNotes() }, []) React.useEffect(() => { const loadFolders = async () => { const theFolders = await Storage.loadFolders() setFolders(theFolders) } loadFolders() }, []) React.useEffect(() => { if (!Array.isArray(notes!)) { return } const theNote = notes.find(n => n.id === id) stateRef.current = theNote ? theNote : { id, title: '', updatedAt: new Date().toISOString(), } setTitle(stateRef.current.title) }, [id, notes]) React.useEffect(() => { setId(idProp || generateId()) }, [idProp]) React.useEffect(() => { autoSave() }, [title]) return ( { idProp === undefined ? 'Notes | New Note' : `Notes | ${title.length > 0 ? title : '(untitled)'}`} New Note { Array.isArray(notes!) && notes.map(n => ( { n.id === id && ( ) } 0 ? 1 : 0.5, }} > {n.title.length > 0 ? n.title : '(untitled)'} {' '} )) }
{ Array.isArray(notes!) && ( ) }
) } export const getServerSideProps = async ctx => { if (ctx.params) { return { props: { id: ctx.params?.id } } } return { props: {} } } export default Notes