summaryrefslogtreecommitdiff
path: root/bin/serve.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'bin/serve.fnl')
-rw-r--r--bin/serve.fnl91
1 files changed, 63 insertions, 28 deletions
diff --git a/bin/serve.fnl b/bin/serve.fnl
index 5b08e55..884fb4f 100644
--- a/bin/serve.fnl
+++ b/bin/serve.fnl
@@ -83,20 +83,21 @@
{:query (str.trim (or (get-query-string params "query") ""))
:tags (filter #(~= "" $2) (or params.tags [category]))
:site (str.trim (or (get-query-string params "site") ""))
+ :sort (str.trim (or (get-query-string params "sort") ""))
:min-price (get-query-number params "min-price")
:max-price (get-query-number params "max-price")
:price-per (= "on" (get-query-string params "price-per"))})
(fn form-empty? [form]
(and
- (= "" form.query)
- (= (# form.tags) 0)
- (= "" form.site)
- (not form.min-price)
- (not form.max-price)
- ;; price-per is intentionally left out since it must not trigger search
- ;; by itself
- ))
+ (= "" form.query)
+ (= (# form.tags) 0)
+ (= "" form.site)
+ (not form.min-price)
+ (not form.max-price)
+ ;; price-per and sort are intentionally left out since they must not
+ ;; trigger search by itself
+ ))
(fn form->path [page form]
(.. "?page=" (tostring page)
@@ -122,6 +123,9 @@
"")
(if form.price-per
"&price-per=on"
+ "")
+ (if form.sort
+ (.. "&sort=" form.sort)
"")))
(fn teas-of-the-day [limit]
@@ -173,18 +177,20 @@
ORDER BY creation_time"
[]))))
-(fn query-products [{: query : tags : min-price : max-price : price-per : site} page]
+(fn query-products [{: query : tags : min-price : max-price : price-per : site : sort} page]
(local tags (or tags []))
(var where-conds [])
- (var where-vars [])
+ (var query-args [])
+
+ ;; create WHERE clause from dynamic form parameters
(when (< 0 (# tags))
(each [_ tag (pairs tags)]
(table.insert where-conds "product_tags.tag = ?")
- (table.insert where-vars tag)))
+ (table.insert query-args tag)))
(when (and query (< 0 (# query)))
(table.insert where-conds "search.title MATCH ?")
- (table.insert where-vars
+ (table.insert query-args
(array.join
(map (fn [_ q]
(local lower-q (must (luna.utf8.lower q)))
@@ -195,21 +201,40 @@
" AND ")))
(when (not (str.empty? site))
(table.insert where-conds "products.site = ?")
- (table.insert where-vars site))
+ (table.insert query-args site))
(when (and min-price (< 0 min-price))
(if price-per
(table.insert where-conds "products.price_per >= ?")
(table.insert where-conds "products.price >= ?"))
- (table.insert where-vars min-price))
+ (table.insert query-args min-price))
(when (and max-price (< 0 max-price))
(if price-per
(table.insert where-conds "products.price_per <= ?")
(table.insert where-conds "products.price <= ?"))
- (table.insert where-vars max-price))
-
+ (table.insert query-args max-price))
(local where-sql
(if (< 0 (# where-conds))
- (.. "AND " (array.join where-conds "\nAND "))
+ (.. "AND " (array.join where-conds "\nAND "))
+ ""))
+
+ ;; create SORT clause from dynamic form parameters
+ (var sort-criteria [])
+ (when sort
+ (if (= sort "cheap-first")
+ (table.insert sort-criteria
+ ;; multiple price by 100 if we only know a price for 1 gram
+ "CASE WHEN products.weight = 1 THEN products.price * 100
+ ELSE products.price
+ END ASC")
+ (= sort "expensive-first")
+ (table.insert sort-criteria
+ ;; multiple price by 100 if we only know a price for 1 gram
+ "CASE WHEN products.weight = 1 THEN products.price * 100
+ ELSE products.price
+ END DESC")))
+ (local sort-sql
+ (if (< 0 (# sort-criteria))
+ (.. (array.join sort-criteria ",\n") ",")
""))
(local total
@@ -227,7 +252,7 @@
AND products.archived = false
%s
GROUP BY products.url)" where-sql)
- where-vars)))
+ query-args)))
{:results
(must
@@ -249,10 +274,11 @@
AND products.archived = false
%s
GROUP BY products.url
- ORDER BY ROW_NUMBER() over (PARTITION BY products.site ORDER BY products.ROWID),
+ ORDER BY %s
+ ROW_NUMBER() over (PARTITION BY products.site ORDER BY products.ROWID),
rank
- LIMIT 48 OFFSET ?" where-sql)
- (array.concat where-vars [(* (- page 1) 48)])))
+ LIMIT 48 OFFSET ?" where-sql sort-sql)
+ (array.concat query-args [(* (- page 1) 48)])))
:total (if (< 0 (# total))
(. total 1 1)
0)})
@@ -366,6 +392,15 @@
:selected (if (= form.site val) "selected" nil)}
(. (require (.. "parser." val)) :title)])
[:ozchai :clubcha :ipuer :artoftea :chaekshop]))]]
+ [:div {}
+ [:select {:name "sort"}
+ [:option {:value ""} "~ Порядок ~"]
+ [:option {:value "cheap-first"
+ :selected (if (= form.sort "cheap-first") "selected" nil)}
+ "Сначала дешевле"]
+ [:option {:value "expensive-first"
+ :selected (if (= form.sort "expensive-first") "selected" nil)}
+ "Сначала дороже"]]]
[:button {:type :submit} "Искать"]]
paginator]])
@@ -414,13 +449,13 @@
(< 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])])
+ [: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]
[:footer {}
[:small {:class "text"} [:NO-ESCAPE texts.footer-text]]]]]]]])