diff options
| author | unwox <me@unwox.com> | 2025-10-03 11:56:37 +0600 |
|---|---|---|
| committer | unwox <me@unwox.com> | 2025-10-13 23:11:01 +0600 |
| commit | 3f5ade2e7a139bb4405437e8fc5546aafc7b05ef (patch) | |
| tree | 77c437958d74b591f11ec207d16749cf207a51e3 /pages/shop/index.fnl | |
| parent | f5a70e6a446e00969adb866ef2e2d10bf33bc4a8 (diff) | |
WIP shop
Diffstat (limited to 'pages/shop/index.fnl')
| -rw-r--r-- | pages/shop/index.fnl | 120 |
1 files changed, 27 insertions, 93 deletions
diff --git a/pages/shop/index.fnl b/pages/shop/index.fnl index bd3e88b..dff486c 100644 --- a/pages/shop/index.fnl +++ b/pages/shop/index.fnl @@ -1,5 +1,6 @@ (import-macros {:compile-html HTML} :macros) (local lib (require :lib)) +(local shop (require :shop)) (local dicts (require :dicts)) (local templates (require :templates)) @@ -17,8 +18,10 @@ products.short_description as \"short-description\", products.price_per AS \"price-per\", products.volume, + products.stock, products.packaging, products.type, + products.region, products.image1, products.image2, products.image3, @@ -28,27 +31,8 @@ where " ORDER BY products.position") []))) -(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) - (fn item-template [product] (local item-url (.. "/shop/" product.name)) - ;; (var quantity-options []) - ;; (if (< 0 product.stock) - ;; (each [_ q (ipairs (quantity-steps product.stock 50))] - ;; (table.insert quantity-options - ;; (HTML - ;; [:option {:value (tostring q)} - ;; (.. q " грамм за " (* product.price-per q) "₽")]))) - ;; (table.insert quantity-options (HTML [:option {:value "0"} "Товар закончился"]))) - (local images []) (for [i 2 5] (table.insert images (. product (.. "image" i)))) @@ -74,47 +58,33 @@ :style (.. "z-index: " (+ idx 2) ";" "width: calc(100% / " (# without-videos) ");" "left: calc(100% / " (# without-videos) " * " (- idx 1) ")")}]))))]] - [:a {:href item-url} [:h3 {:class "shop-item-title"} product.title]] - [:div {:style "font-style: italic; margin-bottom: 0.25rem;"} - (or (dicts.label dicts.product-type product.type) product.type) ", " - (if (not (lib.empty? product.volume)) - (HTML [:span {} [:NO-ESCAPE (.. product.volume " мл., ")]]) - "") - (if (= product.packaging "piece") - (HTML [:strong {} product.price-per "₽"]) - (HTML [:strong {} (* 50 product.price-per) "₽ за 50 гр. "]))] - ;; [:div {:class "shop-item-price"} - ;; [:form {:method "POST"} - ;; [:input {:type "hidden" :name "name" :value product.name}] - ;; [:select {:name "quantity"} (table.concat quantity-options)] - ;; [:button {:type "submit"} "Добавить"]]] + [:a {:href item-url} + [:h3 {:class "shop-item-title"} product.title]] + [:div {:class "shop-item-price"} + (templates.add-to-basket-form product "" "/shop")] + (templates.product-overview product "mb-0-25 font-size-0-875") [:div {} product.short-description]])) -(fn content [db basket basket-total authenticated?] +(fn content [db basket authenticated?] [(HTML - [:div {:class "side"} + [:aside {} (templates.header "/shop" authenticated?) - (if (< 0 (# basket)) - (HTML - [:article {:class "article"} - [:h2 {} "Корзина"] - [:div {} - (table.concat - (icollect [_ item (ipairs basket)] - (templates.basket-item item "/shop")))] - [:div {} "~~~"] - [:div {:class "basket-total"} (.. "Итого: " basket-total "₽")] - [:a {:href "/shop/order"} "Оформить заказ"]]) - "")]) + (if (< 0 (# basket)) (templates.basket basket "/shop") "") + [:section {} + [:h2 {} "Условия"] + [:p {} ""]]]) (HTML [:div {:class "content"} - [:div {:class "mb-1"} [:a {:href "/"} "⟵ Обратно на главную"]] - [:h2 {:class "product-page-title mb-1"} - "Магазин" - (if authenticated? - (HTML [:a {:style "font-size: 1rem; margin-left: 0.75rem;" - :href (.. "/shop/add")} "+ Добавить"]) - "")] + [: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)) @@ -123,45 +93,9 @@ (item-template v))) (HTML [:em {} "Пока что здесь ничего нет!"])))]])]) -(fn create-order [db] - (let [id (_G.must (luna.crypto.random-string 64))] - (_G.must - (luna.db.exec - db "INSERT INTO orders (id, creation_time) VALUES (?, ?)" - [id (lib.now)])) - id)) - -(fn create-order-line [db order-id name quantity] - (_G.must - (luna.db.exec - db - "INSERT INTO order_lines (order_id, product_name, quantity) VALUES (?, ?, ?)" - [order-id name quantity]))) - (fn render [request db authenticated?] - (let [order-id (lib.order-id request) - basket (if order-id (lib.basket db order-id) []) - basket-total (accumulate [sum 0 _ v (ipairs basket)] - (+ sum (* v.quantity v.price-per)))] - (if (= request.method "POST") - (do - (var order-id (lib.order-id request)) - (var headers - (if (not order-id) - (do - (set order-id (create-order db)) - {:Set-Cookie (.. "order= " order-id "; HttpOnly; SameSite=strict" - (if luna.debug? "" "; Secure"))}) - {})) - - (if (and order-id request.body) - (let [body-values (lib.parse-values request.body)] - (create-order-line db order-id body-values.name body-values.quantity) - (tset headers :Location "/shop") - (values 302 headers "")) - (values 400 {} "bad body"))) - (values - 200 {} - (templates.base (content db basket basket-total 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?))))) {: render} |
