From d08e74958019efae1e04a8001c9dbc2d56153f2d Mon Sep 17 00:00:00 2001 From: refi93 Date: Fri, 27 Oct 2023 19:59:18 +0200 Subject: [PATCH 1/2] feat(staking): add activity tab --- apps/browser-extension-wallet/.env.defaults | 1 + apps/browser-extension-wallet/.env.example | 2 + packages/common/src/analytics/types.ts | 1 + .../src/features/activity/Activity.tsx | 1 + .../staking/src/features/activity/index.ts | 1 + .../src/features/i18n/translations/en.ts | 1 + packages/staking/src/features/i18n/types.ts | 1 + .../src/features/staking/Navigation.tsx | 44 ++++++++++++++----- .../src/features/staking/StakingView.tsx | 2 + .../stateMachine/commands.ts | 9 +++- .../stateMachine/processExpandedViewCases.ts | 32 ++++++++++++++ .../stateMachine/types.ts | 7 +++ 12 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 packages/staking/src/features/activity/Activity.tsx create mode 100644 packages/staking/src/features/activity/index.ts diff --git a/apps/browser-extension-wallet/.env.defaults b/apps/browser-extension-wallet/.env.defaults index fded3830dc..5525b46cb8 100644 --- a/apps/browser-extension-wallet/.env.defaults +++ b/apps/browser-extension-wallet/.env.defaults @@ -23,6 +23,7 @@ USE_ADA_HANDLE=true USE_DATA_CHECK=false USE_POSTHOG_ANALYTICS=true USE_COMBINED_PASSWORD_NAME_STEP_COMPONENT=false +USE_MULTI_DELEGATION_STAKING_ACTIVITY=false USE_POSTHOG_ANALYTICS_FOR_OPTED_OUT=false USE_MATOMO_ANALYTICS_FOR_OPTED_OUT=false diff --git a/apps/browser-extension-wallet/.env.example b/apps/browser-extension-wallet/.env.example index f3897cd232..76bb6bead5 100644 --- a/apps/browser-extension-wallet/.env.example +++ b/apps/browser-extension-wallet/.env.example @@ -26,6 +26,8 @@ USE_POSTHOG_ANALYTICS=true USE_POSTHOG_ANALYTICS_FOR_OPTED_OUT=false USE_MATOMO_ANALYTICS_FOR_OPTED_OUT=false USE_COMBINED_PASSWORD_NAME_STEP_COMPONENT=false +USE_MULTI_DELEGATION_STAKING_ACTIVITY=false + # In App URLs CATALYST_GOOGLE_PLAY_URL=https://play.google.com/store/apps/details?id=io.iohk.vitvoting CATALYST_APP_STORE_URL=https://apps.apple.com/fr/app/catalyst-voting/id1517473397?l=en diff --git a/packages/common/src/analytics/types.ts b/packages/common/src/analytics/types.ts index e0cac05cd9..e169c0c88b 100644 --- a/packages/common/src/analytics/types.ts +++ b/packages/common/src/analytics/types.ts @@ -56,6 +56,7 @@ export enum PostHogAction { StakingAboutStakingFaqClick = 'staking | about staking | faq | click', StakingMultiDelegationDedicatedBlogClick = 'staking | multi-delegation | dedicated blog | click', StakingMultiDelegationGotItClick = 'staking | multi-delegation | got it | click', + StakingActivityClick = 'staking | activity | click', StakingOverviewClick = 'staking | overview | click', StakingOverviewCopyAddressClick = 'staking | overview | copy address | click', StakingOverviewManageClick = 'staking | overview | manage | click', diff --git a/packages/staking/src/features/activity/Activity.tsx b/packages/staking/src/features/activity/Activity.tsx new file mode 100644 index 0000000000..c9d20953e1 --- /dev/null +++ b/packages/staking/src/features/activity/Activity.tsx @@ -0,0 +1 @@ +export const Activity = () => <>Activity placeholder; diff --git a/packages/staking/src/features/activity/index.ts b/packages/staking/src/features/activity/index.ts new file mode 100644 index 0000000000..cad213e19d --- /dev/null +++ b/packages/staking/src/features/activity/index.ts @@ -0,0 +1 @@ +export { Activity } from './Activity'; diff --git a/packages/staking/src/features/i18n/translations/en.ts b/packages/staking/src/features/i18n/translations/en.ts index 4fbd7cc4d6..8355763e61 100644 --- a/packages/staking/src/features/i18n/translations/en.ts +++ b/packages/staking/src/features/i18n/translations/en.ts @@ -159,6 +159,7 @@ export const en: Translations = { 'portfolioBar.maxPools': '(max {{maxPoolsCount}})', 'portfolioBar.next': 'Next', 'portfolioBar.selectedPools': '{{selectedPoolsCount}} pools selected', + 'root.nav.activityTitle': 'Activity', 'root.nav.browsePoolsTitle': 'Browse pools', 'root.nav.overviewTitle': 'Overview', 'root.nav.title': 'Staking Navigation', diff --git a/packages/staking/src/features/i18n/types.ts b/packages/staking/src/features/i18n/types.ts index e0d829fd97..12c83ee6e1 100644 --- a/packages/staking/src/features/i18n/types.ts +++ b/packages/staking/src/features/i18n/types.ts @@ -241,6 +241,7 @@ type KeysStructure = { root: { title: ''; nav: { + activityTitle: ''; browsePoolsTitle: ''; title: ''; overviewTitle: ''; diff --git a/packages/staking/src/features/staking/Navigation.tsx b/packages/staking/src/features/staking/Navigation.tsx index c672a5efc3..7d658b16c1 100644 --- a/packages/staking/src/features/staking/Navigation.tsx +++ b/packages/staking/src/features/staking/Navigation.tsx @@ -6,6 +6,7 @@ import { useOutsideHandles } from '../outside-handles-provider'; import { DelegationFlow, useDelegationPortfolioStore } from '../store'; export enum Page { + activity = 'activity', overview = 'overview', browsePools = 'browsePools', } @@ -19,23 +20,33 @@ const isValueAValidSubPage = (value: string): value is Page => Object.values { const { analytics } = useOutsideHandles(); const { activePage, portfolioMutators } = useDelegationPortfolioStore((store) => ({ - activePage: [ - DelegationFlow.Overview, - DelegationFlow.CurrentPoolDetails, - DelegationFlow.PortfolioManagement, - ].includes(store.activeDelegationFlow) - ? Page.overview - : Page.browsePools, + activePage: (() => { + const flowToPage: Record = { + [DelegationFlow.Activity]: Page.activity, + [DelegationFlow.Overview]: Page.overview, + [DelegationFlow.CurrentPoolDetails]: Page.overview, + [DelegationFlow.PortfolioManagement]: Page.overview, + [DelegationFlow.ChangingPreferences]: Page.browsePools, + [DelegationFlow.BrowsePools]: Page.browsePools, + [DelegationFlow.NewPortfolio]: Page.browsePools, + [DelegationFlow.PoolDetails]: Page.browsePools, + }; + return flowToPage[store.activeDelegationFlow]; + })(), portfolioMutators: store.mutators, })); const { t } = useTranslation(); const onValueChange = (value: string) => { if (!isValueAValidSubPage(value)) return; - analytics.sendEventToPostHog( - value === Page.overview ? PostHogAction.StakingOverviewClick : PostHogAction.StakingBrowsePoolsClick - ); + const pageToEventParams = { + [Page.activity]: ['GoToActivity', PostHogAction.StakingActivityClick] as const, + [Page.overview]: ['GoToOverview', PostHogAction.StakingOverviewClick] as const, + [Page.browsePools]: ['GoToBrowsePools', PostHogAction.StakingBrowsePoolsClick] as const, + }; + const [command, posthogEvent] = pageToEventParams[value]; + analytics.sendEventToPostHog(posthogEvent); portfolioMutators.executeCommand({ - type: value === Page.overview ? 'GoToOverview' : 'GoToBrowsePools', + type: command, }); }; @@ -62,6 +73,17 @@ export const Navigation = ({ children }: NavigationProps) => { tabIndex={0} highlightWidth="half" /> + {process.env.USE_MULTI_DELEGATION_STAKING_ACTIVITY === 'true' ? ( + + ) : ( + <> + )} {children(activePage)} diff --git a/packages/staking/src/features/staking/StakingView.tsx b/packages/staking/src/features/staking/StakingView.tsx index 1540a66465..021f96a418 100644 --- a/packages/staking/src/features/staking/StakingView.tsx +++ b/packages/staking/src/features/staking/StakingView.tsx @@ -1,4 +1,5 @@ import { Box, Text } from '@lace/ui'; +import { Activity } from 'features/activity'; import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { BrowsePools } from '../BrowsePools'; @@ -46,6 +47,7 @@ export const StakingView = () => { {activePage === Page.overview && } {activePage === Page.browsePools && } + {activePage === Page.activity && } )} diff --git a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/commands.ts b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/commands.ts index 416f966414..80bd93f600 100644 --- a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/commands.ts +++ b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/commands.ts @@ -39,6 +39,10 @@ export type ManagePortfolio = { type: 'ManagePortfolio'; }; +export type GoToActivity = { + type: 'GoToActivity'; +}; + export type GoToBrowsePools = { type: 'GoToBrowsePools'; }; @@ -96,12 +100,15 @@ export type DrawerFailure = { type: 'DrawerFailure'; }; -export type OverviewCommand = ShowDelegatedPoolDetails | ManagePortfolio | GoToBrowsePools; +export type ActivityCommand = GoToOverview | GoToBrowsePools; + +export type OverviewCommand = ShowDelegatedPoolDetails | ManagePortfolio | GoToBrowsePools | GoToActivity; export type BrowsePoolsCommand = | SelectPoolFromList | UnselectPoolFromList | ShowPoolDetailsFromList + | GoToActivity | GoToOverview | ClearSelections | CreateNewPortfolio; diff --git a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/processExpandedViewCases.ts b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/processExpandedViewCases.ts index 05c5ab2e79..e0d114decf 100644 --- a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/processExpandedViewCases.ts +++ b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/processExpandedViewCases.ts @@ -1,6 +1,7 @@ import { PERCENTAGE_SCALE_MAX } from '../constants'; import { atomicStateMutators } from './atomicStateMutators'; import { + ActivityCommand, AddStakePools, BeginSingleStaking, BrowsePoolsCommand, @@ -14,6 +15,7 @@ import { DrawerBack, DrawerContinue, DrawerFailure, + GoToActivity, GoToBrowsePools, GoToOverview, ManagePortfolio, @@ -48,6 +50,7 @@ import { DrawerManagementStep, ExpandedViewDelegationFlow, Handler, + StateActivity, StateBrowsePools, StateChangingPreferences, StateCurrentPoolDetails, @@ -72,6 +75,10 @@ export const processExpandedViewCases: Handler = (params) => { [DelegationFlow.Overview]: cases( { + GoToActivity: handler(({ state }) => ({ + ...state, + activeDelegationFlow: DelegationFlow.Activity, + })), GoToBrowsePools: handler(({ state }) => ({ ...state, activeDelegationFlow: DelegationFlow.BrowsePools, @@ -92,6 +99,27 @@ export const processExpandedViewCases: Handler = (params) => params.command.type, DelegationFlow.Overview ), + [DelegationFlow.Activity]: cases( + { + GoToBrowsePools: handler(({ state }) => ({ + ...state, + activeDelegationFlow: DelegationFlow.BrowsePools, + draftPortfolio: undefined, + pendingSelectedPortfolio: undefined, + viewedStakePool: undefined, + })), + GoToOverview: handler(({ state }) => ({ + ...state, + activeDelegationFlow: DelegationFlow.Overview, + activeDrawerStep: undefined, + draftPortfolio: undefined, + pendingSelectedPortfolio: undefined, + viewedStakePool: undefined, + })), + }, + params.command.type, + DelegationFlow.Activity + ), [DelegationFlow.BrowsePools]: cases( { ClearSelections: handler(({ state }) => ({ @@ -116,6 +144,10 @@ export const processExpandedViewCases: Handler = (params) => ...atomicStateMutators.beginNewPortfolioCreation({ selections: state.selectedPortfolio }), }; }), + GoToActivity: handler(({ state }) => ({ + ...state, + activeDelegationFlow: DelegationFlow.Activity, + })), GoToOverview: handler(({ state }) => ({ ...state, activeDelegationFlow: DelegationFlow.Overview, diff --git a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/types.ts b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/types.ts index eebfd557b9..41b5639f85 100644 --- a/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/types.ts +++ b/packages/staking/src/features/store/delegationPortfolioStore/stateMachine/types.ts @@ -31,6 +31,7 @@ export type CurrentPortfolioStakePool = PortfolioStakePoolBase & export enum DelegationFlow { Overview = 'Overview', BrowsePools = 'BrowsePools', + Activity = 'Activity', CurrentPoolDetails = 'CurrentPoolDetails', PoolDetails = 'PoolDetails', PortfolioManagement = 'PortfolioManagement', @@ -85,6 +86,11 @@ export type StateOverview = MakeState<{ viewedStakePool: undefined; }>; +export type StateActivity = MakeState<{ + activeDelegationFlow: DelegationFlow.Activity; + activeDrawerStep: undefined; +}>; + export type StateCurrentPoolDetails = MakeState<{ activeDrawerStep: DrawerDefaultStep.PoolDetails; activeDelegationFlow: DelegationFlow.CurrentPoolDetails; @@ -134,6 +140,7 @@ export type StateChangingPreferences = MakeState<{ }>; export type State = + | StateActivity | StateOverview | StateCurrentPoolDetails | StatePortfolioManagement From dcd5f83f651aa8871599b0e083de600c8331ef99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Korba=C5=A1?= Date: Mon, 6 Nov 2023 09:38:54 +0100 Subject: [PATCH 2/2] feat(staking): [LW-8877] Add activity tab to staking, show rewards list (#684) * feat(staking): add rewards list to Staking Activity tab * feat(staking): expose activity detail drawer in staking section to be used by staking activity * feat(staking): add "no staking activity yet" screen * fix(staking): align "no staking activity" component to center vertically --- .../MultiDelegationStakingPopup.tsx | 3 +- .../stores/slices/activity-detail-slice.ts | 4 +- .../components/MultiDelegationStaking.tsx | 43 +++++++++++++++++-- .../src/features/activity/Activity.tsx | 24 ++++++++++- .../activity/NoStakingActivity.css.ts | 13 ++++++ .../features/activity/NoStakingActivity.tsx | 17 ++++++++ .../src/features/activity/RewardsHistory.tsx | 29 +++++++++++++ .../helpers/getGroupedRewardsHistory.ts | 9 ++++ .../src/features/i18n/translations/en.ts | 2 + packages/staking/src/features/i18n/types.ts | 6 +++ .../outside-handles-provider/types.ts | 1 + .../src/features/staking/StakingView.tsx | 2 +- packages/staking/src/features/theme/colors.ts | 3 ++ 13 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 packages/staking/src/features/activity/NoStakingActivity.css.ts create mode 100644 packages/staking/src/features/activity/NoStakingActivity.tsx create mode 100644 packages/staking/src/features/activity/RewardsHistory.tsx create mode 100644 packages/staking/src/features/activity/helpers/getGroupedRewardsHistory.ts diff --git a/apps/browser-extension-wallet/src/features/delegation/components/MultiDelegationStakingPopup.tsx b/apps/browser-extension-wallet/src/features/delegation/components/MultiDelegationStakingPopup.tsx index eca01a83f3..5c4ff1de87 100644 --- a/apps/browser-extension-wallet/src/features/delegation/components/MultiDelegationStakingPopup.tsx +++ b/apps/browser-extension-wallet/src/features/delegation/components/MultiDelegationStakingPopup.tsx @@ -73,7 +73,7 @@ export const MultiDelegationStakingPopup = (): JSX.Element => { name: 'AnalyticsEventNames.Staking.STAKING_MULTI_DELEGATION_POPUP' }); }, []); - const { walletActivities } = useWalletActivities({ sendAnalytics }); + const { walletActivities, walletActivitiesStatus } = useWalletActivities({ sendAnalytics }); const { fiatCurrency } = useCurrencyStore(); const { executeWithPassword } = useWalletManager(); const isLoadingNetworkInfo = useWalletStore(networkInfoStatusSelector); @@ -125,6 +125,7 @@ export const MultiDelegationStakingPopup = (): JSX.Element => { walletStoreNetworkInfo: networkInfo, walletStoreBlockchainProvider: blockchainProvider, walletStoreWalletActivities: walletActivities, + walletStoreWalletActivitiesStatus: walletActivitiesStatus, // TODO: LW-7575 make compactNumber reusable and not pass it here. compactNumber: compactNumberWithUnit, walletAddress, diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index 726edac529..83d4dd6936 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -89,12 +89,15 @@ const buildGetActivityDetail = walletInfo } = get(); + set({ fetchingActivityInfo: true }); + if (activityDetail.type === 'rewards') { const { activity, status, type } = activityDetail; const poolInfos = await getPoolInfos( activity.rewards.map(({ poolId }) => poolId), stakePoolProvider ); + set({ fetchingActivityInfo: false }); return { activity: { @@ -128,7 +131,6 @@ const buildGetActivityDetail = const { activity: tx, status, type, direction } = activityDetail; const walletAssets = await firstValueFrom(wallet.assetInfo$); const protocolParameters = await firstValueFrom(wallet.protocolParameters$); - set({ fetchingActivityInfo: true }); // Assets const assetIds = getTransactionAssetsId(tx.body.outputs); diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/MultiDelegationStaking.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/MultiDelegationStaking.tsx index 4e331faa23..f99a17a5a9 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/MultiDelegationStaking.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/MultiDelegationStaking.tsx @@ -1,5 +1,5 @@ import { OutsideHandlesProvider, Staking } from '@lace/staking'; -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { useAnalyticsContext, useBackgroundServiceAPIContext, @@ -17,6 +17,9 @@ import { MULTIDELEGATION_FIRST_VISIT_LS_KEY, MULTIDELEGATION_FIRST_VISIT_SINCE_PORTFOLIO_PERSISTENCE_LS_KEY } from '@utils/constants'; +import { ActivityDetail } from '../../activity'; +import { Drawer, DrawerNavigation } from '@lace/common'; +import { useTranslation } from 'react-i18next'; export const MultiDelegationStaking = (): JSX.Element => { const { theme } = useTheme(); @@ -38,7 +41,9 @@ export const MultiDelegationStaking = (): JSX.Element => { fetchNetworkInfo, networkInfo, blockchainProvider, - currentChain + currentChain, + activityDetail, + resetActivityState } = useWalletStore((state) => ({ getKeyAgentType: state.getKeyAgentType, inMemoryWallet: state.inMemoryWallet, @@ -50,8 +55,11 @@ export const MultiDelegationStaking = (): JSX.Element => { fetchNetworkInfo: state.fetchNetworkInfo, blockchainProvider: state.blockchainProvider, walletInfo: state.walletInfo, - currentChain: state.currentChain + currentChain: state.currentChain, + activityDetail: state.activityDetail, + resetActivityState: state.resetActivityState })); + const { t } = useTranslation(); const sendAnalytics = useCallback(() => { // TODO implement analytics for the new flow const analytics = { @@ -66,7 +74,7 @@ export const MultiDelegationStaking = (): JSX.Element => { name: 'AnalyticsEventNames.Staking.STAKING_MULTI_DELEGATION_BROWSER' }); }, []); - const { walletActivities } = useWalletActivities({ sendAnalytics }); + const { walletActivities, walletActivitiesStatus } = useWalletActivities({ sendAnalytics }); const { fiatCurrency } = useCurrencyStore(); const { executeWithPassword } = useWalletManager(); const [multidelegationFirstVisit, { updateLocalStorage: setMultidelegationFirstVisit }] = useLocalStorage( @@ -80,6 +88,11 @@ export const MultiDelegationStaking = (): JSX.Element => { const walletAddress = walletInfo.addresses?.[0].address?.toString(); const analytics = useAnalyticsContext(); + // Reset current transaction details and close drawer if network (blockchainProvider) has changed + useEffect(() => { + resetActivityState(); + }, [resetActivityState, blockchainProvider]); + return ( { walletStoreNetworkInfo: networkInfo, walletStoreBlockchainProvider: blockchainProvider, walletStoreWalletActivities: walletActivities, + walletStoreWalletActivitiesStatus: walletActivitiesStatus, // TODO: LW-7575 make compactNumber reusable and not pass it here. compactNumber: compactNumberWithUnit, multidelegationFirstVisit, @@ -118,6 +132,27 @@ export const MultiDelegationStaking = (): JSX.Element => { }} > + {/* + Note: Mounting the browser-extension activity details drawer here is just a workaround. + Ideally, the Drawer/Activity detail should be fully managed within the "Staking" component, + which contains the respective "Activity" section, but that would require moving/refactoring + large chunks of code, ATM tightly coupled with browser-extension state/logic, + to a separate package (core perhaps?). + */} + { + resetActivityState(); + }} + /> + } + > + {activityDetail && priceResult && } + ); }; diff --git a/packages/staking/src/features/activity/Activity.tsx b/packages/staking/src/features/activity/Activity.tsx index c9d20953e1..f6fb246cc4 100644 --- a/packages/staking/src/features/activity/Activity.tsx +++ b/packages/staking/src/features/activity/Activity.tsx @@ -1 +1,23 @@ -export const Activity = () => <>Activity placeholder; +import { StateStatus, useOutsideHandles } from 'features/outside-handles-provider'; +import { getGroupedRewardsActivities } from './helpers/getGroupedRewardsHistory'; +import { NoStakingActivity } from './NoStakingActivity'; +import { RewardsHistory } from './RewardsHistory'; + +export const Activity = () => { + const { walletStoreWalletActivitiesStatus: walletActivitiesStatus, walletStoreWalletActivities: walletActivities } = + useOutsideHandles(); + const groupedRewardsActivities = getGroupedRewardsActivities(walletActivities); + + return ( + <> + {walletActivitiesStatus === StateStatus.LOADED && groupedRewardsActivities.length === 0 ? ( + + ) : ( + + )} + + ); +}; diff --git a/packages/staking/src/features/activity/NoStakingActivity.css.ts b/packages/staking/src/features/activity/NoStakingActivity.css.ts new file mode 100644 index 0000000000..ebbfc6e56a --- /dev/null +++ b/packages/staking/src/features/activity/NoStakingActivity.css.ts @@ -0,0 +1,13 @@ +import { style } from '@lace/ui'; +import { theme } from 'features/theme'; + +export const sadFaceIcon = style({ + height: theme.spacing.$112, + width: theme.spacing.$112, +}); + +export const noActivityText = style({ + color: theme.colors.$activityNoActivityTextColor, + fontSize: theme.fontSizes.$14, + fontWeight: theme.fontWeights.$semibold, +}); diff --git a/packages/staking/src/features/activity/NoStakingActivity.tsx b/packages/staking/src/features/activity/NoStakingActivity.tsx new file mode 100644 index 0000000000..e2c928f3a9 --- /dev/null +++ b/packages/staking/src/features/activity/NoStakingActivity.tsx @@ -0,0 +1,17 @@ +import SadFaceIcon from '@lace/core/src/ui/assets/icons/sad-face.component.svg'; +import { Flex } from '@lace/ui'; +import { Typography } from 'antd'; +import { useTranslation } from 'react-i18next'; +import * as styles from './NoStakingActivity.css'; + +export const NoStakingActivity = () => { + const { t } = useTranslation(); + return ( + + + + {t('activity.rewardsHistory.noStakingActivityYet')} + + + ); +}; diff --git a/packages/staking/src/features/activity/RewardsHistory.tsx b/packages/staking/src/features/activity/RewardsHistory.tsx new file mode 100644 index 0000000000..4f2a2cc45f --- /dev/null +++ b/packages/staking/src/features/activity/RewardsHistory.tsx @@ -0,0 +1,29 @@ +import { AssetActivityListProps, GroupedAssetActivityList } from '@lace/core'; +import { Box, Text } from '@lace/ui'; +import { Skeleton } from 'antd'; +import { StateStatus } from 'features/outside-handles-provider'; +import { useTranslation } from 'react-i18next'; + +const LACE_APP_ID = 'lace-app'; + +type RewardsHistoryProps = { + groupedRewardsActivities: AssetActivityListProps[]; + walletActivitiesStatus: StateStatus; +}; +export const RewardsHistory = ({ groupedRewardsActivities, walletActivitiesStatus }: RewardsHistoryProps) => { + const { t } = useTranslation(); + + return ( + <> + + {t('activity.rewardsHistory.title')} + + + + + + ); +}; diff --git a/packages/staking/src/features/activity/helpers/getGroupedRewardsHistory.ts b/packages/staking/src/features/activity/helpers/getGroupedRewardsHistory.ts new file mode 100644 index 0000000000..c665be690c --- /dev/null +++ b/packages/staking/src/features/activity/helpers/getGroupedRewardsHistory.ts @@ -0,0 +1,9 @@ +import { AssetActivityListProps } from '@lace/core'; + +export const getGroupedRewardsActivities = (walletActivities: AssetActivityListProps[]) => + walletActivities + .map((group) => ({ + ...group, + items: group.items.filter((item) => item.type === 'rewards'), + })) + .filter((group) => group.items.length > 0); diff --git a/packages/staking/src/features/i18n/translations/en.ts b/packages/staking/src/features/i18n/translations/en.ts index 8355763e61..4af359ddb3 100644 --- a/packages/staking/src/features/i18n/translations/en.ts +++ b/packages/staking/src/features/i18n/translations/en.ts @@ -1,6 +1,8 @@ import { Translations } from '../types'; export const en: Translations = { + 'activity.rewardsHistory.noStakingActivityYet': 'No staking activity yet.', + 'activity.rewardsHistory.title': 'History', 'browsePools.stakePoolTableBrowser.addPool': 'Add pool', 'browsePools.stakePoolTableBrowser.disabledTooltip': 'Maximum number of pools selected', 'browsePools.stakePoolTableBrowser.emptyMessage': 'No results matching your search', diff --git a/packages/staking/src/features/i18n/types.ts b/packages/staking/src/features/i18n/types.ts index 12c83ee6e1..31fc5b4e40 100644 --- a/packages/staking/src/features/i18n/types.ts +++ b/packages/staking/src/features/i18n/types.ts @@ -15,6 +15,12 @@ type KeysStructure = { close: ''; }; }; + activity: { + rewardsHistory: { + title: ''; + noStakingActivityYet: ''; + }; + }; browsePools: { stakePoolTableBrowser: { searchInputPlaceholder: ''; diff --git a/packages/staking/src/features/outside-handles-provider/types.ts b/packages/staking/src/features/outside-handles-provider/types.ts index 55d301f551..60165c488b 100644 --- a/packages/staking/src/features/outside-handles-provider/types.ts +++ b/packages/staking/src/features/outside-handles-provider/types.ts @@ -70,6 +70,7 @@ export type OutsideHandlesContextValue = { walletStoreGetKeyAgentType: () => string; walletStoreInMemoryWallet: Wallet.ObservableWallet; walletStoreWalletActivities: AssetActivityListProps[]; + walletStoreWalletActivitiesStatus: StateStatus; walletStoreWalletUICardanoCoin: Wallet.CoinId; walletManagerExecuteWithPassword: ( password: string, diff --git a/packages/staking/src/features/staking/StakingView.tsx b/packages/staking/src/features/staking/StakingView.tsx index 021f96a418..4abae0fd94 100644 --- a/packages/staking/src/features/staking/StakingView.tsx +++ b/packages/staking/src/features/staking/StakingView.tsx @@ -44,7 +44,7 @@ export const StakingView = () => { {(activePage) => ( - + {activePage === Page.overview && } {activePage === Page.browsePools && } {activePage === Page.activity && } diff --git a/packages/staking/src/features/theme/colors.ts b/packages/staking/src/features/theme/colors.ts index 555f53a090..da605a277b 100644 --- a/packages/staking/src/features/theme/colors.ts +++ b/packages/staking/src/features/theme/colors.ts @@ -1,6 +1,7 @@ import { darkColorScheme, laceGradient, lightColorScheme } from '@lace/ui'; export const colorsContract = { + $activityNoActivityTextColor: '', $bannerBellIconColor: '', $bannerInfoIconColor: '', $delegationCardInfoLabelColor: '', @@ -29,6 +30,7 @@ export const colorsContract = { }; export const lightThemeColors: typeof colorsContract = { + $activityNoActivityTextColor: lightColorScheme.$primary_dark_grey, $bannerBellIconColor: lightColorScheme.$primary_accent_purple, $bannerInfoIconColor: lightColorScheme.$primary_accent_purple, $delegationCardInfoLabelColor: lightColorScheme.$primary_dark_grey, @@ -57,6 +59,7 @@ export const lightThemeColors: typeof colorsContract = { }; export const darkThemeColors: typeof colorsContract = { + $activityNoActivityTextColor: darkColorScheme.$primary_light_grey, $bannerBellIconColor: darkColorScheme.$primary_accent_purple, $bannerInfoIconColor: darkColorScheme.$primary_accent_purple, $delegationCardInfoLabelColor: darkColorScheme.$primary_light_grey,