feat: add import form and result page templates

This commit is contained in:
2026-05-20 13:07:31 -04:00
parent e1c2a4bdc5
commit 4738972046
+42
View File
@@ -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