mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-11 06:46:59 +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:
@@ -1,6 +1,8 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react'
|
||||
import { flushSync } from 'react-dom'
|
||||
import { getSystemConfig } from '../lib/config'
|
||||
import { reset401Flag, httpClient } from '../lib/httpClient'
|
||||
import { getPostAuthPath, setUserMode, type UserMode } from '../lib/onboarding'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
@@ -12,7 +14,8 @@ interface AuthContextType {
|
||||
token: string | null
|
||||
login: (
|
||||
email: string,
|
||||
password: string
|
||||
password: string,
|
||||
mode?: UserMode
|
||||
) => Promise<{
|
||||
success: boolean
|
||||
message?: string
|
||||
@@ -24,7 +27,8 @@ interface AuthContextType {
|
||||
register: (
|
||||
email: string,
|
||||
password: string,
|
||||
betaCode?: string
|
||||
betaCode?: string,
|
||||
mode?: UserMode
|
||||
) => Promise<{ success: boolean; message?: string }>
|
||||
resetPassword: (
|
||||
email: string,
|
||||
@@ -89,7 +93,36 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
const handlePostAuthSuccess = (
|
||||
authToken: string,
|
||||
userInfo: User,
|
||||
mode?: UserMode
|
||||
) => {
|
||||
reset401Flag()
|
||||
|
||||
if (mode) {
|
||||
setUserMode(mode)
|
||||
}
|
||||
|
||||
localStorage.setItem('auth_token', authToken)
|
||||
localStorage.setItem('auth_user', JSON.stringify(userInfo))
|
||||
localStorage.setItem('user_id', userInfo.id)
|
||||
flushSync(() => {
|
||||
setToken(authToken)
|
||||
setUser(userInfo)
|
||||
})
|
||||
|
||||
const returnUrl = sessionStorage.getItem('returnUrl')
|
||||
const nextPath = returnUrl || getPostAuthPath(mode)
|
||||
if (returnUrl) {
|
||||
sessionStorage.removeItem('returnUrl')
|
||||
}
|
||||
|
||||
window.history.pushState({}, '', nextPath)
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
}
|
||||
|
||||
const login = async (email: string, password: string, mode?: UserMode) => {
|
||||
try {
|
||||
const response = await fetch('/api/login', {
|
||||
method: 'POST',
|
||||
@@ -103,26 +136,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
if (response.ok) {
|
||||
if (data.token) {
|
||||
// Reset 401 flag on successful login
|
||||
reset401Flag()
|
||||
|
||||
const userInfo = { id: data.user_id, email: data.email }
|
||||
setToken(data.token)
|
||||
setUser(userInfo)
|
||||
localStorage.setItem('auth_token', data.token)
|
||||
localStorage.setItem('auth_user', JSON.stringify(userInfo))
|
||||
|
||||
// Check and redirect to returnUrl if exists
|
||||
const returnUrl = sessionStorage.getItem('returnUrl')
|
||||
if (returnUrl) {
|
||||
sessionStorage.removeItem('returnUrl')
|
||||
window.history.pushState({}, '', returnUrl)
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
} else {
|
||||
// Redirect to config page
|
||||
window.history.pushState({}, '', '/traders')
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
}
|
||||
handlePostAuthSuccess(data.token, userInfo, mode)
|
||||
|
||||
return { success: true, message: data.message }
|
||||
}
|
||||
@@ -156,10 +171,12 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
id: data.user_id || 'admin',
|
||||
email: data.email || 'admin@localhost',
|
||||
}
|
||||
setToken(data.token)
|
||||
setUser(userInfo)
|
||||
localStorage.setItem('auth_token', data.token)
|
||||
localStorage.setItem('auth_user', JSON.stringify(userInfo))
|
||||
flushSync(() => {
|
||||
setToken(data.token)
|
||||
setUser(userInfo)
|
||||
})
|
||||
|
||||
// Check and redirect to returnUrl if exists
|
||||
const returnUrl = sessionStorage.getItem('returnUrl')
|
||||
@@ -184,7 +201,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const register = async (
|
||||
email: string,
|
||||
password: string,
|
||||
betaCode?: string
|
||||
betaCode?: string,
|
||||
mode?: UserMode
|
||||
) => {
|
||||
const requestBody: {
|
||||
email: string
|
||||
@@ -204,26 +222,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}>('/api/register', requestBody)
|
||||
|
||||
if (result.success && result.data) {
|
||||
// Reset 401 flag on successful login
|
||||
reset401Flag()
|
||||
|
||||
const userInfo = { id: result.data.user_id, email: result.data.email }
|
||||
setToken(result.data.token)
|
||||
setUser(userInfo)
|
||||
localStorage.setItem('auth_token', result.data.token)
|
||||
localStorage.setItem('auth_user', JSON.stringify(userInfo))
|
||||
|
||||
// Check and redirect to returnUrl if exists
|
||||
const returnUrl = sessionStorage.getItem('returnUrl')
|
||||
if (returnUrl) {
|
||||
sessionStorage.removeItem('returnUrl')
|
||||
window.history.pushState({}, '', returnUrl)
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
} else {
|
||||
// Redirect to config page
|
||||
window.history.pushState({}, '', '/traders')
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
}
|
||||
handlePostAuthSuccess(result.data.token, userInfo, mode)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user