diff --git a/components/BookInfoInput.tsx b/components/BookInfoInput.tsx index 40cd543..2441d0e 100644 --- a/components/BookInfoInput.tsx +++ b/components/BookInfoInput.tsx @@ -6,15 +6,20 @@ const requiredFields = [ "title", ]; -const possibleFields = [ +const suggestedFields = [ + "author", +] + +const otherFields = [ "date", "description", "rights", "belongs-to-collection", - "author", "editor", "translator", -] +]; + +const possibleFields = [...suggestedFields, ...otherFields]; type Option = { value: string, @@ -28,8 +33,8 @@ const baseSettings = { function BookInfoInput({ handleSubmit }: { handleSubmit: (info: { frontmatter: Frontmatter, cover: File | undefined }) => void }) { const coverRef = useRef(null); - const [fieldsChosen, setFieldsChosen] = useState([]); - const [state, setState] = useState(Object.assign({}, ...requiredFields.map(f => ({ [f]: "" })))); + const [fieldsChosen, setFieldsChosen] = useState(suggestedFields); + const [state, setState] = useState({}); const fields = [...requiredFields, ...fieldsChosen]; const availableFields = possibleFields.filter(f => !fieldsChosen.includes(f)); const availableFieldsOptions = availableFields.map((f): Option => ({ @@ -71,15 +76,18 @@ function BookInfoInput({ handleSubmit }: { handleSubmit: (info: { frontmatter: F } function submit() { const cover = coverRef.current.files[0] as (File | undefined); + const frontmatter = { + ...state, + ...baseSettings, + }; + console.log({ frontmatter }); + return; handleSubmit({ - frontmatter: { - ...state, - ...baseSettings, - }, + frontmatter, cover, }); } - return
+ return
@@ -94,7 +102,7 @@ function BookInfoInput({ handleSubmit }: { handleSubmit: (info: { frontmatter: F } {field} - +
))}
add fields:
@@ -110,7 +118,7 @@ function BookInfoInput({ handleSubmit }: { handleSubmit: (info: { frontmatter: F options={availableFieldsOptions} /> - +
} diff --git a/components/DocReceiver.tsx b/components/DocReceiver.tsx index 6f049a1..24cd1a4 100644 --- a/components/DocReceiver.tsx +++ b/components/DocReceiver.tsx @@ -1,15 +1,24 @@ +import { useState } from "react"; import { useDropzone } from "react-dropzone"; import { uploadDoc } from "../lib/fetchers"; +const textFormats = [ + ".doc", ".docx", ".md", ".txt", "text/*", + "application/vnd.oasis.opendocument.text", ".odt", + "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".rtf" +] + function DocReceiver({ handleReceiveText }: { handleReceiveText: (content: string) => void, }) { + const [state, setState] = useState(""); function onDrop(files: File[]) { uploadDoc(files[0], { - start: () => null, - error: () => null, - progress: () => null, + error: () => setState("Error"), + progress: (p) => setState(p < 100 ? `Uploading ${p}%...` : "Processing..."), complete: (m: string) => { + setState(""); handleReceiveText(m); } }) @@ -17,11 +26,13 @@ function DocReceiver({ handleReceiveText }: { const {getRootProps, getInputProps, isDragActive} = useDropzone({ onDrop, multiple: false, - // accept: [".doc", ".docx", ".md", ".txt", "text/*", ""], + accept: textFormats, }); return
-
Add Text/Markdown File or Word Doc
+
+ {state ? state : "Drag file or click to add text file/document"} +
; } diff --git a/components/FormatGuideModal.tsx b/components/FormatGuideModal.tsx new file mode 100644 index 0000000..509d609 --- /dev/null +++ b/components/FormatGuideModal.tsx @@ -0,0 +1,52 @@ +import { Modal } from "react-bootstrap"; + +function FormatGuideModal(props: { + show: boolean, + onHide: () => void, +}) { + return ( + + + + 📖 Formatting Guide + + + +

+ You can format the text of the book using markdown. If you don't know how to use markdown you only need to know two things: +

+
    +
  1. To make a chapter heading put a # in front of the chapter title.
  2. +
  3. Leave an empty line between every paragraph.
  4. +
+

For example:

+ +
+ + + +
+ ); +} + +export default FormatGuideModal; \ No newline at end of file diff --git a/lib/fetchers.ts b/lib/fetchers.ts index 6563fa7..5d82168 100644 --- a/lib/fetchers.ts +++ b/lib/fetchers.ts @@ -11,10 +11,10 @@ export function bookRequest(req: { content: string, cover?: File, }, callback: { - start: (upload: { cancel: () => void }) => void, progress: (percentage: number) => void, error: () => void, -}) { + complete: () => void, +}): { cancel: () => void } { const formData = new FormData(); const xhr = new XMLHttpRequest(); xhr.responseType = "blob"; @@ -24,6 +24,7 @@ export function bookRequest(req: { formData.append("file", req.cover); } xhr.onload = () => { + callback.complete(); const url = window.URL.createObjectURL(xhr.response); const a = document.createElement('a'); a.href = url; @@ -45,15 +46,14 @@ export function bookRequest(req: { function cancel() { xhr.abort(); } - callback.start({ cancel }); + return { cancel }; } export function uploadDoc(file: File, callback: { - start: (upload: { cancel: () => void }) => void, progress: (percentage: number) => void, error: () => void, complete: (markdown: string) => void, -}) { +}): { cancel: () => void } { const formData = new FormData(); const xhr = new XMLHttpRequest(); formData.append("file", file); @@ -79,5 +79,5 @@ export function uploadDoc(file: File, callback: { function cancel() { xhr.abort(); } - callback.start({ cancel }); + return { cancel }; } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f861b3f..229c204 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "next": "12.0.10", "next-connect": "^0.12.1", "react": "17.0.2", + "react-bootstrap": "^2.1.2", "react-dom": "17.0.2", "react-dropzone": "^12.0.1", "react-select": "^5.2.2", @@ -391,6 +392,58 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz", + "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.0.tgz", + "integrity": "sha512-RxqQKmE8sO7TGdrcSlHTcVzMP450hqowtBSd2bBS9oPlcokVkaGq28c3Rwa8ty5ctw4EBCjXqjP7xdcKMGDzug==", + "dependencies": { + "@babel/runtime": "^7.6.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.5.tgz", + "integrity": "sha512-tLGtY0aHeIfT7aPwUkvQuhIy3+q3w4iqmUzFLPlOAf/vNUacLaBt1j/S//jv/dQhenRh8jvswyMojCwmLvJw8A==", + "dependencies": { + "dequal": "^2.0.2" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.0.1.tgz", + "integrity": "sha512-hLAqltcAjQYtjGuHBHKyPpR3ScTxzdkSYNvniwBfN7rUDbYiHu/UZiI1hvV2idJeUvktRnz29l7W9BnNLHrG6Q==", + "dependencies": { + "@babel/runtime": "^7.13.16", + "@popperjs/core": "^2.10.1", + "@react-aria/ssr": "^3.0.1", + "@restart/hooks": "^0.4.0", + "@types/warning": "^3.0.0", + "dequal": "^2.0.2", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", @@ -439,6 +492,11 @@ "@types/range-parser": "*" } }, + "node_modules/@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -516,6 +574,11 @@ "@types/node": "*" } }, + "node_modules/@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" + }, "node_modules/@typescript-eslint/parser": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", @@ -884,6 +947,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1025,6 +1093,14 @@ "node": ">= 0.4" } }, + "node_modules/dequal": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", + "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==", + "engines": { + "node": ">=6" + } + }, "node_modules/dicer": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", @@ -1911,6 +1987,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -2708,6 +2792,18 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2749,6 +2845,33 @@ "node": ">=0.10.0" } }, + "node_modules/react-bootstrap": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.1.2.tgz", + "integrity": "sha512-E7PR13cVsEW70gw08BWplENwn6PHTshskOsQygZqyc65jQlsnr9MsmuW/lgzAN2OiMBnc0KaNpuZ/FohL7dchw==", + "dependencies": { + "@babel/runtime": "^7.14.0", + "@restart/hooks": "^0.4.5", + "@restart/ui": "^1.0.1", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, "node_modules/react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -2783,6 +2906,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.2.tgz", @@ -3306,6 +3434,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3337,6 +3479,14 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3656,6 +3806,44 @@ "fastq": "^1.6.0" } }, + "@popperjs/core": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz", + "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==" + }, + "@react-aria/ssr": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.1.0.tgz", + "integrity": "sha512-RxqQKmE8sO7TGdrcSlHTcVzMP450hqowtBSd2bBS9oPlcokVkaGq28c3Rwa8ty5ctw4EBCjXqjP7xdcKMGDzug==", + "requires": { + "@babel/runtime": "^7.6.2" + } + }, + "@restart/hooks": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.5.tgz", + "integrity": "sha512-tLGtY0aHeIfT7aPwUkvQuhIy3+q3w4iqmUzFLPlOAf/vNUacLaBt1j/S//jv/dQhenRh8jvswyMojCwmLvJw8A==", + "requires": { + "dequal": "^2.0.2" + } + }, + "@restart/ui": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.0.1.tgz", + "integrity": "sha512-hLAqltcAjQYtjGuHBHKyPpR3ScTxzdkSYNvniwBfN7rUDbYiHu/UZiI1hvV2idJeUvktRnz29l7W9BnNLHrG6Q==", + "requires": { + "@babel/runtime": "^7.13.16", + "@popperjs/core": "^2.10.1", + "@react-aria/ssr": "^3.0.1", + "@restart/hooks": "^0.4.0", + "@types/warning": "^3.0.0", + "dequal": "^2.0.2", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "@rushstack/eslint-patch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz", @@ -3704,6 +3892,11 @@ "@types/range-parser": "*" } }, + "@types/invariant": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", + "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -3781,6 +3974,11 @@ "@types/node": "*" } }, + "@types/warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" + }, "@typescript-eslint/parser": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.11.0.tgz", @@ -4028,6 +4226,11 @@ "supports-color": "^7.1.0" } }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4146,6 +4349,11 @@ "object-keys": "^1.0.12" } }, + "dequal": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", + "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==" + }, "dicer": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", @@ -4835,6 +5043,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -5407,6 +5623,15 @@ "react-is": "^16.13.1" } }, + "prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "requires": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -5428,6 +5653,29 @@ "object-assign": "^4.1.1" } }, + "react-bootstrap": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.1.2.tgz", + "integrity": "sha512-E7PR13cVsEW70gw08BWplENwn6PHTshskOsQygZqyc65jQlsnr9MsmuW/lgzAN2OiMBnc0KaNpuZ/FohL7dchw==", + "requires": { + "@babel/runtime": "^7.14.0", + "@restart/hooks": "^0.4.5", + "@restart/ui": "^1.0.1", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": ">=16.14.8", + "@types/react-transition-group": "^4.4.1", + "@types/warning": "^3.0.0", + "classnames": "^2.3.1", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.1", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + } + }, "react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -5453,6 +5701,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "react-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.2.tgz", @@ -5819,6 +6072,17 @@ "which-boxed-primitive": "^1.0.2" } }, + "uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "requires": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5847,6 +6111,14 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 24618ef..7c72b05 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "next": "12.0.10", "next-connect": "^0.12.1", "react": "17.0.2", + "react-bootstrap": "^2.1.2", "react-dom": "17.0.2", "react-dropzone": "^12.0.1", "react-select": "^5.2.2", diff --git a/pages/index.tsx b/pages/index.tsx index 37d6caa..2c402f4 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,9 +1,10 @@ import type { NextPage } from "next"; -import { useRef } from "react"; +import { useState, useRef } from "react"; import Head from "next/head"; import BookInfoInput from "../components/BookInfoInput"; import DocReceiver from "../components/DocReceiver"; import { bookRequest } from "../lib/fetchers"; +import FormatGuideModal from "../components/FormatGuideModal"; // TODO: Make Title Required // TODO: Have author field in there @@ -12,6 +13,8 @@ import { bookRequest } from "../lib/fetchers"; const Home: NextPage = () => { const mdRef = useRef(null); + const [showFormatGuide, setShowFormatGuide] = useState(false); + const [submissionStatus, setSubmissionStatus] = useState(""); function handleReceiveText(m: string) { mdRef.current.value = m; } @@ -28,18 +31,18 @@ const Home: NextPage = () => { alert("Please enter a title for the book"); return; } + setSubmissionStatus(""); bookRequest({ ...info, content, }, { - // TODO: Implement progress display etc - start: () => null, - progress: () => null, - error: () => null, + complete: () => setSubmissionStatus("Done"), + progress: (p) => setSubmissionStatus(p < 100 ? `Uploading ${p}%...` : "Processing..."), + error: () => setSubmissionStatus("Error"), }); } return ( -
+
RTL EPUB Maker @@ -50,22 +53,41 @@ const Home: NextPage = () => {

RTL EPUB Maker 📚

-

Easily create EPUB e-book files with proper RTL support (🚧 in progress 👷)

-

Book Content

+

Easily create EPUB e-book files with proper RTL support

+

Book Content

- -