UI adjustments: Import link in header, matching font sizes, cook history titles, click-to-upload images

- Add Import link to all page headers (landing, recipe, cook history, import)
- Match ingredient list font size to recipe method text (both 15px)
- Show recipe titles instead of filenames on Cook History page
- Make clicking anywhere on recipe hero image/placeholder trigger file upload dialog
This commit is contained in:
2026-05-27 20:59:24 -04:00
parent 2124630146
commit 0eb6e6ea3c
2 changed files with 25 additions and 15 deletions
+20 -14
View File
@@ -811,8 +811,11 @@ importPage :: Maybe Text -> ByteString
importPage merror =
page "Roux \8212 Import Recipe" $ do
H.nav ! A.class_ "roux-navbar" $ do
H.ul $ H.li $ H.a ! A.href "/" $ "\8592 Back"
H.ul $ H.li $ H.strong "Import Recipe"
H.ul $ H.li $ H.a ! A.class_ "roux-logo" ! A.href "/" $ "Roux"
H.ul $ do
H.li $ H.a ! A.href "/recipes" $ "Recipes"
H.li $ H.a ! A.class_ "active" ! A.href "/import" $ "Import"
H.li $ H.a ! A.href "/cook-history" $ "Cook History"
case merror of
Just err -> H.p ! A.style "color: var(--roux-accent);" $ H.toHtml err
Nothing -> pure ()
@@ -922,8 +925,8 @@ recipePageStyles =
, ".rp-hero { width: 100%; aspect-ratio: 2.2; border-radius: 10px; background-size: cover; background-position: center; margin-bottom: 32px; position: relative; }"
, ".rp-hero-placeholder { background: linear-gradient(135deg, #E8B86A, #C9893F 50%, #8A5A2A); cursor: pointer; display: flex; align-items: center; justify-content: center; }"
, ".rp-hero-upload { font-size: 14px; color: rgba(61,44,30,0.4); }"
, ".rp-hero-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(61,44,30,0.6); color: #F5EFE0; font-size: 0.7rem; text-align: center; padding: 4px 0; cursor: pointer; opacity: 0; transition: opacity 0.15s; border-radius: 0 0 10px 10px; }"
, ".rp-hero:hover .rp-hero-overlay { opacity: 1; }"
, ".rp-hero-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(61,44,30,0.4); color: #F5EFE0; font-size: 14px; display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 0; transition: opacity 0.15s; border-radius: 10px; }"
, ".rp-hero-wrap:hover .rp-hero-overlay { opacity: 1; }"
, ".rp-hero-wrap { position: relative; margin-bottom: 32px; }"
, ".rp-hero-wrap .rp-hero { margin-bottom: 0; }"
, ""
@@ -939,7 +942,7 @@ recipePageStyles =
, ".rp-ingredient-row input[type=checkbox]:checked { border-color: rgba(61,44,30,0.5); }"
, ".rp-ingredient-row input[type=checkbox]:checked::after { content: '\x2713'; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); font-size: 11px; font-weight: 400; color: var(--roux-text); opacity: 0.5; line-height: 1; }"
, ".rp-ingredient-row .rp-qty { color: #8A7560; min-width: 48px; font-variant-numeric: tabular-nums; transition: opacity 0.15s; }"
, ".rp-ingredient-row .name { font-size: 0.9rem; line-height: 1.5; color: var(--roux-text); transition: opacity 0.15s; }"
, ".rp-ingredient-row .name { font-size: 15px; line-height: 1.5; color: var(--roux-text); transition: opacity 0.15s; }"
, ".rp-ingredient-row:has(input:checked) .rp-qty { opacity: 0.4; }"
, ".rp-ingredient-row:has(input:checked) .name { opacity: 0.4; text-decoration: line-through; }"
, ".rp-ing-section { font-size: 13px; font-weight: 500; color: #6B5847; margin: 16px 0 6px; letter-spacing: 0.03em; }"
@@ -975,6 +978,7 @@ renderRecipe filename recipe entries = do
H.a ! A.class_ "rp-logo" ! A.href "/" $ "ROUX"
H.div ! A.class_ "rp-nav-links" $ do
H.a ! A.href "/recipes" $ "Recipes"
H.a ! A.href "/import" $ "Import"
H.a ! A.href "/cook-history" $ "Cook History"
let meta = recipeMetadata recipe
course = metaCourse meta
@@ -1300,30 +1304,31 @@ isRight :: Either a b -> Bool
isRight = not . isLeft
-- | Render the cook history page (all entries across recipes).
cookHistoryPage :: [(Text, [CookLog.CookEntry])] -> ByteString
cookHistoryPage grouped =
cookHistoryPage :: (Text -> Text) -> [(Text, [CookLog.CookEntry])] -> ByteString
cookHistoryPage lookupTitle grouped =
page "Cook History" $ do
H.nav ! A.class_ "roux-navbar" $ do
H.ul $ H.li $ H.a ! A.class_ "roux-logo" ! A.href "/" $ "Roux"
H.ul $ do
H.li $ H.a ! A.href "/recipes" $ "Recipes"
H.li $ H.a ! A.href "/import" $ "Import"
H.li $ H.a ! A.class_ "active" ! A.href "/cook-history" $ "Cook History"
H.h1 "Cook History"
mapM_ renderMonthGroup grouped
mapM_ (renderMonthGroup lookupTitle) grouped
renderMonthGroup :: (Text, [CookLog.CookEntry]) -> Html
renderMonthGroup (month, entries) = do
renderMonthGroup :: (Text -> Text) -> (Text, [CookLog.CookEntry]) -> Html
renderMonthGroup lookupTitle (month, entries) = do
H.h2 $ H.toHtml month
H.ul ! A.style "list-style: none; padding: 0;" $ do
mapM_ renderHistoryEntry entries
mapM_ (renderHistoryEntry lookupTitle) entries
renderHistoryEntry :: CookLog.CookEntry -> Html
renderHistoryEntry entry = do
renderHistoryEntry :: (Text -> Text) -> CookLog.CookEntry -> Html
renderHistoryEntry lookupTitle entry = do
H.li ! A.style "margin-bottom: 0.5rem;" $ do
H.strong $ H.toHtml (formatDay (CookLog.ceCookedDate entry))
""
H.a ! A.href (H.toValue ("/recipes/" <> CookLog.ceRecipeFilename entry <> ".cook")) $
H.toHtml (CookLog.ceRecipeFilename entry)
H.toHtml (lookupTitle (CookLog.ceRecipeFilename entry))
unless (T.null (CookLog.ceComment entry)) $ do
H.br
H.span $ H.toHtml (CookLog.ceComment entry)
@@ -1417,6 +1422,7 @@ landingPage allRecipes recentlyCooked recentlyAdded =
H.div ! A.class_ "lnd-nav-links" $ do
H.a ! A.class_ "active" $ "Home"
H.a ! A.href "/recipes" $ "Recipes"
H.a ! A.href "/import" $ "Import"
H.a ! A.href "/cook-history" $ "Cook History"
-- Shuffle card
H.div ! A.class_ "lnd-shuffle" $ do
+5 -1
View File
@@ -667,7 +667,11 @@ handleRequest recipeDir state db request respond = do
["cook-history"] -> do
entries <- CookLog.fetchAllEntries db
let grouped = groupEntries entries
respond $ htmlResponse (Html.cookHistoryPage grouped)
recipeTitleLookup fn =
case Map.lookup (map toLower (stripCookExt (T.unpack fn))) recipes of
Just info -> Idx.riTitle info
Nothing -> fn
respond $ htmlResponse (Html.cookHistoryPage recipeTitleLookup grouped)
-- Cook log JSON endpoint for all entries
["cook-log"] -> do
entries <- CookLog.fetchAllEntries db