summaryrefslogtreecommitdiff
path: root/templates.fnl
diff options
context:
space:
mode:
Diffstat (limited to 'templates.fnl')
-rw-r--r--templates.fnl127
1 files changed, 119 insertions, 8 deletions
diff --git a/templates.fnl b/templates.fnl
index d18770b..53b5c0c 100644
--- a/templates.fnl
+++ b/templates.fnl
@@ -1,5 +1,6 @@
(import-macros {:compile-html HTML} :macros)
(local lib (require :lib))
+(local dicts (require :dicts))
(fn read-file [file]
(with-open [f (io.open file "r")]
@@ -32,7 +33,7 @@
:alt "Белая жаба в мультяшном стиле с чайником на голове"}]))
(HTML
- [:article {:class "article"}
+ [:section {}
[:div {:class "logo"}
(if authenticated?
(HTML [:img {:class "logo-glasses" :src "/static/glasses.png"
@@ -41,7 +42,7 @@
(if (~= current-path "")
(HTML [:a {:href "/" :class "d-inline-block"} logo])
logo)
- [:h1 {} [:NO-ESCAPE "Чайная<br>«Белая&nbsp;жаба»"]]]
+ [:h1 {} [:NO-ESCAPE "Чайный&nbsp;клуб<br>«Белая&nbsp;жаба»"]]]
[:nav {}
[:a {:href "/shop" :class (if (lib.starts-with? current-path "/shop") "active" "")}
"магазин"]
@@ -51,19 +52,129 @@
[:a {:href "https://vk.com/whitetoadtea"} "вконтакте"]]]))
(fn basket-item [item redirect-url]
+ (local item-link (.. "/shop/" item.name))
+
(HTML
[:div {:class "basket-item"}
[:div {:class "basket-item-image"}
- [:img {:src (.. "/static/files/" (. item :images 1)) :alt item.title}]]
+ [:a {:href item-link :style "font-size: 0;"}
+ [:img {:src (.. "/static/files/" item.image1) :alt item.title}]]]
[:div {}
- [:strong {:class "basket-item-title"} item.title]
+ [:a {:href item-link :class "basket-item-title"} item.title]
[:div {:class "basket-item-price"}
- (.. item.quantity " грамм за "
- (* item.price-per item.quantity) "₽")
+ (if (= item.packaging :piece)
+ (.. (lib.format-price (* item.price-per item.quantity))
+ "₽ за " item.quantity " шт.")
+ (.. (lib.format-price (* item.price-per item.quantity))
+ "₽ за " item.quantity " гр."))
[:form {:class "basket-item-remove" :method "POST"
:action "/shop/cart/remove"}
[:input {:type "hidden" :name "redirect-url" :value redirect-url}]
[:input {:type "hidden" :name "id" :value (tostring item.id)}]
- [:button {:type "submit"} "⨯ убрать из корзины"]]]]]))
+ [:button {:type "submit"} "⨯ убрать"]]]]]))
+
+(fn basket [basket redirect-url]
+ (let [total (accumulate [sum 0 _ v (ipairs basket)]
+ (+ sum (* v.quantity v.price-per)))]
+ (HTML
+ [:section {}
+ [:h2 {} "Корзина"]
+ [:div {:class "mb-0-25"}
+ (table.concat
+ (icollect [_ item (ipairs basket)]
+ (basket-item item redirect-url)))]
+ [:div {:class "mt-0-25"} "—"]
+ [:div {} [:strong {} (.. "Итого: " (lib.format-price total) "₽")]]
+ [:a {:href "/shop/order"} "Оформить заказ ⟶"]])))
+
+(fn product-overview [product classes]
+ (local classes (or classes ""))
+
+ (HTML
+ [:div {:class classes :style "font-style: italic"}
+ (or (dicts.label dicts.product-type product.type) product.type) ", "
+ (if (not (lib.empty? product.year))
+ (HTML [:span {} [:NO-ESCAPE (.. product.year "&nbsp;год, ")]])
+ "")
+ (if (not (lib.empty? product.volume))
+ (HTML [:span {} [:NO-ESCAPE (.. product.volume "&nbsp;мл., ")]])
+ "")
+ (if (not (lib.empty? product.region)) (.. product.region ", ") "")
+ (if (= product.packaging "piece")
+ (HTML [:strong {} (lib.format-price product.price-per) "₽"])
+ (HTML [:span {}
+ [:strong {}
+ [:NO-ESCAPE
+ (lib.format-price (* 50 product.price-per))
+ "₽ за&nbsp;50&nbsp;грамм "]]
+ [:NO-ESCAPE "(" (lib.format-price product.price-per)
+ "₽ за&nbsp;1&nbsp;грамм)"]]))]))
+
+(fn add-to-basket-form [product classes redirect-url]
+ (fn quantity-steps [stock step]
+ (assert (< 0 step) "step must be greater than 0")
+ (var result [])
+ (var first (math.min stock step))
+ (while (<= first stock)
+ (table.insert result first)
+ (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"} "Добавить"]))]))
+
+(fn order-lines [order-lines]
+ (HTML
+ [:div {:class "order mb-0-5"}
+ (table.concat
+ (icollect [_ item (ipairs order-lines)]
+ (let [item-link (.. "/shop/" item.name)]
+ (HTML
+ [:div {:class "order-line"}
+ [:div {:class "order-line-image"}
+ [:a {:href item-link :style "font-size: 0;"}
+ [:img {:src (.. "/static/files/" item.image1)
+ :alt item.title}]]]
+ [:div {}
+ [:a {:href item-link :class "order-line-title"} item.title]
+ [:div {:class "order-line-price"}
+ (if (= item.packaging :piece)
+ (.. (lib.format-price (* item.price-per item.quantity))
+ "₽ за " item.quantity " шт.")
+ (.. (lib.format-price (* item.price-per item.quantity))
+ "₽ за " item.quantity " гр."))]
+ [:em {:class "font-size-0-875"}
+ (dicts.label dicts.product-type item.type)]]]))))]))
+
+(fn order-state [state]
+ (HTML [:strong
+ {:class (.. "order-state order-state-" state)}
+ (dicts.label dicts.order-state state)]))
-{: base : header : basket-item}
+{: base
+ : header
+ : basket-item
+ : basket
+ : product-overview
+ : add-to-basket-form
+ : order-lines
+ : order-state}