chore: Reroute to new onboarding flow

This commit is contained in:
Vanalite 2025-09-15 17:15:42 +07:00
parent 41da624986
commit 839c960034
7 changed files with 179 additions and 15 deletions

View File

@ -4,7 +4,6 @@
"version": "0.6.6",
"type": "module",
"scripts": {
"ios:iphone16": "react-native run-ios --simulator=\"iPhone 16 (iOS 18.6)\"",
"dev": "vite --port 1422",
"build": "tsc -b && vite build",
"lint": "eslint .",

View File

@ -2,16 +2,18 @@ import { useEffect, useState } from 'react'
import { cn } from '@/lib/utils'
interface SplashScreenProps {
onComplete: () => void
onComplete?: () => void
}
export function SplashScreen({ onComplete }: SplashScreenProps) {
export function SplashScreen({ onComplete }: SplashScreenProps = {}) {
const [isVisible, setIsVisible] = useState(true)
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(false)
setTimeout(onComplete, 300) // Wait for fade out animation
if (onComplete) {
setTimeout(onComplete, 300) // Wait for fade out animation
}
}, 2000)
return () => clearTimeout(timer)

View File

@ -12,6 +12,8 @@
import { Route as rootRoute } from './routes/__root'
import { Route as SettingsImport } from './routes/settings'
import { Route as OnboardingImport } from './routes/onboarding'
import { Route as ChatImport } from './routes/chat'
import { Route as IndexImport } from './routes/index'
// Create/Update Routes
@ -22,6 +24,18 @@ const SettingsRoute = SettingsImport.update({
getParentRoute: () => rootRoute,
} as any)
const OnboardingRoute = OnboardingImport.update({
id: '/onboarding',
path: '/onboarding',
getParentRoute: () => rootRoute,
} as any)
const ChatRoute = ChatImport.update({
id: '/chat',
path: '/chat',
getParentRoute: () => rootRoute,
} as any)
const IndexRoute = IndexImport.update({
id: '/',
path: '/',
@ -39,6 +53,20 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute
}
'/chat': {
id: '/chat'
path: '/chat'
fullPath: '/chat'
preLoaderRoute: typeof ChatImport
parentRoute: typeof rootRoute
}
'/onboarding': {
id: '/onboarding'
path: '/onboarding'
fullPath: '/onboarding'
preLoaderRoute: typeof OnboardingImport
parentRoute: typeof rootRoute
}
'/settings': {
id: '/settings'
path: '/settings'
@ -53,36 +81,46 @@ declare module '@tanstack/react-router' {
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/chat': typeof ChatRoute
'/onboarding': typeof OnboardingRoute
'/settings': typeof SettingsRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/chat': typeof ChatRoute
'/onboarding': typeof OnboardingRoute
'/settings': typeof SettingsRoute
}
export interface FileRoutesById {
__root__: typeof rootRoute
'/': typeof IndexRoute
'/chat': typeof ChatRoute
'/onboarding': typeof OnboardingRoute
'/settings': typeof SettingsRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/settings'
fullPaths: '/' | '/chat' | '/onboarding' | '/settings'
fileRoutesByTo: FileRoutesByTo
to: '/' | '/settings'
id: '__root__' | '/' | '/settings'
to: '/' | '/chat' | '/onboarding' | '/settings'
id: '__root__' | '/' | '/chat' | '/onboarding' | '/settings'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
ChatRoute: typeof ChatRoute
OnboardingRoute: typeof OnboardingRoute
SettingsRoute: typeof SettingsRoute
}
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
ChatRoute: ChatRoute,
OnboardingRoute: OnboardingRoute,
SettingsRoute: SettingsRoute,
}
@ -97,12 +135,20 @@ export const routeTree = rootRoute
"filePath": "__root.tsx",
"children": [
"/",
"/chat",
"/onboarding",
"/settings"
]
},
"/": {
"filePath": "index.tsx"
},
"/chat": {
"filePath": "chat.tsx"
},
"/onboarding": {
"filePath": "onboarding.tsx"
},
"/settings": {
"filePath": "settings.tsx"
}

View File

@ -1,15 +1,55 @@
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
import { Toaster } from 'sonner'
import { useState, useEffect } from 'react'
export const Route = createRootRoute({
component: () => (
<div className="h-full flex flex-col overflow-hidden">
component: RootLayout,
})
function RootLayout() {
const [isInitialized, setIsInitialized] = useState(false)
useEffect(() => {
// Initialize mobile app
setIsInitialized(true)
}, [])
if (!isInitialized) {
return (
<div className="h-full flex items-center justify-center bg-background">
<div className="text-center">
<div className="w-16 h-16 mx-auto mb-4">
<svg className="animate-spin h-16 w-16 text-primary" viewBox="0 0 24 24">
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
fill="none"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
</div>
<p className="text-muted-foreground">Loading Jan Mobile...</p>
</div>
</div>
)
}
return (
<div className="h-full flex flex-col overflow-hidden bg-background">
<Outlet />
<Toaster position="top-center" />
{process.env.NODE_ENV === 'development' && (
<TanStackRouterDevtools position="bottom-right" />
)}
</div>
),
})
)
}

View File

@ -0,0 +1,10 @@
import { createFileRoute } from '@tanstack/react-router'
import { ChatScreen } from '@/components/ChatScreen'
export const Route = createFileRoute('/chat')({
component: ChatPage,
})
function ChatPage() {
return <ChatScreen />
}

View File

@ -1,6 +1,56 @@
import { createFileRoute } from '@tanstack/react-router'
import { App } from '@/components/App'
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useEffect, useState } from 'react'
import { SplashScreen } from '@/components/SplashScreen'
import { ChatScreen } from '@/components/ChatScreen'
export const Route = createFileRoute('/')({
component: App,
})
component: HomePage,
})
function HomePage() {
const [showSplash, setShowSplash] = useState(true)
const [isNavigating, setIsNavigating] = useState(false)
const navigate = useNavigate()
useEffect(() => {
// Check if user has completed onboarding
const hasCompletedOnboarding = localStorage.getItem('jan_onboarding_completed')
const timer = setTimeout(() => {
setShowSplash(false)
if (!hasCompletedOnboarding) {
setIsNavigating(true)
navigate({ to: '/onboarding' })
}
}, 2300)
return () => clearTimeout(timer)
}, [navigate])
if (showSplash) {
return <SplashScreen />
}
if (isNavigating) {
return (
<div className="h-full flex items-center justify-center bg-background">
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto"></div>
<p className="mt-4 text-muted-foreground">Setting up...</p>
</div>
</div>
)
}
const hasCompletedOnboarding = localStorage.getItem('jan_onboarding_completed')
if (!hasCompletedOnboarding) {
return (
<div className="h-full flex items-center justify-center bg-background">
<p className="text-muted-foreground">Redirecting to onboarding...</p>
</div>
)
}
return <ChatScreen />
}

View File

@ -0,0 +1,17 @@
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { OnboardingScreen } from '@/components/OnboardingScreen'
export const Route = createFileRoute('/onboarding')({
component: OnboardingPage,
})
function OnboardingPage() {
const navigate = useNavigate()
const handleOnboardingComplete = () => {
localStorage.setItem('jan_onboarding_completed', 'true')
navigate({ to: '/' })
}
return <OnboardingScreen onComplete={handleOnboardingComplete} />
}