diff --git a/src/Roux/Html.hs b/src/Roux/Html.hs
index c244d78..807ff76 100644
--- a/src/Roux/Html.hs
+++ b/src/Roux/Html.hs
@@ -658,11 +658,13 @@ cookLogJs =
, "var form = document.getElementById('roux-record-form');"
, "var dateInput = document.getElementById('roux-record-date');"
, "var commentInput = document.getElementById('roux-record-comment');"
+ , "var errorEl = document.getElementById('roux-record-error');"
, "if (!btn || !modal || !form) return;"
, ""
, "function showModal() {"
, " dateInput.value = new Date().toISOString().slice(0,10);"
, " commentInput.value = '';"
+ , " errorEl.style.display = 'none';"
, " modal.style.display = 'block';"
, " dateInput.focus();"
, "}"
@@ -681,20 +683,23 @@ cookLogJs =
, ""
, "form.addEventListener('submit', async function(e) {"
, " e.preventDefault();"
+ , " var date = dateInput.value;"
+ , " var comment = commentInput.value;"
, " var filename = btn.dataset.filename;"
- , " var fd = new FormData(form);"
+ , " var body = 'cooked-date=' + encodeURIComponent(date);"
+ , " if (comment) body += '&comment=' + encodeURIComponent(comment);"
, " var res = await fetch('/cook-log/' + encodeURIComponent(filename), {"
, " method: 'POST',"
- , " body: fd"
+ , " headers: { 'Content-Type': 'application/x-www-form-urlencoded' },"
+ , " body: body"
, " });"
, " if (!res.ok) {"
, " var err = await res.json();"
- , " alert(err.error || 'Failed to log cooking');"
+ , " errorEl.textContent = err.error || 'Failed to log cooking';"
+ , " errorEl.style.display = 'block';"
, " return;"
, " }"
, " hideModal();"
- , " var date = fd.get('cooked-date');"
- , " var comment = fd.get('comment');"
, " var entryDiv = document.createElement('div');"
, " entryDiv.style.margin = '0.3rem 0';"
, " entryDiv.style.fontSize = '0.9rem';"
@@ -983,6 +988,7 @@ renderRecipe filename recipe entries = do
H.input ! A.type_ "date" ! A.id "roux-record-date" ! A.name "cooked-date" ! A.required ""
H.label ! A.for "roux-record-comment" $ "Comment (optional)"
H.textarea ! A.id "roux-record-comment" ! A.name "comment" ! A.placeholder "How did it go?" ! A.maxlength "500" $ ""
+ H.p ! A.id "roux-record-error" ! A.style "color: var(--roux-accent); font-size: 0.8rem; margin: 0 0 0.5rem; display: none;" $ ""
H.div ! A.class_ "roux-modal-actions" $ do
H.button ! A.type_ "button" ! A.class_ "roux-modal-cancel" ! A.id "roux-modal-cancel" $ "Cancel"
H.button ! A.type_ "submit" ! A.class_ "roux-modal-confirm" $ "Log it"
diff --git a/src/Roux/Server.hs b/src/Roux/Server.hs
index 6ca2f1e..bf7e12b 100644
--- a/src/Roux/Server.hs
+++ b/src/Roux/Server.hs
@@ -26,7 +26,6 @@ import qualified Data.Map.Strict as Map
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
-import Data.Time.Clock (diffUTCTime, getCurrentTime)
import qualified Network.HTTP.Types as HTTP
import qualified Network.Wai as Wai
@@ -48,6 +47,7 @@ import qualified Data.ByteString as BS
import Data.Maybe (fromMaybe, mapMaybe)
import qualified Data.Text.Encoding as TE
import Data.Time.Calendar (Day, fromGregorianValid)
+import Data.Time.Clock (diffUTCTime, getCurrentTime, utctDay)
import qualified Data.Time.Format as Time
import qualified Database.SQLite.Simple as SQL
import Roux.Config (AnthropicConfig (..), RouxConfig (..))
@@ -672,22 +672,29 @@ handleCookLogPost db filename request respond = do
let params = parseFormBody body
dateStr = fromMaybe "" (lookup "cooked-date" params)
comment = lookup "comment" params
+ let doInsert d = do
+ _ <- CookLog.insertEntry db filename d comment
+ respond $
+ Wai.responseLBS
+ HTTP.status200
+ [("Content-Type", "application/json")]
+ (LB.fromStrict (encodeUtf8 "{\"ok\":true}"))
case parseDate dateStr of
- Just day -> do
- _ <- CookLog.insertEntry db filename day comment
- let resp =
- Wai.responseLBS
- HTTP.status200
- [("Content-Type", "application/json")]
- (LB.fromStrict (encodeUtf8 "{\"ok\":true}"))
- respond resp
+ Just d -> doInsert d
Nothing ->
- let resp =
- Wai.responseLBS
- HTTP.status400
- [("Content-Type", "application/json")]
- (LB.fromStrict (encodeUtf8 "{\"error\":\"Invalid date format\"}"))
- in respond resp
+ if T.null dateStr
+ then getCurrentDay >>= doInsert
+ else
+ let resp =
+ Wai.responseLBS
+ HTTP.status400
+ [("Content-Type", "application/json")]
+ (LB.fromStrict (encodeUtf8 "{\"error\":\"Invalid date format\"}"))
+ in respond resp
+
+-- | Get today's date.
+getCurrentDay :: IO Day
+getCurrentDay = utctDay <$> getCurrentTime
-- | Parse a YYYY-MM-DD date string.
parseDate :: Text -> Maybe Day