Implement account_card and variants (#16801)

* Implement account_card and variants with tests
This commit is contained in:
Flavio Fraschetti 2023-08-01 18:00:03 +01:00 committed by GitHub
parent 1a97731454
commit 7c73b7ea12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 422 additions and 4 deletions

View File

@ -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)))))

View File

@ -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})

View File

@ -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))

View File

@ -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)

View File

@ -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]))

View File

@ -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

View File

@ -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}]])