Skip to content

Commit

Permalink
Merge pull request #539 from Concordium/ui-update/setup-delegation-intro
Browse files Browse the repository at this point in the history
UI update/setup delegation intro
  • Loading branch information
soerenbf authored Oct 15, 2024
2 parents 21fcb5f + 23ded15 commit adb0dec
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ $standard-box-shadow: 0 0 15px 0 rgb(0 0 0 / $color-shadow-alpha);
&__credential-statement-container {
height: calc(100% - 115px);
scrollbar-gutter: stable;
padding: 0px 16px 0 32px;
padding: 0 16px 0 32px;
overflow-y: auto;
}

Expand All @@ -55,11 +55,14 @@ $standard-box-shadow: 0 0 15px 0 rgb(0 0 0 / $color-shadow-alpha);
margin: 0 0 0 8px;
}

&__back-icon, &__reject-icon.reject-title {
&__back-icon,
&__reject-icon.reject-title {
margin: 0 8px 0 0;
}

&__reject-icon, &__back-icon, &__continue-icon {
&__reject-icon,
&__back-icon,
&__continue-icon {
height: 15px;
width: 15px;

Expand Down Expand Up @@ -146,7 +149,7 @@ $standard-box-shadow: 0 0 15px 0 rgb(0 0 0 / $color-shadow-alpha);

&__modal {
border-radius: 16px;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.20);
box-shadow: 0 0 15px 0 rgb(0 0 0 / 20%);
width: 85%;
border: none;
}
Expand Down
17 changes: 13 additions & 4 deletions packages/browser-wallet/src/popup/popupX/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,21 +173,30 @@ export const relativeRoutes = {
},
};

const buildAbsoluteRoutes = <R extends RouteNode | RoutePath | RouteChildren>(route: R, base?: string): R => {
/**
* The temporary prefix for all wallet-x routes in the application.
*/
export const routePrefix = '/walletX'; // FIXME: Remove hardcoded walletX prefix.

const buildAbsoluteRoutes = <R extends RouteNode | RoutePath | RouteChildren>(
route: R,
root = true,
base?: string
): R => {
const { path, config, ...rs } = route;

let aPath = path as string | undefined;

if (base === '/') {
aPath = `/${path}`;
if (root) {
aPath = routePrefix; // FIXME: Remove hardcoded walletX prefix.
} else if (base !== undefined) {
aPath = `${base}/${path}`;
}

return Object.entries(rs).reduce(
(acc, [k, r]) => ({
...acc,
[k]: buildAbsoluteRoutes(r as R, aPath),
[k]: buildAbsoluteRoutes(r as R, false, aPath),
}),
{ path: aPath }
) as R;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@

&_container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex-flow: row wrap;
justify-content: flex-start;
width: rem(324px);
margin: 0 auto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Restore from '@assets/svgX/arrow-counter-clock.svg';
import IconButton from '@popup/shared/IconButton';
import Text from '@popup/popupX/shared/Text';
import { Link } from 'react-router-dom';
import { relativeRoutes } from '@popup/popupX/constants/routes';
import { absoluteRoutes, relativeRoutes } from '@popup/popupX/constants/routes';
import { useTranslation } from 'react-i18next';

type MenuTilesProps = {
Expand Down Expand Up @@ -43,7 +43,7 @@ export default function MenuTiles({ menuOpen, setMenuOpen }: MenuTilesProps) {
<Text.Capture>{t('accounts')}</Text.Capture>
</IconButton>
</Link>
<Link to={relativeRoutes.settings.seedPhrase.path}>
<Link to="/">
<IconButton className="main-header__menu-tiles_tile">
<TextColumns />
<Text.Capture>{t('seedPhrase')}</Text.Capture>
Expand All @@ -55,13 +55,13 @@ export default function MenuTiles({ menuOpen, setMenuOpen }: MenuTilesProps) {
<Text.Capture>{t('passcode')}</Text.Capture>
</IconButton>
</Link>
<Link to={relativeRoutes.settings.web3Id.path}>
<Link to={absoluteRoutes.settings.web3Id.path}>
<IconButton className="main-header__menu-tiles_tile">
<WebId />
<Text.Capture>{t('web3Id')}</Text.Capture>
</IconButton>
</Link>
<Link to="/">
<Link to={absoluteRoutes.settings.earn.path}>
<IconButton className="main-header__menu-tiles_tile">
<Plant />
<Text.Capture>{t('earn')}</Text.Capture>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import Carousel from '@popup/popupX/shared/Carousel';
import { relativeRoutes } from '@popup/popupX/constants/routes';
import { useNavigate } from 'react-router-dom';

export default function BakerIntro() {
const nav = useNavigate();
return (
<div className="baker-intro-container">
<div className="baker-intro__title">
<span className="heading_medium">Become a baker</span>
</div>
<Carousel>
<Carousel onDone={() => nav(`../${relativeRoutes.settings.earn.baker.register}`)}>
<span className="capture__main_small">
<div>
A baker is a mode that participates in the network by baking (creating) new blocks that are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,4 @@
flex-direction: column;
height: 100%;
padding-bottom: rem(48px);

.capture__main_small {
display: flex;
flex-direction: column;
gap: rem(16px);
}

a.capture__main_small {
text-decoration: underline;

&:hover {
color: $color-white;
}
}

.delegator-intro {
&__title {
margin-bottom: rem(12px);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,78 @@
import React from 'react';
import Carousel from '@popup/popupX/shared/Carousel';
import { useNavigate } from 'react-router-dom';
import { absoluteRoutes } from '@popup/popupX/constants/routes';
import Page from '@popup/popupX/shared/Page';
import { Trans, useTranslation } from 'react-i18next';
import ExternalLink from '@popup/popupX/shared/ExternalLink';

export default function DelegatorIntro() {
const nav = useNavigate();
const { t } = useTranslation('x', { keyPrefix: 'earn.delegator.intro' });
return (
<div className="delegator-intro-container">
<div className="delegator-intro__title">
<span className="heading_medium">Delegation</span>
</div>
<Carousel>
<Page className="delegator-intro-container">
<Carousel onDone={() => nav(absoluteRoutes.settings.earn.delegator.type.path)}>
<span className="capture__main_small">
<div>
Delegation allows users on the Concordium blockchain to earn rewards without the need to become
a validator or run a node.
</div>
<div>By delegating some of your funds to a pool, you can earn rewards.</div>
<div>
On the next few pages, we will go through the basics of delegation. If you want to learn more,
you can visit our
<a
className="capture__main_small"
href="https://developer.concordium.software/en/mainnet/net/concepts/concepts-delegation.html"
>
documentation website
</a>
</div>
<Page.Top heading={t('1.title')} />
<Trans
t={t}
i18nKey="1.body"
components={{
'1': (
<ExternalLink path="https://developer.concordium.software/en/mainnet/net/concepts/concepts-delegation.html" />
),
}}
/>
</span>
<span className="capture__main_small">
<div>
To become a delegator you must run a node on the Concordium blockchain. Make sure that you have
a setup where the node can operate around the clock.
</div>
<div>
You can run the node yourself or use a third-party provider. Make sure your account in the
wallet has the required amount of CCD to become a delegator.
</div>
<Page.Top heading={t('2.title')} />
<Trans
t={t}
i18nKey="2.body"
components={{
ul: <ul />,
li: <li />,
'1': (
<ExternalLink path="https://developer.concordium.software/en/mainnet/net/concepts/concepts-delegation.html" />
),
}}
/>
</span>
<span className="capture__main_small">
<div>
You have the option when adding a delegator to open a staking pool or not. A staking pool allows
others who want to earn rewards to do so without the need to run a node or become a delegator
themselves.
</div>
<div>
To do this they delegate an amount to your staking pool which then increases your total stake
and your chances of winning the lottery to bake a block. At each pay day the rewards will be
distributed to you and your delegators.
</div>
<div>
You can also choose not to open a pool, in which case only your own stake applies toward the
lottery. You can always open or close a pool later.
</div>
<Page.Top heading={t('3.title')} />
<Trans
t={t}
i18nKey="3.body"
components={{
ul: <ul />,
li: <li />,
'1': (
<ExternalLink path="https://developer.concordium.software/en/mainnet/net/concepts/concepts-delegation.html" />
),
}}
/>
</span>
<span className="capture__main_small">
<Page.Top heading={t('4.title')} />
<Trans t={t} i18nKey="4.body" />
</span>
<span className="capture__main_small">
<Page.Top heading={t('5.title')} />
<Trans
t={t}
i18nKey="5.body"
components={{
'1': (
<ExternalLink path="https://developer.concordium.software/en/mainnet/net/concepts/concepts-delegation.html" />
),
}}
/>
</span>
<span className="capture__main_small">
<Page.Top heading={t('6.title')} />
<Trans t={t} i18nKey="6.body" />
</span>
</Carousel>
</div>
</Page>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { cpBakingThreshold } from '@shared/utils/chain-parameters-helpers';
import { displayAsCcd } from 'wallet-common-helpers';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { absoluteRoutes, relativePath } from '@popup/popupX/constants/routes';
import { absoluteRoutes } from '@popup/popupX/constants/routes';

export default function EarningRewards() {
const { t } = useTranslation('x', { keyPrefix: 'earn.root' });
Expand All @@ -24,31 +24,21 @@ export default function EarningRewards() {
<Page.Top heading="Earning Rewards" />
<Page.Main>
<div className="earn__card">
<span className="text__main">{t('bakerTitle')}</span>
<span className="text__main">{t('validatorTitle')}</span>
<span className="capture__main_small">
{t('bakerDescription', { amount: displayAsCcd(bakingThreshold, false) })}
{t('validatorDescription', { amount: displayAsCcd(bakingThreshold, false) })}
</span>
<Link
to={relativePath(
absoluteRoutes.settings.earn.path,
absoluteRoutes.settings.earn.baker.intro.path
)}
>
<Link to={absoluteRoutes.settings.earn.baker.intro.path}>
<div className="earn__card_continue">
<span className="label__regular">{t('bakerAction')}</span>
<span className="label__regular">{t('validatorAction')}</span>
<ArrowRight />
</div>
</Link>
</div>
<div className="earn__card">
<span className="text__main">{t('delegationTitle')}</span>
<span className="capture__main_small">{t('delegationDescription')}</span>
<Link
to={relativePath(
absoluteRoutes.settings.earn.path,
absoluteRoutes.settings.earn.delegator.intro.path
)}
>
<Link to={absoluteRoutes.settings.earn.delegator.intro.path}>
<div className="earn__card_continue">
<span className="label__regular">{t('delegationAction')}</span>
<ArrowRight />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
const t = {
root: {
bakerTitle: 'Validation',
bakerDescription:
'As a baker, you can participate in the network by baking blocks on the Concordium network. This requires a minimum of {{amount}} CCD and access to a dedicated node.',
bakerAction: 'Continue to validation setup',
validatorTitle: 'Validation',
validatorDescription:
'As a validator, you can participate in the network by baking blocks on the Concordium network. This requires a minimum of {{amount}} CCD and access to a dedicated node.',
validatorAction: 'Continue to validation setup',
delegationTitle: 'Delegation',
delegationDescription:
'If you don’t have access to your own node, you may delegate your stake to one of the other bakers. There is no minimum amount of CCD required when delegating.',
'If you don’t have access to your own node, you may delegate your stake to one of the other validators. There is no minimum amount of CCD required when delegating.',
delegationAction: 'Continue to delegation setup',
note: 'Please note, a single account cannot both be a baker and a delegator, but it is possible to stop one and change to the other.',
note: 'Please note, a single account cannot both be a validator and a delegator, but it is possible to stop one and change to the other.',
},
delegator: {
intro: {
'1': {
title: 'Delegation',
body: 'Delegation allows users on the Concordium blockchain to earn rewards without the need to become a validator or run a node.\n\nBy delegating some of your funds to a pool, you can earn rewards.\n\nOn the next few pages, we will go through the basics of delegation. If you want to learn more, you can visit our <1>documentation website</1>.',
},
'2': {
title: 'Delegation models',
body: "There are two staking models that a delegator can choose:<ul><li>Delegating to a specific pool</li><li>Passive delegation</li></ul>A staking pool is managed by an individual validator running a node, so the rewards depend on that validator's performance.\n\nSince passive delegation doesn't go to a specific pool, it mitigates the risk of a single validator performing badly, however, the rewards are lower.\n\nFor more info, visit our <1>documentation website</1>",
},
'3': {
title: 'Staking pools',
body: "A staking pool is managed by an individual validator.\n\nRunning a pool allows a validator to attract more stake and thus increase chances of being selected to produce a block.\n\nValidators earn a commission from the delegators upon producing a block.\n\nDelegating to a staking pool is usually more profitable than passive delegation, but there is also a risk of losing out on rewards if the validator is not running properly. It is therefore a good idea to keep an eye on the validator's performance.\n\nYou can read more about how to investigate a validator's performance on our <1>documentation website</1>.",
},
'4': {
title: 'Passive delegation',
body: 'For CCD holders who do not want to regularly check the performance of a chosen pool, but just want a stable way of earning rewards, passive delegation offers a low-risk, low-reward alternative.\n\nThis staking strategy is not associated with a specific validator, so there is no risk of poor validator health.\n\nThe trade-off when choosing passive delegation is that the return on your stake will be less than what you may receive when delegating to a specific staking pool.',
},
'5': {
title: 'Pay days',
body: 'Whether you choose an individual validation pool or passive delegation, rewards are paid out at what is called the pay day. Rewards are distributed to everyone in the pool proportional to their stake, and a commission is paid to the validator by all delegators.\n\nIf you make updates to your delegation at a later point, most of these will also take effect from the next pay day.\n\nTo read more about the pay day, you can visit our <1>documentation website</1>.',
},
'6': {
title: 'Lock-ins and cool-downs',
body: 'When you make a delegation to either type of pool, your delegation amount will be locked on your account.\n\nThis means that you cannot use the amount for anything while it is still locked in for delegation.\n\nIf you decrease your delegation amount or stop the delegation altogether, the amount will still be locked for a cool-down period.\n\nAs transactions cost a fee, it is important to take into consideration that you will need some unlocked funds on your public balance to pay the fee for unlocking your delegation amount again.',
},
},
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
.seed-phrase-x {
.card-x.grey {
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex-flow: row wrap;
margin-top: rem(24px);
border: rem(1px) solid $color-input-border;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
}
}

&__icon {
&__icon,
&__text {
display: flex;
align-items: center;
justify-content: center;
Expand Down
Loading

0 comments on commit adb0dec

Please sign in to comment.