diff --git a/src/Roux/Html.hs b/src/Roux/Html.hs
index efd4e35..625fa48 100644
--- a/src/Roux/Html.hs
+++ b/src/Roux/Html.hs
@@ -9,6 +9,9 @@ so name-shadowing is unavoidable with local bindings.
-}
module Roux.Html (
SortMode (..),
+ ImportError (..),
+ importPage,
+ importResultPage,
indexPage,
recipePage,
urlEncode,
@@ -45,6 +48,10 @@ data SortMode
| CourseSort
deriving stock (Eq, Show)
+-- | Error type for the import pipeline.
+data ImportError = ImportError Text
+ deriving stock (Eq, Show)
+
-- ---------------------------------------------------------------------------
-- Helpers used throughout
-- ---------------------------------------------------------------------------
@@ -406,6 +413,41 @@ indexPage _mode recipes =
filterOk = filter (isRight . Idx.riRecipe)
filterBad = filter (isLeft . Idx.riRecipe)
+-- ---------------------------------------------------------------------------
+-- Import page (form + result)
+-- ---------------------------------------------------------------------------
+
+-- | Render the import form page, optionally with a validation error.
+importPage :: Maybe Text -> ByteString
+importPage merror =
+ page "Roux \8212 Import Recipe" $ do
+ H.div ! A.class_ "roux-navbar" $ do
+ H.ul $ H.li $ H.a ! A.href "/" $ "\8592 Back"
+ H.ul $ H.li $ H.strong "Import Recipe"
+ 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.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;"
+ H.button ! A.type_ "submit" $ "Import Recipe"
+
+-- | Render the import result page with an error message.
+importResultPage :: ImportError -> ByteString
+importResultPage (ImportError msg) =
+ page "Roux \8212 Import Error" $ do
+ H.div ! A.class_ "roux-navbar" $ do
+ H.ul $ H.li $ H.a ! A.href "/" $ "\8592 Back"
+ H.ul $ H.li $ H.a ! A.href "/import" $ "Try again"
+ H.h2 "Import failed"
+ H.p $ H.toHtml msg
+
recipePage :: Idx.RecipeInfo -> ByteString
recipePage info =
case Idx.riRecipe info of