mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
refactor(onboarding): align V3 card presentation
Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -455,7 +455,7 @@ export function AgentCreationPreview({
|
||||
className={cn(
|
||||
"w-[400px] p-3",
|
||||
isOnboarding &&
|
||||
"buzz-onboarding-neutral-theme bg-white text-foreground",
|
||||
"buzz-onboarding-neutral-theme bg-white text-foreground [--buzz-onboarding-cta-label:#fff]",
|
||||
)}
|
||||
data-system-color-scheme={isOnboarding ? "light" : undefined}
|
||||
side="bottom"
|
||||
|
||||
@@ -15,6 +15,7 @@ export type OnboardingPreviewPage =
|
||||
| "sign-in-key"
|
||||
| "forgot-password"
|
||||
| "backup-options"
|
||||
| "identity-key-help"
|
||||
| "backup-password"
|
||||
| "setup"
|
||||
| "config"
|
||||
|
||||
@@ -66,6 +66,7 @@ type BackupStepProps = {
|
||||
direction: OnboardingTransitionDirection;
|
||||
identityStorage?: IdentityStorage;
|
||||
onNext: () => void;
|
||||
onOpenIdentityKeyHelp?: () => void;
|
||||
onOpenPasswordBackup: () => void;
|
||||
onShowOptions: () => void;
|
||||
optionsExpanded: boolean;
|
||||
@@ -85,6 +86,7 @@ export function BackupStep({
|
||||
direction,
|
||||
identityStorage,
|
||||
onNext,
|
||||
onOpenIdentityKeyHelp,
|
||||
onOpenPasswordBackup,
|
||||
onShowOptions,
|
||||
optionsExpanded,
|
||||
@@ -225,13 +227,17 @@ export function BackupStep({
|
||||
{previewMode ? "Create a private identity key" : "Backup options"}
|
||||
</h1>
|
||||
{previewMode ? (
|
||||
<div className="mt-5">
|
||||
<div className={cardLayout ? "mt-2" : "mt-5"}>
|
||||
<p className="text-sm leading-6 text-foreground/75">
|
||||
This key will be how you log into Buzz. You can use it across
|
||||
Buzz communities and other platforms.
|
||||
</p>
|
||||
<div className="mt-2">
|
||||
<IdentityKeyHelpDialog inline previewMode />
|
||||
<IdentityKeyHelpDialog
|
||||
inline
|
||||
onPreviewOpen={onOpenIdentityKeyHelp}
|
||||
previewMode
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -36,9 +36,11 @@ function rememberIdentityKeyHelpSeen() {
|
||||
|
||||
export function IdentityKeyHelpDialog({
|
||||
inline = false,
|
||||
onPreviewOpen,
|
||||
previewMode = false,
|
||||
}: {
|
||||
inline?: boolean;
|
||||
onPreviewOpen?: () => void;
|
||||
previewMode?: boolean;
|
||||
}) {
|
||||
const [isVisible, setIsVisible] = React.useState(
|
||||
@@ -56,29 +58,38 @@ export function IdentityKeyHelpDialog({
|
||||
return () => window.clearTimeout(timeout);
|
||||
}, [isVisible, previewMode]);
|
||||
|
||||
const trigger = (
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
className={cn(
|
||||
previewMode
|
||||
? "text-foreground underline decoration-foreground/45 underline-offset-4 hover:decoration-foreground"
|
||||
: "text-foreground/70 hover:text-foreground",
|
||||
"transition-opacity duration-300 motion-reduce:transition-none",
|
||||
inline && "h-auto justify-start p-0 text-left",
|
||||
isVisible ? "opacity-100" : "pointer-events-none opacity-0",
|
||||
)}
|
||||
data-testid="identity-key-help-trigger"
|
||||
tabIndex={isVisible ? 0 : -1}
|
||||
type="button"
|
||||
variant="link"
|
||||
>
|
||||
{previewMode
|
||||
? "Learn how identity keys work"
|
||||
: "What’s an identity key?"}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
const triggerButton = (
|
||||
<Button
|
||||
className={cn(
|
||||
previewMode
|
||||
? "text-foreground underline decoration-foreground/45 underline-offset-4 hover:decoration-foreground"
|
||||
: "text-foreground/70 hover:text-foreground",
|
||||
"transition-opacity duration-300 motion-reduce:transition-none",
|
||||
inline && "h-auto justify-start p-0 text-left",
|
||||
isVisible ? "opacity-100" : "pointer-events-none opacity-0",
|
||||
)}
|
||||
data-testid="identity-key-help-trigger"
|
||||
onClick={previewMode ? onPreviewOpen : undefined}
|
||||
tabIndex={isVisible ? 0 : -1}
|
||||
type="button"
|
||||
variant="link"
|
||||
>
|
||||
{previewMode ? "Learn how identity keys work" : "What’s an identity key?"}
|
||||
</Button>
|
||||
);
|
||||
|
||||
if (previewMode && onPreviewOpen) {
|
||||
return inline ? (
|
||||
triggerButton
|
||||
) : (
|
||||
<OnboardingFooter className="max-w-none">
|
||||
{triggerButton}
|
||||
</OnboardingFooter>
|
||||
);
|
||||
}
|
||||
|
||||
const trigger = <DialogTrigger asChild>{triggerButton}</DialogTrigger>;
|
||||
|
||||
return (
|
||||
<Dialog>
|
||||
{inline ? (
|
||||
@@ -103,17 +114,7 @@ export function IdentityKeyHelpDialog({
|
||||
className="mt-6 space-y-4 text-pretty text-base leading-7 text-[color:var(--buzz-onboarding-backup-ink)]"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Buzz will create a Nostr identity with two parts: a private key
|
||||
that signs you in and a public key you can safely share. You can
|
||||
find your public identity anytime in Buzz settings.
|
||||
</p>
|
||||
<p>
|
||||
This identity belongs to you, not Buzz, and can move with you to
|
||||
another device or compatible Nostr app. Because only you control
|
||||
the private key, Buzz can’t reset or recover it. Keep a backup
|
||||
somewhere safe, and never share it.
|
||||
</p>
|
||||
<IdentityKeyHelpBody />
|
||||
</div>
|
||||
</DialogDescription>
|
||||
</div>
|
||||
@@ -121,3 +122,35 @@ export function IdentityKeyHelpDialog({
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
function IdentityKeyHelpBody() {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Buzz will create a Nostr identity with two parts: a private key that
|
||||
signs you in and a public key you can safely share. You can find your
|
||||
public identity anytime in Buzz settings.
|
||||
</p>
|
||||
<p>
|
||||
This identity belongs to you, not Buzz, and can move with you to another
|
||||
device or compatible Nostr app. Because only you control the private
|
||||
key, Buzz can’t reset or recover it. Keep a backup somewhere safe, and
|
||||
never share it.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/** Production identity-key explainer content in the V3 onboarding card treatment. */
|
||||
export function IdentityKeyHelpPreviewContent() {
|
||||
return (
|
||||
<>
|
||||
<h1 className="text-title font-normal text-foreground">
|
||||
What’s an identity key?
|
||||
</h1>
|
||||
<div className="mt-2 max-w-[500px] space-y-4 text-pretty text-base leading-7 text-foreground/80">
|
||||
<IdentityKeyHelpBody />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,12 @@ export function KeySignInPreview({
|
||||
<h1 className="text-title font-normal text-foreground">
|
||||
Enter your private key
|
||||
</h1>
|
||||
<div className="mt-5 max-w-[440px] text-sm leading-6 text-foreground/80">
|
||||
<div
|
||||
className={cn(
|
||||
"max-w-[440px] text-sm leading-6 text-foreground/80",
|
||||
cardLayout ? "mt-2" : "mt-5",
|
||||
)}
|
||||
>
|
||||
<p>
|
||||
Paste your private key to sign in to Buzz. You can also use a{" "}
|
||||
<button
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
} from "./EncryptedBackupCreator";
|
||||
import { JoinPolicyNotice } from "./JoinPolicyNotice";
|
||||
import { KeySignInPreview } from "./KeySignInPreview";
|
||||
import { IdentityKeyHelpPreviewContent } from "./IdentityKeyHelpDialog";
|
||||
import { LandingBees } from "./LandingBees";
|
||||
import {
|
||||
ONBOARDING_LANDING_CTA_CLASS,
|
||||
@@ -760,6 +761,7 @@ export function OnboardingPreviewApp() {
|
||||
direction="forward"
|
||||
lockedBackupCreated={backupSession.created}
|
||||
onNext={() => setPage("identity-key")}
|
||||
onOpenIdentityKeyHelp={() => setPage("identity-key-help")}
|
||||
onOpenPasswordBackup={() => setPage("backup-password")}
|
||||
onShowOptions={() => setPage("backup-options")}
|
||||
optionsExpanded
|
||||
@@ -768,6 +770,21 @@ export function OnboardingPreviewApp() {
|
||||
/>
|
||||
</OnboardingPreviewStep>
|
||||
);
|
||||
} else if (page === "identity-key-help") {
|
||||
content = (
|
||||
<OnboardingPreviewStep
|
||||
onBack={() => setPage("backup-options")}
|
||||
testId="onboarding-preview-identity-key-help"
|
||||
total={journey.totalSteps}
|
||||
>
|
||||
<OnboardingSlideTransition
|
||||
className="flex min-h-0 w-full max-w-[560px] flex-col items-stretch justify-start text-left"
|
||||
transitionKey="preview-identity-key-help"
|
||||
>
|
||||
<IdentityKeyHelpPreviewContent />
|
||||
</OnboardingSlideTransition>
|
||||
</OnboardingPreviewStep>
|
||||
);
|
||||
} else if (page === "backup-password") {
|
||||
content = (
|
||||
<BackupPasswordPreview
|
||||
|
||||
@@ -20,7 +20,8 @@ export function OnboardingPreviewControls({
|
||||
}) {
|
||||
return (
|
||||
<aside
|
||||
className="fixed right-4 top-4 z-[100] flex w-[320px] max-w-[calc(100vw-2rem)] flex-col gap-3 rounded-2xl border border-foreground/15 bg-background/95 px-4 py-3 text-left shadow-lg backdrop-blur"
|
||||
className="buzz-onboarding-neutral-theme fixed right-4 top-4 z-[100] flex w-[320px] max-w-[calc(100vw-2rem)] flex-col gap-3 rounded-2xl border border-foreground/15 bg-background/95 px-4 py-3 text-left shadow-lg backdrop-blur"
|
||||
data-system-color-scheme="light"
|
||||
data-testid="onboarding-preview-banner"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -35,7 +36,7 @@ export function OnboardingPreviewControls({
|
||||
</div>
|
||||
<Button
|
||||
aria-label="Restart onboarding preview"
|
||||
className="h-8 w-8 shrink-0"
|
||||
className="h-8 w-8 shrink-0 text-foreground hover:text-foreground"
|
||||
data-testid="onboarding-preview-restart"
|
||||
onClick={onRestart}
|
||||
size="icon"
|
||||
|
||||
@@ -320,7 +320,12 @@ export function CommunityChoicePreview({
|
||||
? "Join or create a community"
|
||||
: "Buzz happens in communities"}
|
||||
</h1>
|
||||
<p className="mt-3 text-sm leading-6 text-foreground/80">
|
||||
<p
|
||||
className={cn(
|
||||
"text-sm leading-6 text-foreground/80",
|
||||
cardLayout ? "mt-2" : "mt-3",
|
||||
)}
|
||||
>
|
||||
{includeExistingCommunity
|
||||
? "Join with an invite, create your own community, or reconnect one you already have."
|
||||
: "Communities are shared spaces where people and agents work together."}
|
||||
@@ -420,7 +425,12 @@ export function CommunityEntryPreview({
|
||||
>
|
||||
<div className="w-full max-w-[620px]">
|
||||
<h1 className="text-title font-normal">{heading}</h1>
|
||||
<p className="mt-3 text-sm leading-6 text-foreground/80">
|
||||
<p
|
||||
className={cn(
|
||||
"text-sm leading-6 text-foreground/80",
|
||||
cardLayout ? "mt-2" : "mt-3",
|
||||
)}
|
||||
>
|
||||
{route === "existing"
|
||||
? "Enter the community URL or an invite link. Your role will be restored when you connect."
|
||||
: previewVariant === "v3"
|
||||
|
||||
@@ -75,7 +75,7 @@ export function OnboardingPreviewStep({
|
||||
{cardLayout ? (
|
||||
<Card
|
||||
className={cn(
|
||||
"flex h-[min(41.5rem,calc(100dvh-3rem))] w-full max-w-[47rem] flex-col overflow-hidden rounded-[2rem] bg-white px-6 pb-6 pt-[4.5rem] text-left shadow-lg sm:px-[7.5rem] [&_.buzz-onboarding-transition-content]:!text-left [&_.buzz-onboarding-transition-line]:justify-start [&_h1+p]:!mx-0 [&_h1+p]:!mt-2 [&_h1+p]:!text-left [&_h1+p]:!text-base [&_h1+p]:!leading-6 [&_h1]:!text-left [&_h1]:!text-2xl [&_h1]:!leading-8 [&_h1]:!text-foreground",
|
||||
"flex h-[min(41.5rem,calc(100dvh-3rem))] w-full max-w-[47rem] flex-col overflow-hidden rounded-[2rem] bg-white px-6 pb-6 pt-[4.5rem] text-left shadow-lg [--buzz-onboarding-cta-label:#fff] sm:px-[7.5rem] [&_.buzz-onboarding-transition-content]:!text-left [&_.buzz-onboarding-transition-line]:justify-start [&_h1+p]:!mx-0 [&_h1+p]:!mt-2 [&_h1+p]:!text-left [&_h1+p]:!text-base [&_h1+p]:!leading-6 [&_h1]:!text-left [&_h1]:!text-2xl [&_h1]:!leading-8 [&_h1]:!text-foreground",
|
||||
)}
|
||||
data-testid="onboarding-preview-content-card"
|
||||
ref={cardRef}
|
||||
|
||||
Reference in New Issue
Block a user