mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-09 22:10:57 +08:00
feat: improve user onboarding and setup UX (#1436)
* feat: add beginner onboarding and mode switching flow * chore: ignore local gh auth config * fix: restore kline fallback and align onboarding language --------- Co-authored-by: zavier-bin <zhaobbbhhh@gmail.com>
This commit is contained in:
@@ -5,6 +5,8 @@ import { useAuth } from '../../contexts/AuthContext'
|
||||
import { useLanguage } from '../../contexts/LanguageContext'
|
||||
import { t } from '../../i18n/translations'
|
||||
import { DeepVoidBackground } from '../common/DeepVoidBackground'
|
||||
import { OnboardingModeSelector } from './OnboardingModeSelector'
|
||||
import type { UserMode } from '../../lib/onboarding'
|
||||
|
||||
export function LoginPage() {
|
||||
const { language } = useLanguage()
|
||||
@@ -15,6 +17,7 @@ export function LoginPage() {
|
||||
const [error, setError] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [expiredToastId, setExpiredToastId] = useState<string | number | null>(null)
|
||||
const [mode, setMode] = useState<UserMode>('beginner')
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionStorage.getItem('from401') === 'true') {
|
||||
@@ -28,7 +31,7 @@ export function LoginPage() {
|
||||
e.preventDefault()
|
||||
setError('')
|
||||
setLoading(true)
|
||||
const result = await login(email, password)
|
||||
const result = await login(email, password, mode)
|
||||
setLoading(false)
|
||||
if (result.success) {
|
||||
if (expiredToastId) toast.dismiss(expiredToastId)
|
||||
@@ -109,6 +112,12 @@ export function LoginPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OnboardingModeSelector
|
||||
language={language}
|
||||
mode={mode}
|
||||
onChange={setMode}
|
||||
/>
|
||||
|
||||
{/* Error */}
|
||||
{error && (
|
||||
<p className="text-xs text-red-400 bg-red-500/10 border border-red-500/20 rounded-lg px-3 py-2">
|
||||
|
||||
75
web/src/components/auth/OnboardingModeSelector.tsx
Normal file
75
web/src/components/auth/OnboardingModeSelector.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { UserMode } from '../../lib/onboarding'
|
||||
|
||||
interface OnboardingModeSelectorProps {
|
||||
language: string
|
||||
mode: UserMode
|
||||
onChange: (mode: UserMode) => void
|
||||
}
|
||||
|
||||
export function OnboardingModeSelector({
|
||||
language,
|
||||
mode,
|
||||
onChange,
|
||||
}: OnboardingModeSelectorProps) {
|
||||
const isZh = language === 'zh'
|
||||
|
||||
const options: Array<{
|
||||
id: UserMode
|
||||
title: string
|
||||
badge?: string
|
||||
description: string
|
||||
}> = [
|
||||
{
|
||||
id: 'beginner',
|
||||
title: isZh ? '新手模式' : 'Beginner Mode',
|
||||
badge: isZh ? '推荐' : 'Recommended',
|
||||
description: isZh
|
||||
? '自动生成 Base 钱包,默认接入 Claw402 + DeepSeek,最快完成首次启动。'
|
||||
: 'Generate a Base wallet automatically and start with Claw402 + DeepSeek by default.',
|
||||
},
|
||||
{
|
||||
id: 'advanced',
|
||||
title: isZh ? '老手模式' : 'Advanced Mode',
|
||||
description: isZh
|
||||
? '保持现在的完整配置流程,你自己决定模型、钱包和交易所。'
|
||||
: 'Keep the full manual flow and configure models, wallets, and exchanges yourself.',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="text-xs font-medium text-zinc-400">
|
||||
{isZh ? '使用模式' : 'Experience'}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-2">
|
||||
{options.map((option) => {
|
||||
const selected = option.id === mode
|
||||
return (
|
||||
<button
|
||||
key={option.id}
|
||||
type="button"
|
||||
onClick={() => onChange(option.id)}
|
||||
className={`w-full rounded-xl border px-4 py-3 text-left transition-all ${
|
||||
selected
|
||||
? 'border-nofx-gold/60 bg-nofx-gold/10 shadow-[0_0_0_1px_rgba(240,185,11,0.15)]'
|
||||
: 'border-zinc-800 bg-zinc-950/60 hover:border-zinc-700'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-white">
|
||||
<span>{option.title}</span>
|
||||
{option.badge ? (
|
||||
<span className="rounded-full bg-nofx-gold px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-black">
|
||||
{option.badge}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<p className="mt-1 text-xs leading-5 text-zinc-400">
|
||||
{option.description}
|
||||
</p>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user