From ef6690c285c02174aec07a2b2a81ee3174fd519f Mon Sep 17 00:00:00 2001 From: SouthFox Date: Thu, 24 Aug 2023 21:52:14 +0800 Subject: [PATCH] [front/feat] add active style --- src/main/frontend/app.cljs | 133 +++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 43 deletions(-) diff --git a/src/main/frontend/app.cljs b/src/main/frontend/app.cljs index 1c9b738..4bffdf0 100644 --- a/src/main/frontend/app.cljs +++ b/src/main/frontend/app.cljs @@ -1,74 +1,121 @@ (ns frontend.app - (:require [reagent.core :as r] - [reagent.dom.client :as rdom] + (:require [reagent.dom.client :as rdom] [reitit.frontend :as rf] [reitit.frontend.easy :as rfe] + [reitit.frontend.controllers :as rfc] [spec-tools.data-spec :as ds] - )) - + [re-frame.core :refer [dispatch dispatch-sync reg-event-db clear-subscription-cache! reg-event-fx reg-sub + subscribe ]])) (defn home-page [] [:div :h2 "Home"] [:button {:type "button" - :on-click #(rfe/push-state ::item {:id 3})} - "Item 3"]) + :on-click #(rfe/push-state :item {:id 431038004})} + "Item 431038004"]) (defn about-page [] [:div [:h2 "About"] [:ul - [:li [:a {:href "stub"} "Source code"]]] + [:li [:a {:href "stub"} "Source code"]]]]) - ]) - -(defn item-page [match] - (let [{:keys [path query]} (:parameters match) - {:keys [id]} path] +(defn item-page [] + (let [current-route @(subscribe [::current-route]) + id (get-in current-route [:path-params :id])] [:div - [:h2 "Selected item " id] - (if (:foo query) - [:p "Optional foo query param: " (:foo query)])])) + [:h2 "Selected item " id]])) -(defonce match (r/atom nil)) - -(defn current-page [] - [:div {:class "container p-2 mx-auto"} - [:div {:class "flex flex-row flex-wrap py-4"} - [:div {:class "w-full sm:w-1/3 md:w-1/4 px-2"} - [:div {:class "sticky top-0 p-4 bg-slate-300 rounded-xl w-full"} - [:ul {:class "nav flex flex-col overflow-hidden"} - [:li [:a {:href (rfe/href ::frontpage)} "Home"]] - [:li [:a {:href (rfe/href ::about)} "About"]] - [:li [:a {:href (rfe/href ::item {:id 1})} "Item 1"]]]]] - (if @match - (let [view (:view (:data @match))] - [:div {:class "w-full sm:w-2/3 md:w-3/4 pt-1 px-2"} [view @match]]))]]) (def routes [["/" - {:name ::frontpage - :view home-page}] - ["/about" - {:name ::about - :view about-page}] - ["/item/:id" - {:name ::item - :view item-page - :parameters {:path {:id int?} - :query {(ds/opt :foo) keyword?}}}] - ]) + ["" + {:name :frontpage + :view home-page + :link-text "Home"}] + ["about" + {:name :about + :view about-page + :link-text "About"}] + ["item/:id" + {:name :item + :view item-page + :link-text "Item" + :parameters {:path {:id int?} + :query {(ds/opt :foo) keyword?}}}]]]) + +(def router + (rf/router + routes + )) + +(reg-event-db :initialize-db + (fn [_ _] + {:set-active-page nil})) + +(reg-event-fx + :set-active-page + (fn [{:keys [db]} [_ {:keys [page id]}]] + (let [set-page (assoc db :active-page page)] + (case page + ;; -- URL @ "/" -------------------------------------------------------- + "/" {:db set-page})))) + +(reg-sub ::current-route + (fn [db] + (:current-route db))) + +(reg-event-db ::navigated + (fn [db [_ new-match]] + (let [old-match (:current-route db) + controllers (rfc/apply-controllers (:controllers old-match) new-match)] + (assoc db :current-route (assoc new-match :controllers controllers))))) + + +(def history + #(dispatch [:set-active-page {:page (:path %) + :id (get-in % [:path-params :id])}])) + +(defn on-navigate [new-match] + (when new-match + (dispatch [::navigated new-match]))) + +(defn nav [{:keys [current-route]}] + (js/console.log current-route) + (let [active #(when (= % (-> current-route :data :name)) "> ")] + [:ul {:class "nav flex flex-col overflow-hidden"} + [:li + [:a {:href (rfe/href :frontpage)} (active :frontpage) "Home"]] + [:li + [:a {:href (rfe/href :about)} (active :about) "About"]] + [:li + [:a {:href (rfe/href :item {:id 233})} (active :item) "Item 233"]]])) + + +(defn current-page [] + (let [current-route @(subscribe [::current-route])] + [:div {:class "container p-2 mx-auto"} + [:div {:class "flex flex-row flex-wrap py-4"} + [:div {:class "w-full sm:w-1/3 md:w-1/4 px-2"} + [:div {:class "sticky top-0 p-4 bg-slate-300 rounded-xl w-full"} + [nav {:current-route current-route}]]] + (when current-route + [:div {:class "w-full sm:w-2/3 md:w-3/4 pt-1 px-2"} + [(-> current-route :data :view)]])]])) + (defonce root (rdom/create-root (js/document.getElementById "app"))) (defn ^:dev/after-load start [] - (rdom/render root [current-page] )) + (rdom/render root [current-page {:router router}] )) (defn init [] + (clear-subscription-cache!) + (dispatch-sync [:initialize-db]) (rfe/start! - (rf/router routes) - (fn [m] (reset! match m)) + router + on-navigate {:use-fragment true}) (js/console.log "init") (start))