Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
work:
run-pty % just watch % just caddy

watch:
fd .janet | entr -r -s 'janet example/example.janet'

caddy:
caddy reverse-proxy -i -f office.localhost -t 127.0.0.1:8000

compose:
docker-compose -f example/compose.yaml up

Expand Down
38 changes: 0 additions & 38 deletions example/components.janet

This file was deleted.

7 changes: 0 additions & 7 deletions example/compose.yaml

This file was deleted.

37 changes: 0 additions & 37 deletions example/db.janet

This file was deleted.

105 changes: 67 additions & 38 deletions example/example.janet
Original file line number Diff line number Diff line change
@@ -1,50 +1,79 @@
(import pat)
(import redka)
(import spork/http)
(import ulid)
(import spork/htmlgen)

(import ./db)
(use ../src/server)
(import ../src :as datastar)
(use ../src/server)
(import ../src/attributes)
(import ../src/actions)
(import ../src/events)

(use module)

(def state {:items [{:name "Pencil"} {:name "Eraser"} {:name "Ruler"}]
:users [{:name "Admin"} {:name "Rok"}]
:sessions []
:carts []
:orders []})

# These two contain the HTTP handlers.
(import ./pages)
(import ./sse)
(defmodule- components
(defn heading [summary & breadcrumbs]
[:hgroup
[:h2
[:nav {:aria-label "breadcrumb" :style "--pico-nav-breadcrumb-divider: '|';"}
[:ul ;(map (fn [x] [:li (case (type x) :struct [:a {:href (get x :href)} (get x :txt)] (string x))]) breadcrumbs)]]] [:p summary]])
(defn article [& content] [:article ;content])
(defn catalogue [items]
[:div {:class "row-fluid"}
[:article {:class "col-12 col-md-4"}
[:fieldset
[:label "Filter by" [:select [:option "Name"]]]
[:label "Filter" [:input {:type "text" :placeholder "Filter"}]]
[:label "Order by" [:select [:option "Name"]]]]]
[:div {:class "col-12 col-md-8"}
;(map (fn [i] [:article (get i :name)]) items)]]))

(def redka-client (redka/make-client))
(db/seed redka-client)
(defn primary-layout [& content]
(htmlgen/html
[:html {:lang "en"}
[:head
[:meta {:charset "utf-8"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1"}]
[:meta {:name "color-scheme" :content "light dark"}]
[:link {:rel "stylesheet" :href "https://cdn.jsdelivr.net/npm/@yohns/[email protected]/css/pico.azure.min.css"}]
[:script {:type "module" :src "https://cdn.jsdelivr.net/gh/starfederation/[email protected]/bundles/datastar.js"}]
[:title "Office Shop"]]
[:body (struct :class "container" ;(attributes/signals {:search ""}))
[:header
[:nav
[:ul [:li [:a {:href "/items"} [:strong "Office Shop"]]]]
[:ul
[:li [:a {:href "/about"} "About"]]
[:li [:a {:href "/auth/sign-in" :role "button"} "Sign in"]]]]]
[:main
;content]]]))

(defn- req-to-patt [req]
{:route (string/split "/" (string/triml (get req :route) "/"))
:method (get req :method)})

(defn- session-cookie-mw
[nextmw]
(def cookie-name "cart-id")
(fn session-cookie-mw [req]
(if (get-in req [:cookies cookie-name] false)
(do
(nextmw req))
(do
(def cart-id (ulid/make))
(def new-cookies (table ;(kvs (get req :cookies @{}))))
(put new-cookies cookie-name cart-id)
(put req :cookies new-cookies)
(def ret (table ;(kvs (nextmw req))))
(def new-headers (table ;(kvs (get ret :headers @{}))))
# @TODO make these configurable
(put new-headers :set-cookie (string/format "%s=%s; HttpOnly; SameSite=Lax; Path=/; Domain=localhost; Max-Age=86400" cookie-name cart-id))
(put ret :headers new-headers)
ret))))

(server (http/cookies
(session-cookie-mw
(datastar/middleware
(fn [req]
(pat/match (req-to-patt req)
{:route [""] :method "GET"} {:status 307 :headers {:location "/items"}}
{:route ["about"] :method "GET"} (pages/about req)
{:route ["cart"] :method "GET"} (pages/cart req)
{:route ["items" id "add-to-cart"] :method "POST"} (sse/add-to-cart req id)
{:route ["items"] :method "GET"} (pages/items req redka-client)
_ {:status 404}))))))
(defmodule- handlers
(defn items []
{:status 200 :body (primary-layout (components/heading "Below you can find the items that we currently have in stock." "Items") (components/catalogue (get state :items)))})
(defn item [id] {:status 200 :body (primary-layout (components/heading "Below you can find the items that we currently have in stock." {:href "/items" :txt "Items"} id) (components/article))}))

(server
(http/cookies
(datastar/middleware
(fn [req]
(pat/match
(req-to-patt req)
{:route [""] :method "GET"} {:status 307 :headers {:location "/items"}}
{:route ["items"] :method "GET"} (handlers/items)
{:route ["items" id] :method "GET"} (handlers/item id)

{:route ["about"] :method "GET"} {:status 200 :body (primary-layout (components/heading "Hello" "About") (components/article "Hello"))}
{:route ["auth" "sign-in"] :method "GET"} {:status 200 :body (primary-layout (components/heading "Provide your credentials to sign in to your account." "Sign in") (components/article))}

_ {:status 404})))))
29 changes: 0 additions & 29 deletions example/layouts.janet

This file was deleted.

23 changes: 0 additions & 23 deletions example/pages.janet

This file was deleted.

41 changes: 0 additions & 41 deletions example/sse.janet

This file was deleted.

Loading