diff --git a/resources/public/cards.html b/resources/public/cards.html new file mode 100644 index 0000000..4da97a1 --- /dev/null +++ b/resources/public/cards.html @@ -0,0 +1,13 @@ + + +
+ + + + + + + + + + diff --git a/resources/public/img/logo.svg b/resources/public/img/logo.svg new file mode 100644 index 0000000..7c3d1af --- /dev/null +++ b/resources/public/img/logo.svg @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/src/cljs/commiteth/core.cljs b/src/cljs/commiteth/core.cljs index e9709c2..53fa2bf 100644 --- a/src/cljs/commiteth/core.cljs +++ b/src/cljs/commiteth/core.cljs @@ -14,6 +14,7 @@ [commiteth.common :refer [input checkbox]] [commiteth.subscriptions :refer [user-address-path]] [commiteth.config :as config] + [commiteth.svg :as svg] [clojure.set :refer [rename-keys]] [re-frisk.core :refer [enable-re-frisk!]]) (:import goog.History)) @@ -63,22 +64,7 @@ :size 55 :type "text" :value-path user-address-path})] - [:svg.octicon.octicon-broadcast - {:aria-hidden "true", - :height "16", - :version "1.1", - :viewBox "0 0 16 16", - :width "16"} - [:path - {:d "M9 9H8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H7c-.55 - 0-1 .45-1 1v1c0 .55.45 1 1 1H6c-.55 0-1 .45-1 - 1v2h1v3c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-3h1v-2c0-.55-.45-1-1-1zM7 - 7h1v1H7V7zm2 4H8v4H7v-4H6v-1h3v1zm2.09-3.5c0-1.98-1.61-3.59-3.59-3.59A3.593 - 3.593 0 0 0 4 8.31v1.98c-.61-.77-1-1.73-1-2.8 0-2.48 2.02-4.5 - 4.5-4.5S12 5.01 12 7.49c0 1.06-.39 2.03-1 2.8V8.31c.06-.27.09-.53.09-.81zm3.91 - 0c0 2.88-1.63 5.38-4 6.63v-1.05a6.553 6.553 0 0 0 3.09-5.58A6.59 6.59 0 0 0 - 7.5.91 6.59 6.59 0 0 0 .91 7.5c0 2.36 1.23 4.42 3.09 5.58v1.05A7.497 - 7.497 0 0 1 7.5 0C11.64 0 15 3.36 15 7.5z"}]]]]]))) + [svg/octicon-broadcast]]]]))) (defn header [] (let [page (rf/subscribe [:page]) @@ -87,14 +73,17 @@ [:header.main-header [:div.container [:div.flex-table.mt-4.mb-4 - [:a - {:href "/"} - [:img {:src "img/logo.png", :alt "commiteth", :width "100"}]] + [:header.logo] + [:a {:href "/"} + [:img {:src "/img/logo.svg"} + + ;;[:img {:src "img/logo.png", :alt "commiteth", :width "100"}] + ]] [:div.flex-table-item.flex-table-item-primary [:a {:href "/"}] [:h1.main-title.lh-condensed "commiteth"] [:span.main-link - "earn ETH for commits"]] + "Earn ETH by committing to open source projects"]] [:div.flex-table-item.flex-table-item-primary [login-link]]] [:div.tabnav @@ -103,28 +92,12 @@ [:a.tabnav-tab {:href "#" :class (when (= :issues @page) "selected")} - [:svg.octicon.octicon-repo - {:aria-hidden "true", - :height "16", - :version "1.1", - :viewBox "0 0 12 16", - :width "12"} - [:path - {:d - "M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"}]] + [svg/octicon-repo] "Open Bounties"] (when @user [:a.tabnav-tab {:href "#/manage" :class (when (= :manage @page) "selected")} - [:svg.octicon.octicon-organization - {:aria-hidden "true", - :height "16", - :version "1.1", - :viewBox "0 0 16 16", - :width "16"} - [:path - {:d - "M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4"}]] + [svg/octicon-organization] "Manage Transactions"])]]]]))) (def pages @@ -139,8 +112,6 @@ [error-pane] [(pages @(rf/subscribe [:page]))]])) -;; ------------------------- -;; Routes (secretary/set-config! :prefix "#") (secretary/defroute "/" [] @@ -151,9 +122,6 @@ (rf/dispatch [:set-active-page :manage]) (secretary/dispatch! "/"))) -;; ------------------------- -;; History -;; must be called after routes have been defined (defn hook-browser-navigation! [] (doto (History.) (events/listen @@ -162,8 +130,6 @@ (secretary/dispatch! (.-token event)))) (.setEnabled true))) -;; ------------------------- -;; Initialize app (defn mount-components [] (r/render [#'page] (.getElementById js/document "app"))) diff --git a/src/cljs/commiteth/svg.cljs b/src/cljs/commiteth/svg.cljs new file mode 100644 index 0000000..6305d66 --- /dev/null +++ b/src/cljs/commiteth/svg.cljs @@ -0,0 +1,41 @@ +(ns .commiteth.svg) + +(defn octicon-broadcast [] + [:svg.octicon.octicon-broadcast + {:aria-hidden "true", + :height "16", + :version "1.1", + :viewBox "0 0 16 16", + :width "16"} + [:path + {:d "M9 9H8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H7c-.55 + 0-1 .45-1 1v1c0 .55.45 1 1 1H6c-.55 0-1 .45-1 + 1v2h1v3c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-3h1v-2c0-.55-.45-1-1-1zM7 + 7h1v1H7V7zm2 4H8v4H7v-4H6v-1h3v1zm2.09-3.5c0-1.98-1.61-3.59-3.59-3.59A3.593 + 3.593 0 0 0 4 8.31v1.98c-.61-.77-1-1.73-1-2.8 0-2.48 2.02-4.5 + 4.5-4.5S12 5.01 12 7.49c0 1.06-.39 2.03-1 2.8V8.31c.06-.27.09-.53.09-.81zm3.91 + 0c0 2.88-1.63 5.38-4 6.63v-1.05a6.553 6.553 0 0 0 3.09-5.58A6.59 6.59 0 0 0 + 7.5.91 6.59 6.59 0 0 0 .91 7.5c0 2.36 1.23 4.42 3.09 5.58v1.05A7.497 + 7.497 0 0 1 7.5 0C11.64 0 15 3.36 15 7.5z"}]]) + +(defn octicon-repo [] + [:svg.octicon.octicon-repo + {:aria-hidden "true", + :height "16", + :version "1.1", + :viewBox "0 0 12 16", + :width "12"} + [:path + {:d + "M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"}]]) + +(defn octicon-organization [] + [:svg.octicon.octicon-organization + {:aria-hidden "true", + :height "16", + :version "1.1", + :viewBox "0 0 16 16", + :width "16"} + [:path + {:d + "M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4"}]]) diff --git a/test/cljs/commiteth/cards.cljs b/test/cljs/commiteth/cards.cljs new file mode 100644 index 0000000..d0c2c8c --- /dev/null +++ b/test/cljs/commiteth/cards.cljs @@ -0,0 +1,162 @@ +(ns commiteth.cards + (:require [reagent.core :as r] + [devcards.core] + [commiteth.core-test] + [cljs.test :refer-macros [is testing]] + [devcards.core :refer-macros [defcard-rg + deftest + start-devcard-ui!]])) + + +(enable-console-print!) + + +(def app-state (r/atom {:repo-state :disabled + :active-tab :activity})) + + +(deftest tests-can-be-done-here + (is (= 0 0))) + +(defn fake-toggle-action [app-state] + (let [repo-state (:repo-state @app-state)] + (when-not (= repo-state :busy) + (swap! app-state assoc :repo-state :busy) + (let [to-state (if (= repo-state :enabled) + :disabled + :enabled)] + (.setTimeout js/window + #(swap! app-state assoc :repo-state to-state) + 1000))))) + + +(defn repo-toggle-button [button-state on-click] + (case button-state + :enabled [:div.ui.two.column.container + [:div.ui.button.small.repo-added-button + [:i.icon.check] + "Added"] + [:a.ui.item.remove-link {:on-click on-click} "Remove"]] + :disabled [:div.ui.button.small {:on-click on-click} "Add"] + :busy [:div.ui.button.small.disabled.loading "Busy..."])) + +(defn repo-dynamic [state-ratom] + [:div.ui.card + [:div.content + [:div.repo-label "here-be-dragons"] + [:div.repo-description "Here is a description for the repository."] + [:div.ui.floated.center + [repo-toggle-button + (:repo-state @app-state) + #(fake-toggle-action app-state)]]]]) + +(defcard-rg repo-card-dynamic + [repo-dynamic app-state] + app-state) + + +(defn top-hunters-dynamic [state-ratom] + [:div "TODO"]) + + +(defn activate-tab! [tab] + (swap! app-state assoc :active-tab tab)) + +(defn tabs [app-state] + (let [active-tab (:active-tab app-state)] + [:div.ui.attached.tabular.menu.tiny + (for [[tab caption] [[:activity "Activity"] + [:manage "Repositories"] + [:bounties "Bounties"]]] + (let [props {:class (str "ui item" + (when (= active-tab tab) " active")) + :on-click #(activate-tab! tab)}] + ^{:key tab} [:div props caption]))])) + + +(defn page-header-dynamic [state-ratom] + [:div.ui.grid.container.commiteth-header + [:div.ui.grid.four.column.container + [:div.column + [:img {:src "/img/logo.svg"}]] + ^{:key 1} [:div.column] + ^{:key 2} [:div.column] + [:div.column + [:div.ui.button.tiny "Sign in"]]] + [:div.ui.text.content.justified + [:div.ui.divider.hidden] + [:h2.ui.header "Commit ETH"] + [:h3.ui.subheader "Earn ETH by committing to open source projects"] + [:div.ui.divider.hidden]] + [tabs @state-ratom]]) + +(defcard-rg page-header + [page-header-dynamic app-state] + app-state + {}) + +#_{:activity-item {:type :bounty-created + :issue-id 1 + :foo 42}} + +(defcard-rg feeditem-bounty-created + "An activity feed item with a bounty-created event" + [:div.ui.segment + [:div.ui.grid + [:div.six.column.row + [:div.column + [:img.ui.tiny.circular.image {:src "https://randomuser.me/api/portraits/men/4.jpg"}]] + [:div.five.wide.column + [:div.ui.grid + [:div.row + [:h3 "Random User"]] + [:div.row + [:div.content + "ETH 15 bounty for " [:a {:href "#"} "Fix crash"]]] + [:div.row + [:div.ui.label.tiny "ETH 15"] + [:div.time "2h ago"]]]]]]]) + + +(defcard-rg feeditem-claim-submitted + "An activity feed item with a claim event" + [:div.ui.segment + [:div.ui.grid + [:div.six.column.row + [:div.column + [:img.ui.tiny.circular.image {:src "https://randomuser.me/api/portraits/men/5.jpg"}]] + [:div.five.wide.column + [:div.ui.grid + [:div.row + [:h3 "Pseudo-random User"]] + [:div.row + [:div.content + "Submitted a claim for " [:a {:href "#"} "Fix crash"]]] + [:div.row + [:div.time "2h ago"]]]]]]]) + + +(defn dropdown-component [state-ratom] + (let [menu (if (:dropdown-open? @state-ratom) + [:div.ui.menu.transition.visible] + [:div.ui.menu])] + [:div.ui.right.dropdown.item + {:on-click #(swap! state-ratom update-in [:dropdown-open?] not)} + (:name @state-ratom) + [:i.dropdown.icon] + (into menu + (for [item (:items @state-ratom)] + ^{:key item} [:div.item item]))])) + + +(defcard-rg user-menu + "Top right user menu component" + (fn [state _] + [:div.ui.text.menu + [:div.ui.item + [:img.ui.mini.circular.image {:src "https://randomuser.me/api/portraits/men/4.jpg"}]] + [dropdown-component state]]) + (r/atom {:dropdown-open? false + :name "Random User" + :items ["foo" "bar"]}) + {:inspect-data true})