diff --git a/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidget.mdx b/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidget.mdx index c6967bbe..781ec6ae 100644 --- a/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidget.mdx +++ b/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidget.mdx @@ -41,7 +41,7 @@ import { DocsCallout, DocsCard, DocsGrid, DocsPage, DocsSection } from '../docs/ > Setup tab with connect CTA; Buy Credits, Manage, and History tabs visible but disabled until a wallet connects. - Connected wallet — static onboarding shell for Download AntSeed, Signer Key, and Authorize Wallet (step interactions are follow-up work). + Connected wallet — setup onboarding starts with a Download AntSeed VPR/Desktop action, followed by locked Signer Key and Authorize Wallet steps. Buy tab — stepper with a CTA to open the active step in a bottom drawer. Buy tab — pay step available via drawer CTA; ready to confirm Celo transaction. Buy tab — Celo tx submitted. @@ -60,7 +60,7 @@ import { DocsCallout, DocsCard, DocsGrid, DocsPage, DocsSection } from '../docs/ description="Setup, Buy Credits, Manage, and History appear as tabs (with the GoodDollar header and chain badge). Before a wallet connects, only Setup is active. After connecting, switch tabs anytime — including during payment pending or failed states." > - Onboarding entry point — connect wallet when disconnected; onboarding step shell when connected. + Onboarding entry point — connect wallet when disconnected; Download AntSeed VPR/Desktop action appears first once connected. Stepper for buyer key, consent, and pay — tap a step or CTA to open it in a drawer. Credits balance, stream info, close/withdraw, and API setup. Paginated credit history with source, status, and date filters. diff --git a/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidgetQA.stories.tsx b/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidgetQA.stories.tsx index ee2e7ba1..71e2889b 100644 --- a/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidgetQA.stories.tsx +++ b/examples/storybook/src/stories/ai-credits-widget/AiCreditsWidgetQA.stories.tsx @@ -121,6 +121,16 @@ export const MultiBuyerHistory: Story = { export const SetupTab: Story = { render: () => , + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const root = canvas.getByTestId('AiCreditsWidget-setup-tab') + const downloadLink = within(root).getByRole('link', { name: /download antseed vpr\/desktop/i }) + + await expect(downloadLink).toHaveAttribute( + 'href', + 'https://github.com/AntSeed/antseed/releases/latest', + ) + }, } export const AppKitConnectWallet: Story = { diff --git a/packages/ai-credits-widget/src/AiCreditsWidget.tsx b/packages/ai-credits-widget/src/AiCreditsWidget.tsx index 4669647c..bb550a0d 100644 --- a/packages/ai-credits-widget/src/AiCreditsWidget.tsx +++ b/packages/ai-credits-widget/src/AiCreditsWidget.tsx @@ -32,6 +32,7 @@ import { SetupGuidanceCard, HowToUseView, SetupFaqView, + SetupOnboardingPanel, } from './components' import type { AiCreditsWidgetProps, @@ -87,24 +88,6 @@ function SetupConnectPrompt({ ) } -const SETUP_ONBOARDING_STEPS: Array<{ number: number; title: string; description: string }> = [ - { - number: 1, - title: 'Download AntSeed', - description: 'Install the AntSeed application to manage your AI credits signer key.', - }, - { - number: 2, - title: 'Signer Key', - description: 'Generate or import a signer key that AntSeed will use to authorize requests.', - }, - { - number: 3, - title: 'Authorize Wallet', - description: 'Link your wallet to the signer key so it can be topped up with AI credits.', - }, -] - function SetupTabPanel({ state, onConnect, @@ -126,31 +109,7 @@ function SetupTabPanel({ Onboarding - {SETUP_ONBOARDING_STEPS.map((step) => ( - - - - - {step.number} - - - - {step.title} - - {step.description} - - - - - ))} + ) } diff --git a/packages/ai-credits-widget/src/components/index.ts b/packages/ai-credits-widget/src/components/index.ts index 6d2a5e5b..0d884c3b 100644 --- a/packages/ai-credits-widget/src/components/index.ts +++ b/packages/ai-credits-widget/src/components/index.ts @@ -11,8 +11,8 @@ export { HistoryTab } from './history/HistoryTab' export { SetupGuidanceCard } from './setup/SetupGuidanceCard' export { HowToUseView } from './setup/HowToUseView' export { SetupFaqView } from './setup/SetupFaqView' +export { SetupOnboardingPanel } from './setup/SetupOnboardingPanel' export type { AiCreditsFlowStep } from './flow/types' export { getAiCreditsActiveFlowStep } from './flow/purchaseFlowUtils' export { AiCreditsFlowStepper } from './flow/AiCreditsFlowStepper' export { AiCreditsPurchaseFlow } from './flow/AiCreditsPurchaseFlow' - diff --git a/packages/ai-credits-widget/src/components/setup/SetupOnboardingPanel.tsx b/packages/ai-credits-widget/src/components/setup/SetupOnboardingPanel.tsx new file mode 100644 index 00000000..6de98803 --- /dev/null +++ b/packages/ai-credits-widget/src/components/setup/SetupOnboardingPanel.tsx @@ -0,0 +1,75 @@ +import React from 'react' +import { + Anchor, + Button, + ButtonText, + Card, + Icon, + Stepper, + Text, + YStack, +} from '@goodwidget/ui' +import type { StepperStepItem } from '@goodwidget/ui' + +/** Stable fallback download target for AntSeed VPR/Desktop installers. */ +const ANTSEED_VPR_DOWNLOAD_URL = 'https://github.com/AntSeed/antseed/releases/latest' + +const SETUP_ONBOARDING_STEPS: StepperStepItem[] = [ + { + id: 'download-antseed', + title: 'Download AntSeed', + description: 'Install the desktop app that runs your credits locally.', + status: 'ready', + }, + { + id: 'signer-key', + title: 'Signer Key', + status: 'pending', + }, + { + id: 'authorize-wallet', + title: 'Authorize Wallet', + status: 'pending', + }, +] + +/** + * Setup-only onboarding shell. This slice exposes the AntSeed desktop download + * action while leaving the later Signer Key / Authorize Wallet setup work + * locked behind the first step. + */ +export function SetupOnboardingPanel() { + return ( + + One-time setup, in order — each step unlocks the next. + + + + + + Download AntSeed VPR/Desktop + + Install AntSeed before generating your signer key. It runs your AI credits locally and + only needs to be installed once on each computer. + + + + + + + + + Opens the latest AntSeed desktop release in a new tab. + + + + ) +} diff --git a/tests/widgets/ai-credits-widget/states.spec.ts b/tests/widgets/ai-credits-widget/states.spec.ts index f4378502..7150ba07 100644 --- a/tests/widgets/ai-credits-widget/states.spec.ts +++ b/tests/widgets/ai-credits-widget/states.spec.ts @@ -80,9 +80,14 @@ test('AiCreditsWidget Setup tab — onboarding steps visible', async ({ page }) await gotoStory(page, STORY_IDS.setupTab) const root = page.getByTestId('AiCreditsWidget-setup-tab') await expect(root).toBeVisible() + const downloadLink = root.getByRole('link', { name: /download antseed vpr\/desktop/i }) await expect(root.getByText('Download AntSeed', { exact: true })).toBeVisible() await expect(root.getByText('Signer Key', { exact: true })).toBeVisible() await expect(root.getByText('Authorize Wallet', { exact: true })).toBeVisible() + await expect(downloadLink).toHaveAttribute( + 'href', + 'https://github.com/AntSeed/antseed/releases/latest', + ) await expect(root.getByText('Setup', { exact: true })).toBeVisible() await expect(root.getByText('Buy Credits', { exact: true })).toBeVisible() await page.screenshot({ diff --git a/tests/widgets/ai-credits-widget/test-results/acw-20-setup-tab.png b/tests/widgets/ai-credits-widget/test-results/acw-20-setup-tab.png index b85adf49..3be16bce 100644 Binary files a/tests/widgets/ai-credits-widget/test-results/acw-20-setup-tab.png and b/tests/widgets/ai-credits-widget/test-results/acw-20-setup-tab.png differ