TradingAgents/frontend/components/analysis/AnalysisForm.tsx

179 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Analysis form component
*/
"use client";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { format } from "date-fns";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import type { AnalysisRequest } from "@/lib/types";
const formSchema = z.object({
ticker: z.string().min(1, "股票代碼為必填").max(10),
analysis_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "日期格式必須為 YYYY-MM-DD"),
research_depth: z.number().min(1).max(5),
deep_think_llm: z.string(),
quick_think_llm: z.string(),
});
interface AnalysisFormProps {
onSubmit: (data: AnalysisRequest) => void;
loading?: boolean;
}
export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
ticker: "NVDA",
analysis_date: format(new Date(), "yyyy-MM-dd"),
research_depth: 1,
deep_think_llm: "gpt-4o-mini",
quick_think_llm: "gpt-4o-mini",
},
});
function handleSubmit(values: z.infer<typeof formSchema>) {
const request: AnalysisRequest = {
...values,
analysts: ["market", "sentiment", "news", "fundamentals"],
};
onSubmit(request);
}
return (
<Card className="w-full shadow-lg">
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<FormField
control={form.control}
name="ticker"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input placeholder="NVDA" {...field} />
</FormControl>
<FormDescription>
NVDAAAPL
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="analysis_date"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormControl>
<Input type="date" {...field} />
</FormControl>
<FormDescription>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="research_depth"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<Select
onValueChange={(value) => field.onChange(parseInt(value))}
defaultValue={field.value.toString()}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="選擇深度" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="1">1 - </SelectItem>
<SelectItem value="2">2 - </SelectItem>
<SelectItem value="3">3 - </SelectItem>
<SelectItem value="4">4 - </SelectItem>
<SelectItem value="5">5 - </SelectItem>
</SelectContent>
</Select>
<FormDescription>
=
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="deep_think_llm"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="選擇模型" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="gpt-4o">GPT-4o</SelectItem>
<SelectItem value="gpt-4o-mini">GPT-4o Mini</SelectItem>
<SelectItem value="gpt-4-turbo">GPT-4 Turbo</SelectItem>
</SelectContent>
</Select>
<FormDescription>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</div>
<Button type="submit" className="w-full" disabled={loading} size="lg">
{loading ? "執行分析中..." : "執行分析"}
</Button>
</form>
</Form>
</CardContent>
</Card>
);
}