diff options
Diffstat (limited to 'templates.fnl')
| -rw-r--r-- | templates.fnl | 127 |
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>«Белая жаба»"]]] + [:h1 {} [:NO-ESCAPE "Чайный клуб<br>«Белая жаба»"]]] [: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 " год, ")]]) + "") + (if (not (lib.empty? product.volume)) + (HTML [:span {} [:NO-ESCAPE (.. product.volume " мл., ")]]) + "") + (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)) + "₽ за 50 грамм "]] + [:NO-ESCAPE "(" (lib.format-price product.price-per) + "₽ за 1 грамм)"]]))])) + +(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} |
