summaryrefslogtreecommitdiff
path: root/pages/shop
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2025-10-13 23:10:38 +0600
committerunwox <me@unwox.com>2025-10-13 23:48:17 +0600
commit7f6c204322aa13dd8a9760b311955fc4b9a92637 (patch)
tree0c1d66d123398dacc0851b1c1589a7e3730761f5 /pages/shop
parent5cf21fcb8c91896bb2b889dd4a90cc0b2ef3e9e5 (diff)
add simple filtering
Diffstat (limited to 'pages/shop')
-rw-r--r--pages/shop/_product/edit.fnl7
-rw-r--r--pages/shop/add.fnl5
-rw-r--r--pages/shop/index.fnl92
3 files changed, 78 insertions, 26 deletions
diff --git a/pages/shop/_product/edit.fnl b/pages/shop/_product/edit.fnl
index 3e4f2f0..3995096 100644
--- a/pages/shop/_product/edit.fnl
+++ b/pages/shop/_product/edit.fnl
@@ -2,6 +2,7 @@
(local templates (require :templates))
(local {: product-form} (require :pages.shop.add))
(local forms (require :forms))
+(local shop (require :shop))
(local lib (require :lib))
(fn find-product [db name]
@@ -69,8 +70,10 @@
authenticated?)))
(do
(lib.with-tx db
- (fn [tx] (update-product tx product-form data
- {:name request.params._product})))
+ (fn [tx]
+ (update-product tx product-form data
+ {:name request.params._product})
+ (shop.update-search-index tx)))
(values 302 {:Location (.. "/shop/" data.name)} ""))))
(values 200 {}
(templates.base
diff --git a/pages/shop/add.fnl b/pages/shop/add.fnl
index 01b83d6..460cc81 100644
--- a/pages/shop/add.fnl
+++ b/pages/shop/add.fnl
@@ -1,6 +1,7 @@
(import-macros {:compile-html HTML} :macros)
(local templates (require :templates))
(local dicts (require :dicts))
+(local shop (require :shop))
(local forms (require :forms))
(local lib (require :lib))
@@ -88,7 +89,9 @@
authenticated?)))
(do
(lib.with-tx db
- (fn [tx] (insert-product tx product-form request.form)))
+ (fn [tx]
+ (insert-product tx product-form request.form)
+ (shop.update-search-index tx)))
(values 302 {:Location "/shop"} ""))))
(values 200 {} (templates.base (content product-form {} {}
authenticated?))))))
diff --git a/pages/shop/index.fnl b/pages/shop/index.fnl
index da83114..29d93b6 100644
--- a/pages/shop/index.fnl
+++ b/pages/shop/index.fnl
@@ -4,11 +4,33 @@
(local dicts (require :dicts))
(local templates (require :templates))
-(fn all-products [db authenticated?]
+(fn all-products [db filters authenticated?]
+ (local where-stmts [])
+ (local where-args [])
+ (var has-search-query? false)
+
+ (when (not authenticated?)
+ (table.insert where-stmts "products.published = true"))
+
+ (when filters.type
+ (table.insert where-stmts "products.type = ?")
+ (table.insert where-args filters.type))
+
+ (when filters.search
+ (table.insert where-stmts "products_search MATCH ?")
+ (table.insert where-args filters.search)
+ (set has-search-query? true))
+
(local where
- (if (not authenticated?)
- "WHERE products.published = true"
+ (if (< 0 (# where-stmts))
+ (.. "WHERE " (table.concat where-stmts " AND\n"))
""))
+
+ (local from-sql
+ (if has-search-query?
+ "products_search INNER JOIN products ON products_search.name = products.name"
+ "products"))
+
(_G.must
(luna.db.query-assoc db
(..
@@ -27,9 +49,12 @@
products.image3,
products.image4,
products.image5
- FROM products "
+ FROM " from-sql " "
where
- " ORDER BY products.position") [])))
+ " ORDER BY products.position ASC,
+ products.creation_time DESC"
+ (if has-search-query? ", rank" ""))
+ where-args)))
(fn item-template [product basket]
(local item-url (.. "/shop/" product.name))
@@ -65,7 +90,7 @@
(templates.product-overview product "mb-0-25 font-size-0-875")
[:div {} product.short-description]]))
-(fn content [db basket authenticated?]
+(fn content [db products filters basket authenticated?]
[(HTML
[:aside {}
(templates.header "/shop" authenticated?)
@@ -77,25 +102,46 @@
[:div {:class "content"}
[:div {:class "back"} [:a {:href "/"} "⟵ Обратно на главную"]]
[:h2 {:class "product-page-title"} "Магазин"]
- (if authenticated?
- (HTML
- [:div {:class "mb-1" :style "margin-top: -0.5rem"}
- [:a {:style "white-space: nowrap"
- :href (.. "/shop/add")} "+ Добавить"]
- [:a {:style "white-space: nowrap; margin-left: 1rem;"
- :href (.. "/shop/order/list")} "☰ Список заказов"]])
- "")
- [:div {:class "shop-items"}
- (let [products (all-products db authenticated?)]
- (if (< 0 (# products))
- (table.concat
- (icollect [_ v (ipairs products)]
- (item-template v basket)))
- (HTML [:em {} "Пока что здесь ничего нет!"])))]])])
+ (if authenticated?
+ (HTML
+ [:div {:class "mb-1" :style "margin-top: -0.5rem"}
+ [:a {:style "white-space: nowrap"
+ :href (.. "/shop/add")} "+ Добавить"]
+ [:a {:style "white-space: nowrap; margin-left: 1rem;"
+ :href (.. "/shop/order/list")} "☰ Список заказов"]])
+ "")
+ [:form {:class "d-flex gap-0-5 mb-1"}
+ [:input {:name "search" :type "search"
+ :placeholder "Поиск" :value (or filters.search "")}]
+ [:select {:name "type"}
+ [:option {:value ""} "Все товары"]
+ (table.concat
+ (icollect [_ v (ipairs dicts.product-type)]
+ (HTML [:option (fn [] {:value v.value
+ :selected (= filters.type v.value)})
+ v.label])))]
+ [:button {:type "submit"} "Применить"]]
+ [:div {:class "shop-items"}
+ (if (< 0 (# products))
+ (table.concat
+ (icollect [_ v (ipairs products)]
+ (item-template v basket)))
+ (HTML [:em {} "Пока что здесь ничего нет!"]))]])])
(fn render [request db authenticated?]
(let [order-id (shop.order-id request)
- basket (if order-id (shop.basket db order-id) [])]
- (values 200 {} (templates.base (content db basket authenticated?)))))
+ basket (if order-id (shop.basket db order-id) [])
+ type (if (and request.query.type
+ (not (lib.empty? (. request.query.type 1))))
+ (. request.query.type 1)
+ nil)
+ search (if (and request.query.search
+ (not (lib.empty? (. request.query.search 1))))
+ (. request.query.search 1)
+ nil)
+ filters { : type : search }
+ products (all-products db filters authenticated?)]
+ (values 200 {} (templates.base
+ (content db products filters basket authenticated?)))))
{: render}