From 7c73b7ea1296dcf2448cedf29a612e0348002ac2 Mon Sep 17 00:00:00 2001 From: Flavio Fraschetti Date: Tue, 1 Aug 2023 18:00:03 +0100 Subject: [PATCH] Implement account_card and variants (#16801) * Implement account_card and variants with tests --- .../wallet/account_card/component_spec.cljs | 62 ++++++++ .../components/wallet/account_card/style.cljs | 95 +++++++++++++ .../components/wallet/account_card/view.cljs | 122 ++++++++++++++++ src/quo2/core.cljs | 4 +- src/quo2/core_spec.cljs | 3 +- src/status_im2/contexts/quo_preview/main.cljs | 8 +- .../quo_preview/wallet/account_card.cljs | 132 ++++++++++++++++++ 7 files changed, 422 insertions(+), 4 deletions(-) create mode 100644 src/quo2/components/wallet/account_card/component_spec.cljs create mode 100644 src/quo2/components/wallet/account_card/style.cljs create mode 100644 src/quo2/components/wallet/account_card/view.cljs create mode 100644 src/status_im2/contexts/quo_preview/wallet/account_card.cljs diff --git a/src/quo2/components/wallet/account_card/component_spec.cljs b/src/quo2/components/wallet/account_card/component_spec.cljs new file mode 100644 index 0000000000..3714fa0420 --- /dev/null +++ b/src/quo2/components/wallet/account_card/component_spec.cljs @@ -0,0 +1,62 @@ +(ns quo2.components.wallet.account-card.component-spec + (:require [quo2.components.wallet.account-card.view :as account-card] + [test-helpers.component :as h])) + +(def username "Alisher account") +(def empty-username "Account 1") + +(defn get-test-data + [type watch-only? empty? loading? metrics?] + {:name (if empty? empty-username username) + :balance "€1,000.00" + :percentage-value "50%" + :amount "€500.00" + :customization-color :blue + :watch-only? watch-only? + :loading? loading? + :metrics? metrics? + :type type}) + +(h/describe "Account_card tests" + (h/test "Renders Default" + (let [data (get-test-data :default false false false true)] + (h/render [account-card/view data]) + (h/is-truthy (h/get-by-text username)))) + + (h/test "Renders Watch-Only" + (let [data (get-test-data :watch-only true false false true)] + (h/render [account-card/view data]) + (h/is-truthy (h/get-by-text username)))) + + (h/test "Renders Add-Account" + (let [data {:type :add-account}] + (h/render [account-card/view data]) + (h/is-truthy (h/get-by-label-text :add-account)))) + + (h/test "Renders Empty" + (let [data (get-test-data :empty false true false true)] + (h/render [account-card/view data]) + (h/is-truthy (h/get-by-text empty-username)))) + + (h/test "Add account on press fires correctly" + (let [on-press (h/mock-fn) + data {:type :add-account + :on-press on-press}] + (h/render [account-card/view data]) + (h/fire-event :on-press (h/get-by-label-text :add-account)) + (h/was-called on-press))) + + (h/test "Renders component without metrics" + (let [data (get-test-data :default false false false false)] + (h/render [account-card/view data]) + (h/is-falsy (h/query-by-label-text :metrics)))) + + (h/test "Renders loading state" + (let [data (get-test-data :default false false true true)] + (h/render [account-card/view data]) + (h/is-truthy (h/get-by-label-text :loading)))) + + (h/test "Renders loading state without metrics" + (let [data (get-test-data :default false false true false)] + (h/render [account-card/view data]) + (h/is-falsy (h/query-by-label-text :metrics))))) diff --git a/src/quo2/components/wallet/account_card/style.cljs b/src/quo2/components/wallet/account_card/style.cljs new file mode 100644 index 0000000000..54c30e6239 --- /dev/null +++ b/src/quo2/components/wallet/account_card/style.cljs @@ -0,0 +1,95 @@ +(ns quo2.components.wallet.account-card.style + (:require + [quo2.foundations.colors :as colors])) + +(defn text-color + [watch-only? theme] + (if (and watch-only? (= :light theme)) + colors/neutral-100 + colors/white)) + +(defn card + [customization-color watch-only? metrics? theme] + {:width 162 + :height (if metrics? 88 68) + :background-color (if watch-only? + (colors/theme-colors colors/neutral-80-opa-5 colors/neutral-95 theme) + (colors/theme-colors + (colors/custom-color customization-color 50) + (colors/custom-color customization-color 60) + theme)) + :border-radius 16 + :border-width 1 + :border-color (if watch-only? + (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme) + colors/neutral-80-opa-10) + :padding-horizontal 12 + :padding-top 6 + :padding-bottom 10}) + +(def profile-container + {:margin-bottom 6 + :flex-direction :row}) + +(def metrics-container + {:flex-direction :row + :align-items :center}) + +(defn account-name + [watch-only? theme] + {:color (text-color watch-only? theme) + :margin-left 2}) + +(def watch-only-container + {:flex-direction :row + :justify-content :space-between + :align-items :center + :flex 1}) + +(defn account-value + [watch-only? theme] + {:color (text-color watch-only? theme)}) + +(defn metrics + [watch-only? theme] + {:color (if (and watch-only? (= :light theme)) + colors/neutral-80-opa-60 + colors/white-opa-70)}) + +(defn separator + [watch-only? theme] + {:width 2 + :height 2 + :border-radius 20 + :background-color (if (and watch-only? (= :light theme)) + colors/neutral-80-opa-20 + colors/white-opa-40) + :margin-horizontal 4}) + +(defn add-account-container + [theme metrics?] + {:width 161 + :height (if metrics? 88 68) + :border-color (colors/theme-colors colors/neutral-20 colors/white-opa-5 theme) + :border-width 1 + :border-style :dashed + :align-items :center + :justify-content :center + :border-radius 16 + :padding-vertical 12 + :padding-horizontal 10}) + +(def emoji + {:font-size 10 + :line-height 20}) + +(defn loader-view + [width height watch-only? theme] + {:width width + :height height + :background-color (if (and watch-only? (= :light theme)) colors/neutral-80-opa-5 colors/white-opa-10) + :border-radius 6}) + +(def loader-container + {:flex-direction :row + :align-items :center}) diff --git a/src/quo2/components/wallet/account_card/view.cljs b/src/quo2/components/wallet/account_card/view.cljs new file mode 100644 index 0000000000..cdf5a614b4 --- /dev/null +++ b/src/quo2/components/wallet/account_card/view.cljs @@ -0,0 +1,122 @@ +(ns quo2.components.wallet.account-card.view + (:require [react-native.core :as rn] + [quo2.foundations.colors :as colors] + [quo2.components.icon :as icon] + [quo2.components.wallet.account-card.style :as style] + [quo2.components.buttons.button.view :as button] + [quo2.components.markdown.text :as text] + [utils.i18n :as i18n] + [quo2.theme :as theme])) + +(defn- loading-view + [{:keys [customization-color type theme metrics?]}] + (let [watch-only? (= :watch-only type) + empty? (= :empty type)] + [rn/view + {:accessibility-label :loading + :style (style/card customization-color watch-only? metrics? theme)} + [rn/view {:style style/loader-container} + [rn/view + {:style (assoc (style/loader-view 16 + 16 + watch-only? + theme) + :margin-right 8 + :margin-top 2)}] + [rn/view {:style style/watch-only-container} + [rn/view {:style (style/loader-view 57 8 watch-only? theme)}] + (when watch-only? [icon/icon :reveal {:color colors/neutral-50 :size 12}])]] + [rn/view + {:style (assoc (style/loader-view + (if empty? 56 80) + 16 + watch-only? + theme) + :margin-top + 13)}] + (when metrics? + [rn/view + {:accessibility-label :metrics + :style (assoc (style/loader-view + (if empty? 37 96) + 8 + watch-only? + theme) + :margin-top + 10)}])])) + +(defn- user-account + [{:keys [state name balance percentage-value loading? amount customization-color type emoji metrics? + theme]}] + (let [watch-only? (= :watch-only type) + empty? (= :empty type) + account-amount (if (= :empty state) "€0.00" amount) + account-name (if (= :empty state) (i18n/label :t/Account 1) name) + account-percentage (if (= :empty state) "€0.00" percentage-value)] + (if loading? + [loading-view + {:customization-color customization-color + :type type + :theme theme + :metrics? metrics?}] + [:<> + [rn/view {:style (style/card customization-color watch-only? metrics? theme)} + [rn/view {:style style/profile-container} + [rn/view {:style {:padding-bottom 2 :margin-right 2}} + [text/text {:style style/emoji} emoji]] + [rn/view {:style style/watch-only-container} + [text/text + {:size :paragraph-2 + :weight :medium + :style (style/account-name watch-only? theme)} + account-name] + (when watch-only? [icon/icon :reveal {:color colors/neutral-50 :size 12}])]] + [text/text + {:size :heading-2 + :weight :semi-bold + :style (style/account-value watch-only? theme)} + balance] + (when metrics? + [rn/view {:style style/metrics-container} + [text/text + {:weight :semi-bold + :size :paragraph-2 + :accessibility-label :metrics + :style (style/metrics watch-only? theme)} + account-percentage] + (when (not empty?) + [:<> + [rn/view (style/separator watch-only? theme)] + [text/text + {:weight :semi-bold + :size :paragraph-2 + :style (style/metrics watch-only? theme)} account-amount] + [rn/view {:style {:margin-left 4}} + [icon/icon :positive + {:color (if (and watch-only? (not (colors/dark?))) + colors/neutral-50 + colors/white-opa-70) + :size 16}]]])])]]))) + +(defn- add-account-view + [{:keys [on-press customization-color theme metrics?]}] + [rn/view (style/add-account-container theme metrics?) + [button/button + {:type :primary + :size 24 + :icon true + :accessibility-label :add-account + :on-press on-press + :customization-color customization-color} + :i/add]]) + +(defn- view-internal + [{:keys [type] :as props}] + (case type + :watch-only [user-account props] + :add-account [add-account-view props] + :default [user-account props] + :empty [user-account props] + nil)) + +(def view (theme/with-theme view-internal)) diff --git a/src/quo2/core.cljs b/src/quo2/core.cljs index 86fd72ca2d..60e235947f 100644 --- a/src/quo2/core.cljs +++ b/src/quo2/core.cljs @@ -103,7 +103,8 @@ quo2.components.tags.token-tag quo2.components.text-combinations.title.view quo2.components.wallet.network-amount.view - quo2.components.wallet.network-bridge.view)) + quo2.components.wallet.network-bridge.view + quo2.components.wallet.account-card.view)) (def separator quo2.components.common.separator.view/separator) @@ -295,3 +296,4 @@ ;;;; WALLET (def network-amount quo2.components.wallet.network-amount.view/view) (def network-bridge quo2.components.wallet.network-bridge.view/view) +(def account-card quo2.components.wallet.account-card.view/view) diff --git a/src/quo2/core_spec.cljs b/src/quo2/core_spec.cljs index 7bcad8d7ad..358d129089 100644 --- a/src/quo2/core_spec.cljs +++ b/src/quo2/core_spec.cljs @@ -49,4 +49,5 @@ [quo2.components.share.share-qr-code.component-spec] [quo2.components.tags.status-tags-component-spec] [quo2.components.wallet.network-amount.component-spec] - [quo2.components.wallet.network-bridge.component-spec])) + [quo2.components.wallet.network-bridge.component-spec] + [quo2.components.wallet.account-card.component-spec])) diff --git a/src/status_im2/contexts/quo_preview/main.cljs b/src/status_im2/contexts/quo_preview/main.cljs index c8ba25ac9a..a79c9a560d 100644 --- a/src/status_im2/contexts/quo_preview/main.cljs +++ b/src/status_im2/contexts/quo_preview/main.cljs @@ -103,7 +103,8 @@ [status-im2.contexts.quo-preview.community.channel-actions :as channel-actions] [status-im2.contexts.quo-preview.gradient.gradient-cover :as gradient-cover] [status-im2.contexts.quo-preview.wallet.network-amount :as network-amount] - [status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge])) + [status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge] + [status-im2.contexts.quo-preview.wallet.account-card :as account-card])) (def screens-categories {:foundations [{:name :shadows @@ -394,7 +395,10 @@ :text-combinations [{:name :title :options {:topBar {:visible true}} :component title/preview-title}] - :wallet [{:name :network-amount + :wallet [{:name :account-card + :options {:topBar {:visible true}} + :component account-card/preview-account-card} + {:name :network-amount :options {:topBar {:visible true}} :component network-amount/preview} {:name :network-bridge diff --git a/src/status_im2/contexts/quo_preview/wallet/account_card.cljs b/src/status_im2/contexts/quo_preview/wallet/account_card.cljs new file mode 100644 index 0000000000..cdf6e35096 --- /dev/null +++ b/src/status_im2/contexts/quo_preview/wallet/account_card.cljs @@ -0,0 +1,132 @@ +(ns status-im2.contexts.quo-preview.wallet.account-card + (:require [react-native.core :as rn] + [quo2.foundations.colors :as colors] + [quo2.components.markdown.text :as text] + [quo2.core :as quo] + [quo2.components.icon :as icon] + [reagent.core :as reagent] + [utils.collection] + [status-im2.contexts.quo-preview.preview :as preview])) + +(def descriptor + [{:label "Type:" + :key :type + :type :select + :options [{:key :default + :value "Default"} + {:key :watch-only + :value "Watch Only"} + {:key :add-account + :value "Add Account"} + {:key :empty + :value "Empty"}]} + {:label "Customization color:" + :key :customization-color + :type :select + :options (map (fn [[color-kw _]] + {:key color-kw + :value (name color-kw)}) + colors/customization)} + {:label "Name:" + :key :name + :type :text} + {:label "Balance:" + :key :balance + :type :text} + {:label "Percentage value:" + :key :percentage-value + :type :text} + {:label "Amount:" + :key :amount + :type :text} + {:label "Metrics:" + :key :metrics? + :type :boolean} + {:label "Loading:" + :key :loading? + :type :boolean} + {:label "Emoji:" + :key :emoji + :type :text}]) + +(defn initial-state + [type] + (case type + :default + {:name "Alisher account" + :balance "€2,269.12" + :percentage-value "16.9%" + :amount "€570.24" + :customization-color :turquoise + :metrics? true + :type :default + :emoji "💎"} + + :empty + {:name "Account 1" + :balance "€0.00" + :percentage-value "€0.00" + :customization-color :blue + :metrics? true + :type :empty + :emoji "🍑"} + + :watch-only + {:name "Alisher account" + :balance "€2,269.12" + :percentage-value "16.9%" + :amount "€570.24" + :metrics? true + :type :watch-only + :emoji "💸"} + + :add-account + {:customization-color :blue + :on-press #(js/alert "Button pressed") + :metrics? true + :type :add-account})) + +(defn cool-preview + [] + (let [state (reagent/atom (initial-state :default))] + [:f> + (fn [] + (rn/use-effect + (fn [] (reset! state (initial-state (:type @state)))) + [(:type @state)]) + [rn/view + {:style {:flex 1}} + [rn/view + {:style {:margin-vertical 40 + :padding-left 40 + :flex-direction :row + :align-items :center}} + [text/text + {:size :heading-1 + :weight :semi-bold} + "Account card"] + [rn/view + {:style {:width 20 + :height 20 + :border-radius 60 + :background-color colors/success-50 + :align-items :center + :justify-content :center + :margin-left 8}} + [icon/icon :i/check {:color colors/white :size 16}]]] + [rn/view {:style {:flex 1}} + [preview/customizer state descriptor]] + [rn/view {:style {:align-items :center :margin-top 40}} + [quo/account-card @state]]])])) + +(defn preview-account-card + [] + [rn/view + {:background-color (colors/theme-colors colors/white + colors/neutral-90) + :flex 1} + [rn/flat-list + {:flex 1 + :keyboard-should-persist-taps :always + :header [cool-preview] + :key-fn str}]])