98 lines
3.9 KiB
TypeScript
98 lines
3.9 KiB
TypeScript
import { useState, useRef, lazy, Suspense } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { Navbar } from '@/components/Navbar'
|
|
import { Card, CardContent } from '@/components/ui/card'
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
|
import { User, Palette, Copy } from 'lucide-react'
|
|
import type { CustomVoiceFormHandle } from '@/components/tts/CustomVoiceForm'
|
|
import type { VoiceDesignFormHandle } from '@/components/tts/VoiceDesignForm'
|
|
import { HistorySidebar } from '@/components/HistorySidebar'
|
|
import { OnboardingDialog } from '@/components/OnboardingDialog'
|
|
import FormSkeleton from '@/components/FormSkeleton'
|
|
import LoadingScreen from '@/components/LoadingScreen'
|
|
import { useUserPreferences } from '@/contexts/UserPreferencesContext'
|
|
|
|
const CustomVoiceForm = lazy(() => import('@/components/tts/CustomVoiceForm'))
|
|
const VoiceDesignForm = lazy(() => import('@/components/tts/VoiceDesignForm'))
|
|
const VoiceCloneForm = lazy(() => import('@/components/tts/VoiceCloneForm'))
|
|
|
|
function Home() {
|
|
const { t } = useTranslation('nav')
|
|
const [currentTab, setCurrentTab] = useState('custom-voice')
|
|
const [sidebarOpen, setSidebarOpen] = useState(false)
|
|
const { preferences } = useUserPreferences()
|
|
|
|
const customVoiceFormRef = useRef<CustomVoiceFormHandle>(null)
|
|
const voiceDesignFormRef = useRef<VoiceDesignFormHandle>(null)
|
|
|
|
if (!preferences) {
|
|
return <LoadingScreen />
|
|
}
|
|
|
|
const showOnboarding = !preferences.onboarding_completed
|
|
|
|
|
|
return (
|
|
<div className="h-screen overflow-hidden flex bg-background">
|
|
<OnboardingDialog
|
|
open={showOnboarding}
|
|
onComplete={() => {}}
|
|
/>
|
|
|
|
<HistorySidebar
|
|
open={sidebarOpen}
|
|
onOpenChange={setSidebarOpen}
|
|
/>
|
|
|
|
<div className="flex-1 flex flex-col overflow-hidden bg-muted/30">
|
|
<Navbar onToggleSidebar={() => setSidebarOpen(!sidebarOpen)} />
|
|
|
|
<main className="flex-1 overflow-y-auto flex items-start md:items-center justify-center lg:rounded-tl-2xl bg-background">
|
|
<div className="w-full container mx-auto p-3 md:p-6 max-w-[800px] md:max-w-[700px]">
|
|
<Tabs value={currentTab} onValueChange={setCurrentTab}>
|
|
<TabsList className="grid w-full grid-cols-3 h-9 mb-3">
|
|
<TabsTrigger value="custom-voice" variant="default">
|
|
<User className="h-4 w-4 md:mr-2" />
|
|
<span className="hidden md:inline">{t('customVoiceTab')}</span>
|
|
</TabsTrigger>
|
|
<TabsTrigger value="voice-design" variant="secondary">
|
|
<Palette className="h-4 w-4 md:mr-2" />
|
|
<span className="hidden md:inline">{t('voiceDesignTab')}</span>
|
|
</TabsTrigger>
|
|
<TabsTrigger value="voice-clone" variant="outline">
|
|
<Copy className="h-4 w-4 md:mr-2" />
|
|
<span className="hidden md:inline">{t('voiceCloneTab')}</span>
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<Card>
|
|
<CardContent className="pt-6 px-3 md:px-6 pb-6">
|
|
<TabsContent value="custom-voice" className="mt-0">
|
|
<Suspense fallback={<FormSkeleton />}>
|
|
<CustomVoiceForm ref={customVoiceFormRef} />
|
|
</Suspense>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="voice-design" className="mt-0">
|
|
<Suspense fallback={<FormSkeleton />}>
|
|
<VoiceDesignForm ref={voiceDesignFormRef} />
|
|
</Suspense>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="voice-clone" className="mt-0">
|
|
<Suspense fallback={<FormSkeleton />}>
|
|
<VoiceCloneForm />
|
|
</Suspense>
|
|
</TabsContent>
|
|
</CardContent>
|
|
</Card>
|
|
</Tabs>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Home
|