From 7f6c204322aa13dd8a9760b311955fc4b9a92637 Mon Sep 17 00:00:00 2001 From: unwox Date: Mon, 13 Oct 2025 23:10:38 +0600 Subject: add simple filtering --- pages/shop/index.fnl | 92 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 23 deletions(-) (limited to 'pages/shop/index.fnl') 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} -- cgit v1.2.3