Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added dapp/frontend/src/assets/gateway-login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dapp/frontend/src/assets/gateway-parties.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added dapp/frontend/src/assets/wallet-picker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion dapp/frontend/src/components/CreateGrant/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Button } from '@/components/Button'
import { Details } from '@/components/CreateGrant/Details'
import { Preview } from '@/components/CreateGrant/Preview'
import { Schedule } from '@/components/CreateGrant/Schedule'
import { StepBar } from '@/components/CreateGrant/StepBar'
import {
initialScheduleForm,
type ScheduleForm,
Expand All @@ -16,6 +15,7 @@ import {
} from '@/components/CreateGrant/scheduleForm'
import { useFundingToken } from '@/components/CreateGrant/useFundingToken'
import { Modal } from '@/components/Modal'
import { StepBar } from '@/components/StepBar'
import { useBackend } from '@/providers/Backend'
import { useVestingStore } from '@/store/useVestingStore'
import { compareAmounts } from '@/utils/amount'
Expand Down
144 changes: 144 additions & 0 deletions dapp/frontend/src/components/TopBar/ConnectGuide.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { Steps } from '@ark-ui/react/steps'
import { useState } from 'react'
import gatewayLogin from '@/assets/gateway-login.png'
import gatewayParties from '@/assets/gateway-parties.png'
import walletPicker from '@/assets/wallet-picker.png'
import { Button } from '@/components/Button'
import { CopyButton } from '@/components/CopyButton'
import { Modal } from '@/components/Modal'
import { StepBar } from '@/components/StepBar'
import { roundButtonClass } from '@/components/TopBar/ThemeToggle'
import { cn } from '@/utils/cn'
import { WALLET_GATEWAY_UI_URL } from '@/utils/config'

const SEEN_KEY = 'vesting.connectGuideSeen'

const hasSeenGuide = (): boolean => {
try {
return localStorage.getItem(SEEN_KEY) !== null
} catch {
return true
}
}

const markGuideSeen = (): void => {
try {
localStorage.setItem(SEEN_KEY, 'true')
} catch {}
}

const steps = [
{
alt: 'The wallet picker with Wallet Gateway highlighted',
image: walletPicker,
name: 'Connect',
text: (
<>
<b>Wallet Gateway</b> is available by default to be used as a wallet. To connect it, click
the "Connect" button in the header and select <b>Wallet Gateway</b> from the options.
</>
),
},
{
alt: 'The Wallet Gateway login with the client secret field highlighted',
image: gatewayLogin,
name: 'Sign in',
text: (
<>
Enter{' '}
<span className="inline-flex items-center gap-1 font-mono text-[0.85em] font-semibold">
<code>unsafe</code>
<CopyButton label="Client secret" size={13} value="unsafe" />
</span>{' '}
as the client secret
</>
),
},
{
alt: 'The Wallet Gateway parties list with Set as primary highlighted',
image: gatewayParties,
name: 'Connected',
text: (
<>
You're connected now. You can change the primary party to try different views in the dApp.
Direct access to Wallet Gateway available{' '}
<a
aria-label="Open Wallet Gateway"
className="font-semibold text-primary-strong underline underline-offset-3"
href={WALLET_GATEWAY_UI_URL}
rel="noreferrer"
target="_blank"
>
here
</a>
.
</>
),
},
]

export const ConnectGuide = (): React.JSX.Element => {
const [open, setOpen] = useState(() => !hasSeenGuide())

const close = (): void => {
markGuideSeen()
setOpen(false)
}

return (
<>
<button
type="button"
aria-label="How to connect a wallet"
onClick={() => setOpen(true)}
className={cn(roundButtonClass, 'text-[0.95rem] font-bold')}
>
?
</button>
{open && (
<Modal onClose={close} title="Welcome">
<Steps.Root count={steps.length}>
<StepBar steps={steps.map(({ name }) => name)} />
{steps.map(({ alt, image, name, text }, index) => (
<Steps.Content className="focus-visible:outline-none" index={index} key={name}>
<img
alt={alt}
className="block w-full rounded-xl border border-border"
height={232}
loading="lazy"
src={image}
width={400}
/>
<p className="mt-4 text-[0.95rem] leading-6">{text}</p>
</Steps.Content>
))}
<Steps.Context>
{(api) => (
<div className="mt-6 flex items-center gap-3">
{api.hasPrevStep && (
<Steps.PrevTrigger asChild>
<Button variant="ghost" size="sm" className="px-0">
Back
</Button>
</Steps.PrevTrigger>
)}
{api.value < api.count - 1 ? (
<Steps.NextTrigger asChild>
<Button className="ml-auto" size="sm">
Next
</Button>
</Steps.NextTrigger>
) : (
<Button className="ml-auto" size="sm" onClick={close}>
Done
</Button>
)}
</div>
)}
</Steps.Context>
</Steps.Root>
</Modal>
)}
</>
)
}
5 changes: 4 additions & 1 deletion dapp/frontend/src/components/TopBar/ThemeToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useTheme } from '@bootnodedev/canton-dappbooster'
import { Moon, Sun } from 'lucide-react'

export const roundButtonClass =
'inline-grid size-9 place-items-center rounded-full border border-border bg-surface text-fg-muted transition-colors hover:border-primary hover:text-primary-strong'

export const ThemeToggle = (): React.JSX.Element => {
const { resolved, toggle } = useTheme()
const next = resolved === 'dark' ? 'light' : 'dark'
Expand All @@ -10,7 +13,7 @@ export const ThemeToggle = (): React.JSX.Element => {
onClick={toggle}
aria-label={`Switch to ${next} theme`}
title={`Switch to ${next} theme`}
className="inline-grid size-9 place-items-center rounded-full border border-border bg-surface text-fg-muted transition-colors hover:border-primary hover:text-primary-strong"
className={roundButtonClass}
>
{resolved === 'dark' ? <Moon size={16} /> : <Sun size={16} />}
</button>
Expand Down
2 changes: 2 additions & 0 deletions dapp/frontend/src/components/TopBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NavLink, type NavLinkRenderProps } from 'react-router-dom'
import { ConnectFace } from '@/components/ConnectFace'
import { Spinner } from '@/components/Spinner'
import { AccountMenu } from '@/components/TopBar/AccountMenu'
import { ConnectGuide } from '@/components/TopBar/ConnectGuide'
import { Logo } from '@/components/TopBar/Logo'
import { ThemeToggle } from '@/components/TopBar/ThemeToggle'
import { useBackend } from '@/providers/Backend'
Expand All @@ -29,6 +30,7 @@ export const TopBar = (): React.JSX.Element => {

<div className="flex items-center gap-3">
<ThemeToggle />
<ConnectGuide />
{sessionPending ? (
<span
role="status"
Expand Down
1 change: 1 addition & 0 deletions dapp/frontend/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const EXPLORER: ExplorerConfig = { baseUrl: import.meta.env.VITE_EXPLORER

// The gateway serves its UI on the origin and the dApp API under /api/v0/dapp.
export const WALLET_GATEWAY_URL: string = import.meta.env.VITE_WALLET_GATEWAY_URL
export const WALLET_GATEWAY_UI_URL = new URL(WALLET_GATEWAY_URL).origin

export const SCAN_API_URL: string = import.meta.env.VITE_SCAN_API_URL

Expand Down
Loading