- {activeTab === 'profiles' && (
-
-
-
- )}
-
- {activeTab === 'generate' && (
-
-
-
- )}
-
- {activeTab === 'history' && (
-
-
-
- )}
-
- {activeTab === 'settings' && (
-
+
+
diff --git a/app/src/components/Generation/GenerationForm.tsx b/app/src/components/Generation/GenerationForm.tsx
index e4f6cbd9..06502c89 100644
--- a/app/src/components/Generation/GenerationForm.tsx
+++ b/app/src/components/Generation/GenerationForm.tsx
@@ -1,7 +1,8 @@
import { zodResolver } from '@hookform/resolvers/zod';
-import { Loader2 } from 'lucide-react';
+import { Loader2, Mic } from 'lucide-react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';
+import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
@@ -24,10 +25,10 @@ import {
import { Textarea } from '@/components/ui/textarea';
import { useToast } from '@/components/ui/use-toast';
import { useGeneration } from '@/lib/hooks/useGeneration';
-import { useProfiles } from '@/lib/hooks/useProfiles';
+import { useProfile } from '@/lib/hooks/useProfiles';
+import { useUIStore } from '@/stores/uiStore';
const generationSchema = z.object({
- profileId: z.string().min(1, 'Please select a voice profile'),
text: z.string().min(1, 'Text is required').max(5000),
language: z.enum(['en', 'zh']),
seed: z.number().int().optional(),
@@ -37,14 +38,14 @@ const generationSchema = z.object({
type GenerationFormValues = z.infer;
export function GenerationForm() {
- const { data: profiles } = useProfiles();
+ const selectedProfileId = useUIStore((state) => state.selectedProfileId);
+ const { data: selectedProfile } = useProfile(selectedProfileId || '');
const generation = useGeneration();
const { toast } = useToast();
const form = useForm({
resolver: zodResolver(generationSchema),
defaultValues: {
- profileId: '',
text: '',
language: 'en',
seed: undefined,
@@ -53,9 +54,18 @@ export function GenerationForm() {
});
async function onSubmit(data: GenerationFormValues) {
+ if (!selectedProfileId) {
+ toast({
+ title: 'No profile selected',
+ description: 'Please select a voice profile from the cards above.',
+ variant: 'destructive',
+ });
+ return;
+ }
+
try {
const result = await generation.mutateAsync({
- profile_id: data.profileId,
+ profile_id: selectedProfileId,
text: data.text,
language: data.language,
seed: data.seed,
@@ -85,30 +95,20 @@ export function GenerationForm() {
-
+ {activeTab === 'settings' ? (
+
+ ) : (
+ // Main view: Profiles top left, Generator bottom left, History right
+
+ {/* Left Column */}
+
)}
+ {/* Profiles - Top Left */}
+
+
+ {/* Right Column - History */}
+
+
+
+
+ {/* Generator - Bottom Left */}
+
+
+
+
+
+
+