feat: expand import form with file upload via base64 JS
This commit is contained in:
+58
-3
@@ -546,6 +546,36 @@ indexPage _mode recipes =
|
||||
filterOk = filter (isRight . Idx.riRecipe)
|
||||
filterBad = filter (isLeft . Idx.riRecipe)
|
||||
|
||||
-- | Inline JavaScript for converting file uploads to base64 before form submission.
|
||||
fileUploadJs :: Text
|
||||
fileUploadJs =
|
||||
T.unlines
|
||||
[ "(function(){"
|
||||
, "'use strict';"
|
||||
, "var form = document.getElementById('import-form');"
|
||||
, "var fileInput = document.getElementById('file-input');"
|
||||
, "var b64Field = document.getElementById('file-b64');"
|
||||
, "var nameField = document.getElementById('file-name');"
|
||||
, "var mimeField = document.getElementById('file-mime');"
|
||||
, ""
|
||||
, "form.addEventListener('submit', function(e) {"
|
||||
, " if (fileInput.files.length > 0) {"
|
||||
, " e.preventDefault();"
|
||||
, " var file = fileInput.files[0];"
|
||||
, " var reader = new FileReader();"
|
||||
, " reader.onload = function() {"
|
||||
, " var b64 = reader.result.split(',')[1];"
|
||||
, " b64Field.value = b64;"
|
||||
, " nameField.value = file.name;"
|
||||
, " mimeField.value = file.type;"
|
||||
, " form.submit();"
|
||||
, " };"
|
||||
, " reader.readAsDataURL(file);"
|
||||
, " }"
|
||||
, "});"
|
||||
, "})();"
|
||||
]
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Import page (form + result)
|
||||
-- ---------------------------------------------------------------------------
|
||||
@@ -560,16 +590,41 @@ importPage merror =
|
||||
case merror of
|
||||
Just err -> H.p ! A.style "color: var(--roux-accent);" $ H.toHtml err
|
||||
Nothing -> pure ()
|
||||
H.form ! A.method "POST" ! A.action "/import" $ do
|
||||
H.p ! A.style "font-size: 0.85rem; opacity: 0.7; margin-bottom: 1.5rem;" $
|
||||
"Paste a recipe URL, upload a PDF or image, or paste recipe text directly."
|
||||
H.form ! A.method "POST" ! A.action "/import" ! A.id "import-form" $ do
|
||||
-- URL input
|
||||
H.label ! A.for "url" $ "Recipe URL"
|
||||
H.input
|
||||
! A.type_ "url"
|
||||
! A.id "url"
|
||||
! A.name "url"
|
||||
! A.placeholder "https://cooking.nytimes.com/recipes/..."
|
||||
! A.required ""
|
||||
! A.style "width: 100%; margin-bottom: 1rem;"
|
||||
! A.style "width: 100%; margin-bottom: 1.5rem;"
|
||||
-- File upload
|
||||
H.label ! A.for "file-input" $ "Or upload a PDF or image"
|
||||
H.input
|
||||
! A.type_ "file"
|
||||
! A.id "file-input"
|
||||
! A.accept ".pdf,image/*"
|
||||
! A.style "width: 100%; margin-bottom: 1.5rem;"
|
||||
-- Hidden fields for base64 file data (set by JS)
|
||||
H.input ! A.type_ "hidden" ! A.id "file-b64" ! A.name "file-b64" ! A.value ""
|
||||
H.input ! A.type_ "hidden" ! A.id "file-name" ! A.name "file-name" ! A.value ""
|
||||
H.input ! A.type_ "hidden" ! A.id "file-mime" ! A.name "file-mime" ! A.value ""
|
||||
-- Text area
|
||||
H.label ! A.for "text" $ "Or paste recipe text"
|
||||
H.textarea
|
||||
! A.id "text"
|
||||
! A.name "text"
|
||||
! A.rows "8"
|
||||
! A.placeholder "Paste recipe text here..."
|
||||
! A.style "width: 100%; margin-bottom: 1.5rem; font-family: monospace; font-size: 0.85rem;"
|
||||
$ ""
|
||||
-- Submit
|
||||
H.button ! A.type_ "submit" $ "Import Recipe"
|
||||
-- Inline JS for base64 file conversion
|
||||
H.script ! A.type_ "text/javascript" $ H.preEscapedText fileUploadJs
|
||||
|
||||
-- | Render the import result page with an error message.
|
||||
importResultPage :: ImportError -> ByteString
|
||||
|
||||
Reference in New Issue
Block a user