From c5c4ea3ecb460412c35cbaf8c288fb4eb2fb2bea Mon Sep 17 00:00:00 2001 From: arturdolzan Date: Wed, 15 Jan 2025 18:12:16 -0300 Subject: [PATCH] Add base files and menu for staking campaign --- .github/actions/deploy-portal/action.yml | 4 ++ .github/workflows/hostinger-deployment.yml | 1 + webapp/README.md | 5 ++ webapp/app/[locale]/_components/header.tsx | 4 ++ .../navbar/_components/navItem.tsx | 10 +++- .../app/[locale]/_components/navbar/index.tsx | 41 +++++++++++------ webapp/app/[locale]/stake/dashboard/page.tsx | 22 +++++++++ webapp/app/[locale]/stake/layout.tsx | 16 +++++++ webapp/app/[locale]/stake/page.tsx | 21 +++++++++ webapp/app/featureFlags.ts | 2 + webapp/app/stake/page.tsx | 5 ++ webapp/components/icons/stakeIcon.tsx | 18 ++++++++ webapp/components/stakeTabs.tsx | 46 +++++++++++++++++++ webapp/messages/en.json | 11 +++++ webapp/messages/es.json | 11 +++++ 15 files changed, 200 insertions(+), 17 deletions(-) create mode 100644 webapp/app/[locale]/stake/dashboard/page.tsx create mode 100644 webapp/app/[locale]/stake/layout.tsx create mode 100644 webapp/app/[locale]/stake/page.tsx create mode 100644 webapp/app/stake/page.tsx create mode 100644 webapp/components/icons/stakeIcon.tsx create mode 100644 webapp/components/stakeTabs.tsx diff --git a/.github/actions/deploy-portal/action.yml b/.github/actions/deploy-portal/action.yml index ada60342..166336ca 100644 --- a/.github/actions/deploy-portal/action.yml +++ b/.github/actions/deploy-portal/action.yml @@ -45,6 +45,9 @@ inputs: NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET: required: true description: Feature flag to enable Mainnet + NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN: + required: true + description: Feature flag to enable Stake Campaign NEXT_PUBLIC_SENTRY_DSN: required: false description: Sentry DSN URL @@ -83,6 +86,7 @@ runs: NEXT_PUBLIC_ENABLE_ANALYTICS: ${{ inputs.NEXT_PUBLIC_ENABLE_ANALYTICS }} NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL: ${{ inputs.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL }} NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET: ${{ inputs.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET }} + NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN: ${{ inputs.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN }} NEXT_PUBLIC_SENTRY_DSN: ${{ inputs.NEXT_PUBLIC_SENTRY_DSN }} NEXT_PUBLIC_TRACES_SAMPLE_RATE: ${{ inputs.NEXT_PUBLIC_TRACES_SAMPLE_RATE }} SENTRY_AUTH_TOKEN: ${{ inputs.SENTRY_AUTH_TOKEN }} diff --git a/.github/workflows/hostinger-deployment.yml b/.github/workflows/hostinger-deployment.yml index 104b0abd..33aa3344 100644 --- a/.github/workflows/hostinger-deployment.yml +++ b/.github/workflows/hostinger-deployment.yml @@ -45,6 +45,7 @@ jobs: NEXT_PUBLIC_ENABLE_ANALYTICS: ${{ github.event_name == 'release' }} NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL: ${{ vars.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL || 'false' }} NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET: ${{ vars.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET || 'false' }} + NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN: ${{ vars.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN || 'false' }} NEXT_PUBLIC_SENTRY_DSN: ${{ vars.NEXT_PUBLIC_SENTRY_DSN }} NEXT_PUBLIC_TRACES_SAMPLE_RATE: ${{ vars.NEXT_PUBLIC_TRACES_SAMPLE_RATE }} SENTRY_AUTH_TOKEN: ${{ github.event_name == 'release' && secrets.SENTRY_AUTH_TOKEN_PROD || '' }} # TODO: ASK OP TO MOVE TO ENV SECRETS diff --git a/webapp/README.md b/webapp/README.md index 221b295d..5777bd22 100644 --- a/webapp/README.md +++ b/webapp/README.md @@ -16,6 +16,11 @@ NEXT_PUBLIC_WORKERS_DEBUG_ENABLE= # enable logging on web workers NEXT_PUBLIC_ENABLE_ANALYTICS= # Enable Analytics with Umami NEXT_PUBLIC_ANALYTICS_URL= # Umami analytics URL NEXT_PUBLIC_ANALYTICS_WEBSITE_ID= # Umami website ID +# These env variables are required for Enabling the fallowing features +NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL= # Enable BTC tunnel +NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET= # Enable mainnet network +NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN= # Enable Staking Campaign + # The following variables could be used to customize the contracts addresses used by Hemi (for example, for testing with a forked blockchain): NEXT_PUBLIC_ADDRESS_MANAGER=
NEXT_PUBLIC_L2_BRIDGE=
diff --git a/webapp/app/[locale]/_components/header.tsx b/webapp/app/[locale]/_components/header.tsx index e63ca8aa..e182496e 100644 --- a/webapp/app/[locale]/_components/header.tsx +++ b/webapp/app/[locale]/_components/header.tsx @@ -1,6 +1,7 @@ import { CloseIcon } from 'components/icons/closeIcon' import { HamburgerIcon } from 'components/icons/hamburgerIcon' import { Link } from 'components/link' +import { StakeTabs } from 'components/stakeTabs' import { TunnelTabs } from 'components/tunnelTabs' import { useTunnelOperationByConnectedWallet } from 'hooks/useTunnelOperationByConnectedWallet' import dynamic from 'next/dynamic' @@ -32,6 +33,9 @@ export const Header = function ({ isMenuOpen, toggleMenu }: Props) { +
+ +
diff --git a/webapp/app/[locale]/_components/navbar/_components/navItem.tsx b/webapp/app/[locale]/_components/navbar/_components/navItem.tsx index 91f1fb94..6e6ff36e 100644 --- a/webapp/app/[locale]/_components/navbar/_components/navItem.tsx +++ b/webapp/app/[locale]/_components/navbar/_components/navItem.tsx @@ -16,13 +16,15 @@ import { usePathname } from 'next/navigation' import { useLocale } from 'next-intl' import { ComponentProps, MutableRefObject, ReactNode, useState } from 'react' import { useOnClickOutside } from 'ui-common/hooks/useOnClickOutside' +import { UrlObject } from 'url' import { isRelativeUrl } from 'utils/url' type Props = { - event: AnalyticsEventsWithChain + event?: AnalyticsEventsWithChain icon?: ReactNode rightSection?: ReactNode text: string + urlToBeSelected?: string | UrlObject } type Selectable = { selected?: boolean } @@ -129,13 +131,17 @@ const PageLink = function ({ icon, rightSection, text, + urlToBeSelected = href, }: ItemLinkProps) { const locale = useLocale() const [networkType] = useNetworkType() const pathname = usePathname() const { track } = useUmami() - const selected = pathname.startsWith(`/${locale}${href}`) + const selected = + typeof urlToBeSelected === 'string' + ? pathname.startsWith(`/${locale}${urlToBeSelected}`) + : pathname.startsWith(`/${locale}${urlToBeSelected.pathname}`) return (
  • + {featureFlags.stakeCampaignEnabled && ( + } + text={t('stake')} + urlToBeSelected="/stake" + /> + )} +
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • } @@ -115,10 +126,10 @@ export const Navbar = function () { text={t('tools')} />
  • -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • {featureFlags.mainnetEnabled && ( -
  • +
  • )} -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • diff --git a/webapp/app/[locale]/stake/dashboard/page.tsx b/webapp/app/[locale]/stake/dashboard/page.tsx new file mode 100644 index 00000000..e6c2ff88 --- /dev/null +++ b/webapp/app/[locale]/stake/dashboard/page.tsx @@ -0,0 +1,22 @@ +'use client' + +import { featureFlags } from 'app/featureFlags' +import { PageTitle } from 'components/pageTitle' +import { useTranslations } from 'next-intl' + +const Page = function () { + const t = useTranslations('stake-page') + + if (!featureFlags.stakeCampaignEnabled) return null + + return ( +
    + +
    + ) +} + +export default Page diff --git a/webapp/app/[locale]/stake/layout.tsx b/webapp/app/[locale]/stake/layout.tsx new file mode 100644 index 00000000..1f9f22d8 --- /dev/null +++ b/webapp/app/[locale]/stake/layout.tsx @@ -0,0 +1,16 @@ +import { StakeTabs } from 'components/stakeTabs' + +type Props = { + children: React.ReactNode +} + +const Layout = ({ children }: Props) => ( + <> +
    + +
    + {children} + +) + +export default Layout diff --git a/webapp/app/[locale]/stake/page.tsx b/webapp/app/[locale]/stake/page.tsx new file mode 100644 index 00000000..c6395857 --- /dev/null +++ b/webapp/app/[locale]/stake/page.tsx @@ -0,0 +1,21 @@ +'use client' + +import { featureFlags } from 'app/featureFlags' +import { PageTitle } from 'components/pageTitle' +import { useTranslations } from 'next-intl' + +const Stake = function () { + const t = useTranslations('stake-page') + + if (!featureFlags.stakeCampaignEnabled) return null + + return ( +
    + +
    + ) +} + +export default function Page() { + return +} diff --git a/webapp/app/featureFlags.ts b/webapp/app/featureFlags.ts index bf48e0fe..abcf4e39 100644 --- a/webapp/app/featureFlags.ts +++ b/webapp/app/featureFlags.ts @@ -3,4 +3,6 @@ export const featureFlags = { process.env.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_BTC_TUNNEL === 'true', mainnetEnabled: process.env.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_MAINNET === 'true', + stakeCampaignEnabled: + process.env.NEXT_PUBLIC_FEATURE_FLAG_ENABLE_STAKE_CAMPAIGN === 'true', } diff --git a/webapp/app/stake/page.tsx b/webapp/app/stake/page.tsx new file mode 100644 index 00000000..c490aff5 --- /dev/null +++ b/webapp/app/stake/page.tsx @@ -0,0 +1,5 @@ +import { LocalePageRedirect } from 'components/localePageRedirect' + +const Page = () => + +export default Page diff --git a/webapp/components/icons/stakeIcon.tsx b/webapp/components/icons/stakeIcon.tsx new file mode 100644 index 00000000..36a654ab --- /dev/null +++ b/webapp/components/icons/stakeIcon.tsx @@ -0,0 +1,18 @@ +import { ComponentProps } from 'react' + +export const StakeIcon = (props: ComponentProps<'svg'>) => ( + + + +) diff --git a/webapp/components/stakeTabs.tsx b/webapp/components/stakeTabs.tsx new file mode 100644 index 00000000..96c187ca --- /dev/null +++ b/webapp/components/stakeTabs.tsx @@ -0,0 +1,46 @@ +'use client' + +import { featureFlags } from 'app/featureFlags' +import { Tab, Tabs } from 'components/tabs' +import { usePathname } from 'next/navigation' +import { useLocale, useTranslations } from 'next-intl' +import { Suspense } from 'react' + +const StakeTabsImpl = function () { + const locale = useLocale() + const pathname = usePathname() + const t = useTranslations('stake-page') + + if ( + !pathname.startsWith(`/${locale}/stake/`) || + !featureFlags.stakeCampaignEnabled + ) { + return null + } + + const isInDashboard = pathname === `/${locale}/stake/dashboard/` + const isInStake = pathname === `/${locale}/stake/` + + return ( +
    + + +
    + {t('dashboard.title')} +
    +
    + + + {t('stake.title')} + + +
    +
    + ) +} + +export const StakeTabs = () => ( + + + +) diff --git a/webapp/messages/en.json b/webapp/messages/en.json index a6d7e169..1eef602e 100644 --- a/webapp/messages/en.json +++ b/webapp/messages/en.json @@ -172,10 +172,21 @@ "hemidocs": "Hemi Docs", "network-status": "Network Status", "swap": "Swap", + "stake": "Stake", "tools": "Tools", "tunnel": "Tunnel", "web-pop-miner": "Web PoP Miner" }, + "stake-page": { + "dashboard": { + "subtitle": "Stake your assets to earn rewards and boost your points.", + "title": "Dashboard" + }, + "stake": { + "subtitle": "Stake assets to earn points and rewards.", + "title": "Stake" + } + }, "token-custom-drawer": { "add-contract-to-preview": "Add a contract address to preview the token...", "add-this-pair": "Add this pair to Hemi’s token list for everyone to tunnel", diff --git a/webapp/messages/es.json b/webapp/messages/es.json index d3f38a41..3492bf8b 100644 --- a/webapp/messages/es.json +++ b/webapp/messages/es.json @@ -172,10 +172,21 @@ "hemidocs": "Documentación de Hemi", "network-status": "Estado de la red", "swap": "Intercambiar", + "stake": "Apostar", "tools": "Herramientas", "tunnel": "Túnel", "web-pop-miner": "Minero PoP Web" }, + "stake-page": { + "dashboard": { + "subtitle": "Apueste sus activos para ganar recompensas y aumentar tus puntos.", + "title": "Panel" + }, + "stake": { + "subtitle": "Apueste activos para ganar puntos y recompensas.", + "title": "Apostar" + } + }, "token-custom-drawer": { "add-contract-to-preview": "Añada una dirección de contrato para previsualizar el token...", "add-this-pair": "Agregue este par a la lista de tokens de Hemi para que todos puedan tunelizarlos",