diff options
| author | unwox <me@unwox.com> | 2025-10-15 16:03:08 +0600 |
|---|---|---|
| committer | unwox <me@unwox.com> | 2025-10-15 16:15:47 +0600 |
| commit | b06fdc9c3b4b6dc0d5d60098303dd57d5c098e13 (patch) | |
| tree | 9ba4247d46b2a8b984a0893c5a13d1d03af51460 /pages/shop/index.fnl | |
| parent | 163773bdf237ba80a34a4a5366df826933f2cd8a (diff) | |
implement pagination
Diffstat (limited to 'pages/shop/index.fnl')
| -rw-r--r-- | pages/shop/index.fnl | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/pages/shop/index.fnl b/pages/shop/index.fnl index 58ff288..0d78b0a 100644 --- a/pages/shop/index.fnl +++ b/pages/shop/index.fnl @@ -5,12 +5,14 @@ (local templates (require :templates)) (local synonyms (require :synonyms)) -(fn all-products [db filters authenticated?] +(local pagination-limit 12) + +(fn all-products [db page filters] (local where-stmts []) (local where-args []) (var has-search-query? false) - (when (not authenticated?) + (when filters.only-published? (table.insert where-stmts "products.published = true")) (when filters.type @@ -35,8 +37,16 @@ "products_search INNER JOIN products ON products_search.name = products.name" "products")) - (_G.must - (luna.db.query-assoc db + {:total + (. (_G.must + (luna.db.query db + (.. "SELECT COUNT(products.ROWID) FROM " from-sql " " where) + where-args)) + 1 1) + + :products + (_G.must + (luna.db.query-assoc db (.. "SELECT products.name, products.title, @@ -57,10 +67,36 @@ where " ORDER BY products.position ASC, products.creation_time DESC" - (if has-search-query? ", rank" "")) - where-args))) + (if has-search-query? ", rank" "") + " LIMIT ? OFFSET ?") + (lib.concat where-args + [pagination-limit + (* (- page 1) pagination-limit)])))}) + +(fn filters-path [page filters] + (.. "/shop?page=" (tostring page) + (if filters.type (.. "&type=" filters.type) "") + (if filters.search (.. "&search=" filters.search) ""))) -(fn item-template [product basket] +(fn paginator-template [filters page limit total classes] + (if (< limit total) + (HTML + [:div {:class (.. "paginator " classes)} + (if (< 1 page) + (HTML + [:div {} + [:a {:href (filters-path (- page 1) filters)} + "⟵ Предыдущая страница"]]) + "") + (if (< page (math.ceil (/ total limit))) + (HTML + [:div {} + [:a {:href (filters-path (+ page 1) filters)} + "Следующая страница ⟶"]]) + "")]) + "")) + +(fn item-template [product basket redirect-url] (local item-url (.. "/shop/" product.name)) (local images []) (for [i 2 5] @@ -90,15 +126,17 @@ [:a {:href item-url} [:h3 {:class "shop-item-title"} product.title]] [:div {:class "shop-item-price"} - (templates.add-to-basket-form product basket "" "/shop")] + (templates.add-to-basket-form product basket "" redirect-url)] (templates.product-overview product "mb-0-25 font-size-0-875") [:div {} product.short-description]])) -(fn content [db products filters basket authenticated?] +(fn content [db products page total filters basket authenticated?] + (local redirect-url (filters-path page filters)) + [(HTML [:aside {} (templates.header "/shop" authenticated?) - (if (< 0 (# basket)) (templates.basket basket "/shop") "") + (if (< 0 (# basket)) (templates.basket basket redirect-url) "") ;; [:section {} [:h2 {} "Условия"] [:p {} ""]] ]) (HTML @@ -124,12 +162,14 @@ :selected (= filters.type v.value)}) v.label])))] [:button {:type "submit"} "Применить"]] + (paginator-template filters page pagination-limit total "mb-1") [:div {:class "shop-items"} (if (< 0 (# products)) (table.concat (icollect [_ v (ipairs products)] - (item-template v basket))) - (HTML [:em {} "Пока что здесь ничего нет!"]))]])]) + (item-template v basket redirect-url))) + (HTML [:em {} "Пока что здесь ничего нет!"]))] + (paginator-template filters page pagination-limit total "mt-2")])]) (fn render [request db authenticated?] (let [order-id (shop.order-id request) @@ -142,9 +182,15 @@ (not (lib.empty? (. request.query.search 1)))) (. request.query.search 1) nil) - filters { : type : search } - products (all-products db filters authenticated?)] + page (if (and request.query.page + (not (lib.empty? (. request.query.page 1)))) + (math.max 1 (tonumber (. request.query.page 1))) + 1) + only-published? (not authenticated?) + filters {: type : search : page : only-published?} + {: total : products} (all-products db page filters)] (values 200 {} (templates.base - (content db products filters basket authenticated?))))) + (content db products page total + filters basket authenticated?))))) {: render} |
