summaryrefslogtreecommitdiff
path: root/bin/serve.fnl
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2024-11-14 23:28:05 +0600
committerunwox <me@unwox.com>2024-11-14 23:45:28 +0600
commit5b13a916af68a8d7edb220b9b97911827b61d6e2 (patch)
tree0dbb516c3670077e36e54102d407d91ef8aaaf04 /bin/serve.fnl
parent9c7bfe06f4643c4875e3390aad324a84ebac4044 (diff)
add home page
Diffstat (limited to 'bin/serve.fnl')
-rw-r--r--bin/serve.fnl206
1 files changed, 115 insertions, 91 deletions
diff --git a/bin/serve.fnl b/bin/serve.fnl
index b1863e0..420100e 100644
--- a/bin/serve.fnl
+++ b/bin/serve.fnl
@@ -53,16 +53,6 @@
(str.trim (input:gsub "[=()<>']" "") " ")
nil))
-(fn category-menu-path [category]
- (. {"Красный чай" "red-tea"
- "Шен пуэр" "sheng-puer"
- "Шу пуэр" "shou-puer"
- "Улун" "oolong"
- "Зеленый чай" "green-tea"
- "Белый чай" "white-tea"
- "Желтый чай" "yellow-tea"
- "Посуда" "teaware"} category))
-
(fn query-string [query key]
(if (and query
(. query key)
@@ -85,10 +75,11 @@
(values k (array.join (map (fn [_ vv] (.. k "=" vv)) v) "&"))))
(array.join (array.list flattened-object) "&"))
-(fn collect-form [params category]
+(fn collect-form [params]
{:query (or (query-string params "query") "")
+ :page (or (query-number params "page") 1)
:tags (map #(sanitize-input $2)
- (filter #(~= "" $2) (or params.tags [category])))
+ (filter #(~= "" $2) (or params.tags [])))
:site (or (query-string params "site") "")
:sort (or (query-string params "sort") "")
:min-price (query-number params "min-price")
@@ -162,15 +153,15 @@
products.price,
products.weight,
products.price_per AS \"price-per\"
- FROM products
- INNER JOIN product_tags ON product_tags.product = products.url
- WHERE products.archived = false
- AND product_tags.tag IN ('Красный чай', 'Улун', 'Шен пуэр', 'Шу пуэр',
- 'Зеленый чай', 'Белый чай', 'Желтый чай')
- GROUP BY products.url
- ORDER BY ROW_NUMBER() over (PARTITION BY site ORDER BY products.ROWID)
- LIMIT ?
- OFFSET ?"
+ FROM products
+ INNER JOIN product_tags ON product_tags.product = products.url
+ WHERE products.archived = false
+ AND product_tags.tag IN ('Красный чай', 'Улун', 'Шен пуэр', 'Шу пуэр',
+ 'Зеленый чай', 'Белый чай', 'Желтый чай')
+ GROUP BY products.url
+ ORDER BY ROW_NUMBER() over (PARTITION BY site ORDER BY products.ROWID)
+ LIMIT ?
+ OFFSET ?"
[limit (% the-number (- total limit))])))
(fn all-tags []
@@ -184,6 +175,20 @@
ORDER BY creation_time"
[]))))
+(fn shops-count []
+ (# (must (luna.db.query db "SELECT DISTINCT site FROM products" []))))
+
+(fn products-count []
+ (. (must (luna.db.query db "SELECT DISTINCT COUNT(url) FROM products" []))
+ 1 1))
+
+(fn latest-update-date []
+ (. (must
+ (luna.db.query db
+ "SELECT creation_time FROM products ORDER BY creation_TIME DESC LIMIT 1"
+ []))
+ 1 1))
+
(fn query-products [{: query : tags : min-price : max-price : price-per : site : sort} page]
(local tags (or tags []))
@@ -376,7 +381,7 @@
(fn aside-template [form path paginator]
[:aside {:class "aside"}
[:div {:class "aside-content"}
- (if (not (form-empty? form))
+ (if (or (not (form-empty? form)) (~= path "/"))
[:a {:href "/" :style "display: block;"}
[:img {:class "logo" :src "/static/logo.svg"
:alt "Логотип everytea.ru" :title "Логотип everytea.ru"}]]
@@ -426,19 +431,24 @@
:selected (if (= form.sort "expensive-first") "selected" nil)}
"Сначала дороже"]]]
[:button {:type :submit} "Искать"]]
- paginator]])
-
-(fn base-template [form path page total items text]
- (local menu-path
- (if (and form.tags (< 0 (# form.tags)))
- (category-menu-path (. form.tags 1))
- nil))
- (local spellfix-suggestion
- (if (and (not (str.empty? form.query)) items (= 0 (# items)))
- (cache.wrap
- db (.. "spellfix:" form.query)
- #(spellfix.guess form.query))
- nil))
+ (if paginator "")]])
+
+(fn home-template []
+ [:div {}
+ [:article {:class "description"}
+ [:h1 {} "Добро пожаловать!"]
+ [:div {:class "description-text text"}
+ [:p {} [:NO-ESCAPE
+ (string.format texts.home-text
+ (shops-count)
+ (products-count)
+ (latest-update-date))]]]]
+ (comment [:section {}
+ [:h2 {} "Чаи дня"]
+ [:div {:class "list"}
+ (table.unpack (map #(item-template $2) (teas-of-the-day 10)))]])])
+
+(fn base-template [form path content aside-content]
[:html {:lang "ru-RU"}
[:head {}
[:meta {:charset "utf-8"}]
@@ -457,76 +467,90 @@
[:body {}
[:div {:class "container"}
[:div {:class "content"}
- (aside-template form path (paginator-template form page 48 total 7))
+ (aside-template form path aside-content)
[:main {}
(menu-template path)
- [:article {:class "description"}
- (if (. form.tags 1)
- [:h1 {} (. form.tags 1)]
- "")
- (if (and menu-path (. texts (.. menu-path "-description")))
- [:div {:class "description-text text"}
- [:NO-ESCAPE (. texts (.. menu-path "-description"))]]
- "")]
- (if text
- [:p {:class "text"} text]
- (< 0 (# items))
- [:div {:class "list"}
- (table.unpack (map #(item-template $2) items))]
- [:p {:class "text"}
- (if spellfix-suggestion
- [:NO-ESCAPE
- (string.format texts.no-results-with-suggestion
- spellfix-suggestion
- spellfix-suggestion)]
- [:NO-ESCAPE texts.no-results])])
- [:div {} (paginator-template form page 48 total 17)]
+ content
[:footer {}
[:small {:class "text"} [:NO-ESCAPE texts.footer-text]]]]]]]])
(fn root-handler [{: path : query}]
(local cache-key (.. "page:" path "?" (serialize-query query)))
(local cached (cache.get db cache-key))
+
+ (fn render-listing [form category]
+ (local headers {:content-type "text/html"})
+ (when category (table.insert form.tags category))
+
+ (local {: results : total} (query-products form form.page))
+ (local spellfix-suggestion
+ (if (and (not (str.empty? form.query)) results (= 0 (# results)))
+ (cache.wrap
+ db (.. "spellfix:" form.query)
+ #(spellfix.guess form.query))
+ nil))
+
+ (local description-key (.. (str.trim path "/") "-description"))
+ (local page
+ (base-template form path
+ [:div {}
+ (if (and (. form.tags 1) (. texts description-key))
+ [:article {:class "description"}
+ [:h1 {} (. form.tags 1)]
+ [:div {:class "description-text text"}
+ [:NO-ESCAPE (. texts description-key)]]]
+ "")
+ (if (< 0 (# results))
+ [:div {:class "list"}
+ (table.unpack (map #(item-template $2) results))]
+ [:p {:class "text"}
+ (if spellfix-suggestion
+ [:NO-ESCAPE
+ (string.format texts.no-results-with-suggestion
+ spellfix-suggestion
+ spellfix-suggestion)]
+ [:NO-ESCAPE texts.no-results])])
+ [:div {} (paginator-template form form.page 48 total 17)]]
+ ;; aside
+ (paginator-template form form.page 48 total 7)))
+
+ (values
+ 200 headers
+ (cache.set db cache-key
+ (.. "<!DOCTYPE html>\n" (html.render page true)))))
+
+ ;; TODO: if !dev && cached
(if cached
(values 200 {:content-type "text/html"} cached)
(do
- (fn respond [query category]
- (let [headers {:content-type "text/html"}
- page (or (query-number query "page") 1)
- form (collect-form query category)
- {: results : total}
- (if (not (form-empty? form))
- (query-products form page)
- {:total 10 :results (teas-of-the-day 10)})]
- (values
- 200 headers
- (cache.set db cache-key
- (.. "<!DOCTYPE html>\n"
- (html.render
- (base-template form path page total results)
- true))))))
-
- (match (str.split path "/")
- ["red-tea"] (respond query "Красный чай")
- ["sheng-puer"] (respond query "Шен пуэр")
- ["shou-puer"] (respond query "Шу пуэр")
- ["oolong"] (respond query "Улун")
- ["green-tea"] (respond query "Зеленый чай")
- ["white-tea"] (respond query "Белый чай")
- ["yellow-tea"] (respond query "Желтый чай")
- ["teaware"] (respond query "Посуда")
- (where t (= 0 (# t))) (respond query)
- _ (values
- 404 {:content-type "text/html"}
+ (local form (collect-form query))
+ (match (str.split path "/")
+ ["red-tea"] (render-listing form "Красный чай")
+ ["sheng-puer"] (render-listing form "Шен пуэр")
+ ["shou-puer"] (render-listing form "Шу пуэр")
+ ["oolong"] (render-listing form "Улун")
+ ["green-tea"] (render-listing form "Зеленый чай")
+ ["white-tea"] (render-listing form "Белый чай")
+ ["yellow-tea"] (render-listing form "Желтый чай")
+ ["teaware"] (render-listing form "Посуда")
+ (where t (= 0 (# t)))
+ (if (form-empty? form)
+ (values
+ 200 {:content-type "text/html"}
(.. "<!DOCTYPE html>\n"
- (html.render
- (base-template
- (collect-form query nil)
- "" 1 0 [] "Страница не найдена!")
- true)))))))
+ (html.render (base-template form path (home-template))
+ true)))
+ (render-listing form))
+ _ (values
+ 404 {:content-type "text/html"}
+ (.. "<!DOCTYPE html>\n"
+ (html.render
+ (base-template form path [:div {} "Страница не найдена!"])
+ true)))))))
(fn robots-handler []
- (values 200 {:content-type "text/plain"} "User-agent: *\nAllow: /"))
+ (values 200 {:content-type "text/plain"}
+ "User-agent: *\nAllow: /"))
(must (luna.router.route "GET /" root-handler))
(must (luna.router.route "GET /robots.txt" robots-handler))