diff --git a/src/Roux/Html.hs b/src/Roux/Html.hs
index 67ee2b5..76a097d 100644
--- a/src/Roux/Html.hs
+++ b/src/Roux/Html.hs
@@ -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
diff --git a/src/Roux/Server.hs b/src/Roux/Server.hs
index 14acc2a..c52f42b 100644
--- a/src/Roux/Server.hs
+++ b/src/Roux/Server.hs
@@ -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