From b8384c87be81180d96bfb587309e8dd75d9babf8 Mon Sep 17 00:00:00 2001 From: Gosha Tcherednitchenko Date: Sun, 2 Feb 2025 07:43:33 +0000 Subject: [PATCH] feat(layouts): refactor layouts - Add a new fullscreen layout to use for main app rendering - Add helpers to render different scripts/styles per layout - Enable passing an option has to layouts that contains title, description, etc. --- src/main/parts/handlers/pages.clj | 95 ++++++++++++++++--------------- src/main/parts/views/layouts.clj | 30 ++++------ src/main/parts/views/partials.clj | 36 ++++++++++++ 3 files changed, 96 insertions(+), 65 deletions(-) diff --git a/src/main/parts/handlers/pages.clj b/src/main/parts/handlers/pages.clj index 4490251..83fa938 100644 --- a/src/main/parts/handlers/pages.clj +++ b/src/main/parts/handlers/pages.clj @@ -10,54 +10,55 @@ [_] (response/response (html - (layouts/main "System" - [:section.container - [:div.content - [:div [:h2 "System"]] - [:div#root]]])))) + (layouts/fullscreen + {:title "System" + :styles ["/css/flow.css"]} + [:section.container + [:div.content + [:div#root]]])))) (defn home-page "Page rendered for GET /" [_] - (-> (response/response - (html - (layouts/main - "Mapping tools for IFS practitioners and their clients" - [:section.container - [:div.content - [:section.hero - [:h1 - "Understand your clients’ parts and their relationships."]] - [:div.main - [:section.illustration - [:p - [:img {:src "/images/system-illustration.svg"}]]] - [:section.signup - [:h3.hook - [:strong "Parts"] - " is a mapping tool for IFS practitioners to keep track of, visualise, and explore the relationships between their clients’ parts."] - [:p - [:strong "Parts"] - " is being actively developed, and we would love to have your feedback! Please enter your email below to join the private beta test."] - (partials/waitlist-signup-form ".signup")]]]] - [:section.aboutus.container - [:div.content - [:h3 - "Who made this?"] - [:div.person-cards - [:div.person-card - [:img {:src "/images/avatars/gosha.svg"}] - [:p - [:strong "Gosha Tcherednitchenko"] - " is a software engineer with 20 years experience building for the Web." - [:br] - "Online: " - [:a {:href "https://gosha.net"} "Website"] - ", " - [:a {:href "https://bsky.app/profile/gosha.net"} "Bluesky"] - "."]] - [:div.person-card - [:img {:src "/images/avatars/tingyi.svg"}] - [:p - [:strong "Ting-yi Lai"] - " is an IFS Level 1 trained art psychotherapist, focusing on trauma."]]]]]))))) + (response/response + (html + (layouts/main + {:title "Mapping tools for IFS practitioners and their clients"} + [:section.container + [:div.content + [:section.hero + [:h1 + "Understand your clients’ parts and their relationships."]] + [:div.main + [:section.illustration + [:p + [:img {:src "/images/system-illustration.svg"}]]] + [:section.signup + [:h3.hook + [:strong "Parts"] + " is a mapping tool for IFS practitioners to keep track of, visualise, and explore the relationships between their clients’ parts."] + [:p + [:strong "Parts"] + " is being actively developed, and we would love to have your feedback! Please enter your email below to join the private beta test."] + (partials/waitlist-signup-form ".signup")]]]] + [:section.aboutus.container + [:div.content + [:h3 + "Who made this?"] + [:div.person-cards + [:div.person-card + [:img {:src "/images/avatars/gosha.svg"}] + [:p + [:strong "Gosha Tcherednitchenko"] + " is a software engineer with 20 years experience building for the Web." + [:br] + "Online: " + [:a {:href "https://gosha.net"} "Website"] + ", " + [:a {:href "https://bsky.app/profile/gosha.net"} "Bluesky"] + "."]] + [:div.person-card + [:img {:src "/images/avatars/tingyi.svg"}] + [:p + [:strong "Ting-yi Lai"] + " is an IFS Level 1 trained art psychotherapist, focusing on trauma."]]]]])))) diff --git a/src/main/parts/views/layouts.clj b/src/main/parts/views/layouts.clj index 6955cb7..c2b4430 100644 --- a/src/main/parts/views/layouts.clj +++ b/src/main/parts/views/layouts.clj @@ -5,26 +5,20 @@ (defn main "Fundamental application layout" - [title & content] + [options & content] (html - [:head - [:meta {:charset "utf-8"}] - [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}] - [:meta {:name "description" :content "Parts is a mapping tool for IFS practitioners to keep track of, visualise, and explore the relationships between their clients’ parts."}] - [:meta {:name "theme-color" :content "#62a294"}] - [:link {:rel "icon" :sizes "192x192" :href "/images/icons/favicon.png"}] - [:link {:rel "apple-touch-icon" :href "/images/icons/favicon.png"}] - [:title (str title " — Parts")] - [:link {:rel "stylesheet" :href "/css/style.css"}] - [:link {:rel "stylesheet" :href "/css/flow.css"}] - [:link {:rel "preconnect" :href "https://fonts.googleapis.com"}] - [:link {:rel "preconnect" :href "https://fonts.gstatic.com" :crossorigin true}] - [:link {:rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&display=swap"}] - [:script {:defer true - :data-domain "parts.ifs.tools" - :src "https://plausible.io/js/script.outbound-links.tagged-events.js"}]] + (partials/head options) [:body (partials/header) content (partials/footer) - [:script {:src "/js/main.js"}]])) + (partials/scripts options)])) + +(defn fullscreen + "Full-screen layout without header or footer" + [options & content] + (html + (partials/head options) + [:body + content + (partials/scripts options)])) diff --git a/src/main/parts/views/partials.clj b/src/main/parts/views/partials.clj index 9f1e437..68f5222 100644 --- a/src/main/parts/views/partials.clj +++ b/src/main/parts/views/partials.clj @@ -2,6 +2,42 @@ (:require [ring.middleware.anti-forgery :refer [*anti-forgery-token*]])) +(defn scripts + "Render script tags at the bottom of the main body tag. + Always includes main.js plus any additional scripts from options." + [{:keys [scripts]}] + (for [src (into ["/js/main.js"] (or scripts []))] + [:script {:src src}])) + +(defn head + "Head tag with configurable options. + Options map can include: + :title - page title + :description - meta description + :styles - additional stylesheets" + ([] (head {})) + ([{:keys [title description styles] + :or {description "Parts is a mapping tool for IFS practitioners to keep track of, visualise, and explore the relationships between their clients’ parts."}}] + [:head + [:meta {:charset "utf-8"}] + [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}] + [:meta {:name "description" :content description}] + [:meta {:name "theme-color" :content "#62a294"}] + [:link {:rel "icon" :sizes "192x192" :href "/images/icons/favicon.png"}] + [:link {:rel "apple-touch-icon" :href "/images/icons/favicon.png"}] + [:title (if title + (str title " — Parts") + "Parts")] + [:link {:rel "stylesheet" :href "/css/style.css"}] + [:link {:rel "preconnect" :href "https://fonts.googleapis.com"}] + [:link {:rel "preconnect" :href "https://fonts.gstatic.com" :crossorigin true}] + [:link {:rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&display=swap"}] + (for [href (or styles [])] + [:link {:rel "stylesheet" :href href}]) + [:script {:defer true + :data-domain "parts.ifs.tools" + :src "https://plausible.io/js/script.outbound-links.tagged-events.js"}]])) + (defn header "Site header" []