diff --git a/package.json b/package.json
index c271bf8..d99fab9 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"@dydxprotocol/v4-localization": "^1.1.5",
"@ethersproject/providers": "^5.7.2",
"@js-joda/core": "^5.5.3",
+ "@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 552ea95..67939f7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,9 +1,5 @@
lockfileVersion: '6.0'
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
dependencies:
'@0xsquid/sdk':
specifier: ^1.10.0
@@ -41,6 +37,9 @@ dependencies:
'@js-joda/core':
specifier: ^5.5.3
version: 5.5.3
+ '@radix-ui/react-accordion':
+ specifier: ^1.1.2
+ version: 1.1.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-checkbox':
specifier: ^1.0.4
version: 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
@@ -2320,6 +2319,35 @@ packages:
'@babel/runtime': 7.22.10
dev: false
+ /@radix-ui/react-accordion@1.1.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.10
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collapsible': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.14)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0)
+ '@types/react': 18.2.14
+ '@types/react-dom': 18.2.6
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
peerDependencies:
@@ -11748,8 +11776,8 @@ packages:
engines: {node: '>=10.5.0'}
dev: true
- /node-fetch-native@1.4.1:
- resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==}
+ /node-fetch-native@1.6.1:
+ resolution: {integrity: sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==}
dev: false
/node-fetch-native@1.6.1:
@@ -11899,7 +11927,7 @@ packages:
resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==}
dependencies:
destr: 2.0.2
- node-fetch-native: 1.4.1
+ node-fetch-native: 1.6.1
ufo: 1.3.2
dev: false
@@ -13787,7 +13815,7 @@ packages:
consola: 3.2.3
defu: 6.1.3
mime: 3.0.0
- node-fetch-native: 1.4.1
+ node-fetch-native: 1.6.1
pathe: 1.1.1
dev: false
@@ -13910,7 +13938,7 @@ packages:
listhen: 1.5.5
lru-cache: 10.1.0
mri: 1.2.0
- node-fetch-native: 1.4.1
+ node-fetch-native: 1.6.1
ofetch: 1.3.3
ufo: 1.3.2
transitivePeerDependencies:
@@ -14726,3 +14754,7 @@ packages:
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: true
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
diff --git a/src/components/Accordion.tsx b/src/components/Accordion.tsx
new file mode 100644
index 0000000..b65c90e
--- /dev/null
+++ b/src/components/Accordion.tsx
@@ -0,0 +1,119 @@
+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 { PlusIcon } from '@/icons';
+
+export type AccordionItem = {
+ header: React.ReactNode;
+ content: React.ReactNode;
+};
+
+type AccordionProps = {
+ items: AccordionItem[];
+ className?: string;
+};
+
+export const Accordion = ({ items, className }: AccordionProps) => (
+
+ {items.map(({ header, content }, idx) => (
+
+
+ {content}
+
+ ))}
+
+);
+
+const Styled: Record = {};
+
+Styled.Root = styled(Root)`
+ > *:not(:last-child) {
+ border-bottom: var(--border-width) solid var(--border-color);
+ }
+`;
+
+Styled.Item = styled(Item)``;
+
+Styled.Icon = styled.div`
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+
+ width: 2.25rem;
+ height: 2.25rem;
+
+ --color-border: var(--color-layer-6);
+ color: var(--color-text-1);
+ background-color: var(--color-layer-5);
+ border: solid var(--border-width) var(--color-border);
+ border-radius: 50%;
+ font: var(--font-small-book);
+
+ svg {
+ height: 1.125em;
+ width: 1.125em;
+ }
+`;
+
+Styled.Trigger = styled(Trigger)`
+ ${layoutMixins.spacedRow}
+ width: 100%;
+ padding: 1rem 0.75rem;
+
+ color: var(--color-text-1);
+ text-align: start;
+
+ &:hover {
+ ${Styled.Icon} {
+ color: var(--color-text-2);
+ filter: brightness(1.1);
+ }
+ }
+
+ svg {
+ color: var(--color-text-0);
+ transition: transform 0.3s var(--ease-out-expo);
+ }
+
+ &[data-state='open'] svg {
+ transform: rotate(45deg);
+ }
+`;
+
+Styled.Content = styled(Content)`
+ overflow: hidden;
+ margin: 0 0.75rem 1rem;
+
+ color: var(--color-text-0);
+
+ &[data-state='open'] {
+ animation: ${keyframes`
+ from {
+ height: 0;
+ }
+ to {
+ height: var(--radix-accordion-content-height);
+ }
+ `} 0.3s var(--ease-out-expo);
+ }
+
+ &[data-state='closed'] {
+ animation: ${keyframes`
+ from {
+ height: var(--radix-accordion-content-height);
+ }
+ to {
+ height: 0;
+ }
+ `} 0.1s var(--ease-in-expo);
+ }
+`;
diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx
index d5f5d64..d8db86f 100644
--- a/src/components/Icon.tsx
+++ b/src/components/Icon.tsx
@@ -55,6 +55,7 @@ import {
OverviewIcon,
PencilIcon,
PlayIcon,
+ PlusIcon,
PositionsIcon,
PriceChartIcon,
PrivacyIcon,
@@ -130,6 +131,7 @@ export enum IconName {
Overview = 'Overview',
Pencil = 'Pencil',
Play = 'Play',
+ Plus = 'Plus',
Positions = 'Positions',
PriceChart = 'PriceChart',
Privacy = 'Privacy',
@@ -204,6 +206,7 @@ const icons = {
[IconName.Overview]: OverviewIcon,
[IconName.Pencil]: PencilIcon,
[IconName.Play]: PlayIcon,
+ [IconName.Plus]: PlusIcon,
[IconName.Positions]: PositionsIcon,
[IconName.PriceChart]: PriceChartIcon,
[IconName.Privacy]: PrivacyIcon,
diff --git a/src/icons/index.ts b/src/icons/index.ts
index a32913e..bd3b347 100644
--- a/src/icons/index.ts
+++ b/src/icons/index.ts
@@ -44,6 +44,7 @@ export { default as OrderbookIcon } from './orderbook.svg';
export { default as OverviewIcon } from './overview.svg';
export { default as PencilIcon } from './pencil.svg';
export { default as PlayIcon } from './play.svg';
+export { default as PlusIcon } from './plus.svg';
export { default as PortfolioIcon } from './portfolio.svg';
export { default as PositionsIcon } from './positions.svg';
export { default as PriceChartIcon } from './price-chart.svg';
diff --git a/src/icons/plus.svg b/src/icons/plus.svg
new file mode 100644
index 0000000..c74751a
--- /dev/null
+++ b/src/icons/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/pages/rewards/RewardsHelpPanel.tsx b/src/pages/rewards/RewardsHelpPanel.tsx
new file mode 100644
index 0000000..e7c23d6
--- /dev/null
+++ b/src/pages/rewards/RewardsHelpPanel.tsx
@@ -0,0 +1,80 @@
+import styled, { AnyStyledComponent } from 'styled-components';
+
+import { STRING_KEYS } from '@/constants/localization';
+import { layoutMixins } from '@/styles/layoutMixins';
+import { useStringGetter } from '@/hooks';
+
+import { Accordion } from '@/components/Accordion';
+import { Link } from '@/components/Link';
+import { Panel } from '@/components/Panel';
+
+const REWARDS_LEARN_MORE_LINK = ''; // to be configured
+
+export const RewardsHelpPanel = () => {
+ const stringGetter = useStringGetter();
+
+ return (
+
+ {stringGetter({ key: STRING_KEYS.HELP })}
+ {REWARDS_LEARN_MORE_LINK && (
+
+ {stringGetter({ key: STRING_KEYS.LEARN_MORE })}
+
+ )}
+
+ }
+ >
+
+
+ );
+};
+
+const Styled: Record = {};
+
+Styled.HelpCard = styled(Panel)`
+ --panel-content-paddingY: 0;
+ width: 100%;
+ height: max-content;
+ padding: 0;
+ gap: 0;
+
+ text-align: start;
+`;
+
+Styled.Header = styled.div`
+ ${layoutMixins.spacedRow}
+ gap: 1ch;
+
+ padding: 1.25rem 1.5rem;
+ border-bottom: var(--border-width) solid var(--border-color);
+
+ font: var(--font-small-book);
+
+ h3 {
+ font: var(--font-medium-book);
+ color: var(--color-text-2);
+ }
+`;
+
+Styled.Link = styled(Link)`
+ display: inline-flex;
+`;