From b2234cb9697e39b17567a8b963f801c722451468 Mon Sep 17 00:00:00 2001 From: aleka Date: Tue, 9 Jan 2024 16:57:02 -0500 Subject: [PATCH] reorganize rewards vs. profile, update panel and accordion styling (#221) * reorganize rewards vs. profile, update panel and accordion styling * feedback --- src/components/Accordion.stories.tsx | 26 ++++++++++ src/components/Accordion.tsx | 16 ++++-- src/components/Panel.tsx | 7 +++ src/icons/caret-down.svg | 4 +- src/pages/Profile.tsx | 42 +++++++++++----- src/pages/rewards/DYDXBalancePanel.tsx | 14 +----- src/pages/rewards/LaunchIncentivesPanel.tsx | 15 ++---- src/pages/rewards/MigratePanel.tsx | 16 ++---- src/pages/rewards/RewardsHelpPanel.tsx | 8 ++- src/pages/rewards/RewardsPage.tsx | 56 ++++++++++++++------- 10 files changed, 134 insertions(+), 70 deletions(-) create mode 100644 src/components/Accordion.stories.tsx diff --git a/src/components/Accordion.stories.tsx b/src/components/Accordion.stories.tsx new file mode 100644 index 0000000..be7b479 --- /dev/null +++ b/src/components/Accordion.stories.tsx @@ -0,0 +1,26 @@ +import type { Story } from '@ladle/react'; + +import { Accordion as AccordionComponent, AccordionProps } from '@/components/Accordion'; + +import { StoryWrapper } from '.ladle/components'; + +export const Accordion: Story = (args) => { + return ( + + + + ); +}; + +Accordion.args = { + items: [ + { + header: 'Question 1?', + content: 'Answer 1.', + }, + { + header: 'Question 2?', + content: 'Answer 2.', + }, + ], +}; \ No newline at end of file diff --git a/src/components/Accordion.tsx b/src/components/Accordion.tsx index b65c90e..a3b5dee 100644 --- a/src/components/Accordion.tsx +++ b/src/components/Accordion.tsx @@ -3,6 +3,8 @@ import styled, { keyframes, type AnyStyledComponent } from 'styled-components'; import { Root, Item, Header, Trigger, Content } from '@radix-ui/react-accordion'; import { layoutMixins } from '@/styles/layoutMixins'; +import { breakpoints } from '@/styles'; + import { PlusIcon } from '@/icons'; export type AccordionItem = { @@ -10,7 +12,7 @@ export type AccordionItem = { content: React.ReactNode; }; -type AccordionProps = { +export type AccordionProps = { items: AccordionItem[]; className?: string; }; @@ -36,6 +38,13 @@ export const Accordion = ({ items, className }: AccordionProps) => ( const Styled: Record = {}; Styled.Root = styled(Root)` + --accordion-paddingY: 1rem; + --accordion-paddingX: 1rem; + + @media ${breakpoints.notTablet} { + --accordion-paddingX: 1.5rem; + } + > *:not(:last-child) { border-bottom: var(--border-width) solid var(--border-color); } @@ -67,7 +76,8 @@ Styled.Icon = styled.div` Styled.Trigger = styled(Trigger)` ${layoutMixins.spacedRow} width: 100%; - padding: 1rem 0.75rem; + padding: var(--accordion-paddingY) var(--accordion-paddingX); + gap: 0.5rem; color: var(--color-text-1); text-align: start; @@ -91,7 +101,7 @@ Styled.Trigger = styled(Trigger)` Styled.Content = styled(Content)` overflow: hidden; - margin: 0 0.75rem 1rem; + margin: 0 var(--accordion-paddingX) var(--accordion-paddingY); color: var(--color-text-0); diff --git a/src/components/Panel.tsx b/src/components/Panel.tsx index e7b1cd0..6582769 100644 --- a/src/components/Panel.tsx +++ b/src/components/Panel.tsx @@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'; import { Icon, IconName } from '@/components/Icon'; import { layoutMixins } from '@/styles/layoutMixins'; +import { breakpoints } from '@/styles'; type PanelProps = { slotHeaderContent?: string; @@ -67,6 +68,12 @@ Styled.Panel = styled.section<{ onClick?: () => void }>` --panel-content-paddingY: var(--panel-paddingY); --panel-content-paddingX: var(--panel-paddingX); + @media ${breakpoints.notTablet} { + --panel-paddingX: 1.5rem; + --panel-paddingY: 1.25rem; + --panel-content-paddingY: 1rem; + } + ${layoutMixins.row} background-color: var(--color-layer-3); diff --git a/src/icons/caret-down.svg b/src/icons/caret-down.svg index 678fb0f..c55d391 100644 --- a/src/icons/caret-down.svg +++ b/src/icons/caret-down.svg @@ -1,3 +1 @@ - - - + \ No newline at end of file diff --git a/src/pages/Profile.tsx b/src/pages/Profile.tsx index a7f9a8e..2f9a0bd 100644 --- a/src/pages/Profile.tsx +++ b/src/pages/Profile.tsx @@ -30,6 +30,9 @@ import abacusStateManager from '@/lib/abacus'; import { isTruthy } from '@/lib/isTruthy'; import { truncateAddress } from '@/lib/wallet'; +import { DYDXBalancePanel } from './rewards/DYDXBalancePanel'; +import { MigratePanel } from './rewards/MigratePanel'; + const ENS_CHAIN_ID = 1; // Ethereum const Profile = () => { @@ -175,8 +178,27 @@ const Profile = () => { onClick={() => dispatch(openDialog({ type: DialogTypes.Help }))} /> + + + + + + { layout="grid" /> - - - * { + height: 100%; + } + dl { --details-grid-numColumns: 1; } diff --git a/src/pages/rewards/DYDXBalancePanel.tsx b/src/pages/rewards/DYDXBalancePanel.tsx index f5c6c60..5300fc2 100644 --- a/src/pages/rewards/DYDXBalancePanel.tsx +++ b/src/pages/rewards/DYDXBalancePanel.tsx @@ -2,7 +2,6 @@ import type { ElementType } from 'react'; import styled, { AnyStyledComponent } from 'styled-components'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; -import breakpoints from '@/styles/breakpoints'; import { layoutMixins } from '@/styles/layoutMixins'; import { useAccountBalance, useAccounts, useTokenConfigs, useStringGetter } from '@/hooks'; @@ -33,7 +32,7 @@ export const DYDXBalancePanel = () => { const { chainTokenLabel } = useTokenConfigs(); return ( - @@ -109,21 +108,12 @@ export const DYDXBalancePanel = () => { ]} /> - + ); }; const Styled: Record = {}; -Styled.Panel = styled(Panel)` - --panel-paddingX: 1.5rem; - - @media ${breakpoints.tablet} { - --panel-paddingY: 1.5rem; - --panel-content-paddingY: 1rem; - } -`; - Styled.Header = styled.div` ${layoutMixins.spacedRow} gap: 1rem; diff --git a/src/pages/rewards/LaunchIncentivesPanel.tsx b/src/pages/rewards/LaunchIncentivesPanel.tsx index a5a59cb..e2e8bb7 100644 --- a/src/pages/rewards/LaunchIncentivesPanel.tsx +++ b/src/pages/rewards/LaunchIncentivesPanel.tsx @@ -70,10 +70,12 @@ const EstimatedRewards = () => { const { data, isLoading } = useQuery({ enabled: !!dydxAddress, - queryKey: `launch_incentives_rewards_${dydxAddress ?? ''}`, + queryKey: `launch_incentives_rewards_${dydxAddress ?? ''}_${SEASON_NUMBER}`, queryFn: async () => { if (!dydxAddress) return undefined; - const resp = await fetch(`https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}?n=${SEASON_NUMBER}`); + const resp = await fetch( + `https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}?n=${SEASON_NUMBER}` + ); return (await resp.json())?.incentivePoints; }, onError: (error: Error) => log('LaunchIncentives/fetchPoints', error), @@ -151,15 +153,8 @@ const LaunchIncentivesContent = () => { const Styled: Record = {}; Styled.Panel = styled(Panel)` - --panel-paddingY: 1rem; - --panel-paddingX: 1.5rem; - background-color: var(--color-layer-4); width: 100%; - - @media ${breakpoints.tablet} { - --panel-paddingY: 1.5rem; - } `; Styled.ForV4 = styled.span` @@ -223,7 +218,7 @@ Styled.Column = styled.div` Styled.EstimatedRewardsCard = styled.div` ${layoutMixins.spacedRow} padding: 1rem 1.25rem; - min-width: 21.25rem; + min-width: 19rem; height: calc(100% - calc(1.5rem * 2)); margin: 1.5rem; diff --git a/src/pages/rewards/MigratePanel.tsx b/src/pages/rewards/MigratePanel.tsx index f623082..38aacf1 100644 --- a/src/pages/rewards/MigratePanel.tsx +++ b/src/pages/rewards/MigratePanel.tsx @@ -7,8 +7,6 @@ import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons'; import { useAccountBalance, useBreakpoints, useStringGetter } from '@/hooks'; -import { breakpoints } from '@/styles'; - import { layoutMixins } from '@/styles/layoutMixins'; import { Details } from '@/components/Details'; @@ -28,7 +26,7 @@ import { MustBigNumber } from '@/lib/numbers'; const TOKEN_MIGRATION_LEARN_MORE_LINK = 'https://www.dydx.foundation/blog/update-on-exploring-the-future-of-dydx'; -export const MigratePanel = () => { +export const MigratePanel = ({ className }: { className?: string }) => { const { isNotTablet } = useBreakpoints(); const stringGetter = useStringGetter(); @@ -45,6 +43,7 @@ export const MigratePanel = () => { return isNotTablet ? ( {stringGetter({ key: STRING_KEYS.MIGRATE })}} slotRight={ @@ -74,6 +73,7 @@ export const MigratePanel = () => { ) : (

@@ -134,17 +134,11 @@ export const MigratePanel = () => { const Styled: Record = {}; Styled.MigratePanel = styled(Panel)` - --panel-paddingX: 1.5rem; width: 100%; background-image: url('/dots-background.svg'); background-position: right; background-repeat: no-repeat; - - @media ${breakpoints.tablet} { - --panel-paddingY: 1.5rem; - --panel-content-paddingY: 1rem; - } `; Styled.Title = styled.h3` @@ -157,7 +151,7 @@ Styled.Title = styled.h3` Styled.MigrateAction = styled.div` ${layoutMixins.flexEqualColumns} align-items: center; - margin-right: 1rem; + margin: 1rem; gap: 1rem; padding: 1rem; width: 100%; @@ -197,7 +191,7 @@ Styled.MobileMigrateHeader = styled.div` font: var(--font-small-book); color: var(--color-text-0); - padding: 1rem 1.5rem 0; + padding: 1rem 1rem 0; h3 { ${layoutMixins.inlineRow} diff --git a/src/pages/rewards/RewardsHelpPanel.tsx b/src/pages/rewards/RewardsHelpPanel.tsx index e7c23d6..ac26d95 100644 --- a/src/pages/rewards/RewardsHelpPanel.tsx +++ b/src/pages/rewards/RewardsHelpPanel.tsx @@ -1,5 +1,6 @@ import styled, { AnyStyledComponent } from 'styled-components'; +import { breakpoints } from '@/styles'; import { STRING_KEYS } from '@/constants/localization'; import { layoutMixins } from '@/styles/layoutMixins'; import { useStringGetter } from '@/hooks'; @@ -51,6 +52,7 @@ export const RewardsHelpPanel = () => { const Styled: Record = {}; Styled.HelpCard = styled(Panel)` + --panel-content-paddingX: 0; --panel-content-paddingY: 0; width: 100%; height: max-content; @@ -64,11 +66,15 @@ Styled.Header = styled.div` ${layoutMixins.spacedRow} gap: 1ch; - padding: 1.25rem 1.5rem; + padding: 1rem 1rem; border-bottom: var(--border-width) solid var(--border-color); font: var(--font-small-book); + @media ${breakpoints.notTablet} { + padding: 1.5rem 1.25rem; + } + h3 { font: var(--font-medium-book); color: var(--color-text-2); diff --git a/src/pages/rewards/RewardsPage.tsx b/src/pages/rewards/RewardsPage.tsx index 2476c0f..f69078a 100644 --- a/src/pages/rewards/RewardsPage.tsx +++ b/src/pages/rewards/RewardsPage.tsx @@ -1,15 +1,18 @@ import styled, { AnyStyledComponent } from 'styled-components'; import { useDispatch } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { STRING_KEYS } from '@/constants/localization'; import { ButtonAction, ButtonSize } from '@/constants/buttons'; import { DialogTypes } from '@/constants/dialogs'; +import { AppRoute } from '@/constants/routes'; import { useBreakpoints, useStringGetter, useURLConfigs } from '@/hooks'; import { breakpoints } from '@/styles'; import { layoutMixins } from '@/styles/layoutMixins'; +import { BackButton } from '@/components/BackButton'; import { Panel } from '@/components/Panel'; import { IconName } from '@/components/Icon'; import { IconButton } from '@/components/IconButton'; @@ -20,12 +23,14 @@ import { openDialog } from '@/state/dialogs'; import { DYDXBalancePanel } from './DYDXBalancePanel'; import { MigratePanel } from './MigratePanel'; import { LaunchIncentivesPanel } from './LaunchIncentivesPanel'; +import { RewardsHelpPanel } from './RewardsHelpPanel'; const RewardsPage = () => { const dispatch = useDispatch(); const stringGetter = useStringGetter(); const { governanceLearnMore, stakingLearnMore } = useURLConfigs(); const { isTablet, isNotTablet } = useBreakpoints(); + const navigate = useNavigate(); const panelArrow = ( @@ -39,13 +44,16 @@ const RewardsPage = () => { return ( - {import.meta.env.VITE_V3_TOKEN_ADDRESS && } + {isTablet && ( + + navigate(AppRoute.Profile)} /> + {stringGetter({ key: STRING_KEYS.TRADING_REWARDS })} + + )} + {import.meta.env.VITE_V3_TOKEN_ADDRESS && isNotTablet && } {isTablet ? ( - <> - - - + ) : ( @@ -55,7 +63,9 @@ const RewardsPage = () => { {stringGetter({ key: STRING_KEYS.GOVERNANCE })}} + slotHeaderContent={ + {stringGetter({ key: STRING_KEYS.GOVERNANCE })} + } slotRight={panelArrow} onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))} > @@ -68,7 +78,9 @@ const RewardsPage = () => { {stringGetter({ key: STRING_KEYS.STAKING })}} + slotHeaderContent={ + {stringGetter({ key: STRING_KEYS.STAKING })} + } slotRight={panelArrow} onClick={() => dispatch(openDialog({ type: DialogTypes.ExternalNavKeplr }))} > @@ -80,6 +92,8 @@ const RewardsPage = () => { + + ); }; @@ -95,33 +109,41 @@ Styled.Page = styled.div` align-items: center; > * { - --content-max-width: 70rem; + --content-max-width: 80rem; max-width: min(calc(100vw - 4rem), var(--content-max-width)); } @media ${breakpoints.tablet} { - padding: 1.25rem; + --stickyArea-topHeight: var(--page-header-height-mobile); + padding: 0 1rem 1rem; > * { - max-width: calc(100vw - 2.5rem); + max-width: calc(100vw - 2rem); width: 100%; } } `; -Styled.Panel = styled(Panel)` - --panel-paddingX: 1.5rem; +Styled.MobileHeader = styled.header` + ${layoutMixins.contentSectionDetachedScrollable} + ${layoutMixins.stickyHeader} + z-index: 2; + padding: 1.25rem 0; + margin-bottom: -1.5rem; - @media ${breakpoints.tablet} { - --panel-paddingY: 1.5rem; - --panel-content-paddingY: 1rem; - } + font: var(--font-large-medium); + color: var(--color-text-2); + background-color: var(--color-layer-2); +`; + +Styled.Panel = styled(Panel)` + height: fit-content; `; Styled.Title = styled.h3` font: var(--font-medium-book); color: var(--color-text-2); - padding: 1rem 1.5rem 0; + margin-bottom: -1rem; `; Styled.Description = styled.div`