summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2025-10-13 21:04:15 +0600
committerunwox <me@unwox.com>2025-10-13 23:11:20 +0600
commit5cf21fcb8c91896bb2b889dd4a90cc0b2ef3e9e5 (patch)
tree05826ed8beb78c736c94158ebe37d67063e38438
parenta7c25a5513e32669978b8e07fc9c61bd15cbdb02 (diff)
finishing touches for shop functionality
-rw-r--r--pages/shop/_product/index.fnl2
-rw-r--r--pages/shop/cart/add.fnl3
-rw-r--r--pages/shop/index.fnl6
-rw-r--r--pages/shop/order/index.fnl4
-rwxr-xr-xrun.sh1
-rw-r--r--shop.fnl16
-rw-r--r--templates.fnl54
7 files changed, 56 insertions, 30 deletions
diff --git a/pages/shop/_product/index.fnl b/pages/shop/_product/index.fnl
index f8b38f7..0dd5ff9 100644
--- a/pages/shop/_product/index.fnl
+++ b/pages/shop/_product/index.fnl
@@ -64,7 +64,7 @@
[:a {:href (.. "/shop/" product.name "/edit")}
"% Редактировать"]])
"")
- (templates.add-to-basket-form product "mb-0-5" redirect-url)
+ (templates.add-to-basket-form product basket "mb-0-5" redirect-url)
(templates.product-overview product "mb-0-5")
[:div {:class "mb-1" :style "font-style: italic;"}
diff --git a/pages/shop/cart/add.fnl b/pages/shop/cart/add.fnl
index 53366b4..b276608 100644
--- a/pages/shop/cart/add.fnl
+++ b/pages/shop/cart/add.fnl
@@ -19,7 +19,8 @@
(let [body-values (lib.parse-values request.body)]
(if (and order-id request.body
- (< 0 (tonumber body-values.quantity)))
+ (< 0 (tonumber body-values.quantity))
+ (not (shop.in-basket? db order-id body-values.name)))
(do
(shop.create-order-line
db order-id body-values.name body-values.quantity)
diff --git a/pages/shop/index.fnl b/pages/shop/index.fnl
index dff486c..da83114 100644
--- a/pages/shop/index.fnl
+++ b/pages/shop/index.fnl
@@ -31,7 +31,7 @@
where
" ORDER BY products.position") [])))
-(fn item-template [product]
+(fn item-template [product basket]
(local item-url (.. "/shop/" product.name))
(local images [])
(for [i 2 5]
@@ -61,7 +61,7 @@
[:a {:href item-url}
[:h3 {:class "shop-item-title"} product.title]]
[:div {:class "shop-item-price"}
- (templates.add-to-basket-form product "" "/shop")]
+ (templates.add-to-basket-form product basket "" "/shop")]
(templates.product-overview product "mb-0-25 font-size-0-875")
[:div {} product.short-description]]))
@@ -90,7 +90,7 @@
(if (< 0 (# products))
(table.concat
(icollect [_ v (ipairs products)]
- (item-template v)))
+ (item-template v basket)))
(HTML [:em {} "Пока что здесь ничего нет!"])))]])])
(fn render [request db authenticated?]
diff --git a/pages/shop/order/index.fnl b/pages/shop/order/index.fnl
index 7d25a40..019b61a 100644
--- a/pages/shop/order/index.fnl
+++ b/pages/shop/order/index.fnl
@@ -8,11 +8,11 @@
[{:title ""
:fields [
(forms.text-input "name" "Как к вам обращаться?" true)
- (forms.text-input "contact" "Телеграм или E-mail для связи" true)
+ (forms.text-input "contact" "Telegram, Whatsapp или E-mail для связи" true)
(forms.checkbox-input "correct-order" "Данные заказа верны" true)
(forms.checkbox-input "consent"
(..
- "Я даю согласие ИП «Горенкин Владислав Константинович» (ИНН ...)"
+ "Я даю согласие " ;; "ИП «Горенкин Владислав Константинович» (ИНН ...)")
" на хранение и обработку предоставленных персональных данных для уточнения деталей заказа.")
true)]}])
diff --git a/run.sh b/run.sh
index f8231b8..235fcd6 100755
--- a/run.sh
+++ b/run.sh
@@ -29,6 +29,7 @@ deploy () {
scp macros.fnl root@everytea.ru:~/whitetoad.ru/
scp dicts.fnl root@everytea.ru:~/whitetoad.ru/
scp templates.fnl root@everytea.ru:~/whitetoad.ru/
+ scp shop.fnl root@everytea.ru:~/whitetoad.ru/
ssh root@everytea.ru -- systemctl restart whitetoad
git stash pop
}
diff --git a/shop.fnl b/shop.fnl
index fea398e..9711095 100644
--- a/shop.fnl
+++ b/shop.fnl
@@ -111,6 +111,19 @@
ORDER BY order_lines.creation_time ASC"
[order-id])))
+(fn in-basket? [db order-id product-name]
+ (= 1
+ (#
+ (_G.must
+ (luna.db.query
+ db
+ "SELECT id
+ FROM order_lines
+ WHERE order_lines.order_id = ?
+ AND order_lines.product_name = ?
+ LIMIT 1"
+ [order-id product-name])))))
+
{: create-order
: place-order
: finish-order
@@ -118,4 +131,5 @@
: order-id
: create-order-line
: delete-order-line
- : basket}
+ : basket
+ : in-basket?}
diff --git a/templates.fnl b/templates.fnl
index 53b5c0c..b80576c 100644
--- a/templates.fnl
+++ b/templates.fnl
@@ -110,7 +110,7 @@
[:NO-ESCAPE "(" (lib.format-price product.price-per)
"₽ за&nbsp;1&nbsp;грамм)"]]))]))
-(fn add-to-basket-form [product classes redirect-url]
+(fn add-to-basket-form [product basket classes redirect-url]
(fn quantity-steps [stock step]
(assert (< 0 step) "step must be greater than 0")
(var result [])
@@ -120,27 +120,37 @@
(set first (+ first step)))
result)
- (var quantity-options [])
- (var no-stock? false)
- (let [piece? (= product.packaging :piece)]
- (if (< 0 product.stock)
- (each [_ q (ipairs (quantity-steps product.stock (if piece? 1 50)))]
- (table.insert
- quantity-options
- (HTML
- [:option {:value (tostring q)}
- (.. (lib.format-price (* product.price-per q))
- "₽ за " q (if piece? " шт." " гр."))])))
- (do
- (table.insert quantity-options (HTML [:option {:value "0"} "Товар закончился"]))
- (set no-stock? true))))
-
- (HTML
- [:form {:method "POST" :action "/shop/cart/add" :class classes}
- [:input {:type "hidden" :name "name" :value product.name}]
- [:input {:type "hidden" :name "redirect-url" :value redirect-url}]
- [:select {:name "quantity"} (table.concat quantity-options)]
- (if no-stock? "" (HTML [:button {:type "submit"} "Добавить"]))]))
+ (var in-basket-quantity nil)
+ (each [_ basket-item (pairs basket) &until in-basket-quantity]
+ (when (= product.name basket-item.name)
+ (set in-basket-quantity basket-item.quantity)))
+
+ (var quantity-options [])
+ (var out-of-stock? false)
+ (let [piece? (= product.packaging :piece)]
+ (if (< 0 product.stock)
+ (each [_ q (ipairs (quantity-steps product.stock (if piece? 1 50)))]
+ (table.insert
+ quantity-options
+ (HTML
+ [:option (fn [] {:value q
+ :selected (= in-basket-quantity q)})
+ (.. (lib.format-price (* product.price-per q))
+ "₽ за " q (if piece? " шт." " гр."))])))
+ (do
+ (table.insert quantity-options (HTML [:option {:value "0"} "Товар закончился"]))
+ (set out-of-stock? true))))
+
+ (local disabled (or out-of-stock? in-basket-quantity))
+
+ (HTML
+ [:form {:method "POST" :action "/shop/cart/add" :class classes}
+ [:input {:type "hidden" :name "name" :value product.name}]
+ [:input {:type "hidden" :name "redirect-url" :value redirect-url}]
+ [:select (fn [] {:name "quantity" :disabled disabled})
+ (table.concat quantity-options)]
+ [:button (fn [] {:type "submit" :disabled disabled})
+ (if in-basket-quantity "В корзине" "Добавить")]]))
(fn order-lines [order-lines]
(HTML