137 lines
4.2 KiB
TypeScript
137 lines
4.2 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { Input } from "@/components/ui/input";
|
||
import { Button } from "@/components/ui/button";
|
||
import { Label } from "@/components/ui/label";
|
||
import { Card, CardContent } from "@/components/ui/card";
|
||
import { Loader2, Sparkles, ArrowRight } from "lucide-react";
|
||
|
||
interface Step1BrandNameProps {
|
||
initialValue?: string;
|
||
onNext: (brandName: string) => void;
|
||
onSkip?: () => void;
|
||
}
|
||
|
||
export function Step1BrandName({
|
||
initialValue = "",
|
||
onNext,
|
||
onSkip,
|
||
}: Step1BrandNameProps) {
|
||
const [brandName, setBrandName] = useState(initialValue);
|
||
const [error, setError] = useState<string | null>(null);
|
||
const [isValidating, setIsValidating] = useState(false);
|
||
|
||
const validateBrandName = async (name: string): Promise<boolean> => {
|
||
if (name.trim().length < 2) {
|
||
setError("品牌名称至少需要2个字符");
|
||
return false;
|
||
}
|
||
if (name.trim().length > 50) {
|
||
setError("品牌名称不能超过50个字符");
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
const handleSubmit = async (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
setError(null);
|
||
|
||
const trimmedName = brandName.trim();
|
||
if (!trimmedName) {
|
||
setError("请输入品牌名称");
|
||
return;
|
||
}
|
||
|
||
setIsValidating(true);
|
||
const isValid = await validateBrandName(trimmedName);
|
||
setIsValidating(false);
|
||
|
||
if (isValid) {
|
||
onNext(trimmedName);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="flex flex-col items-center justify-center py-8">
|
||
<div className="mb-8 text-center">
|
||
<div className="mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-primary/10">
|
||
<Sparkles className="h-8 w-8 text-primary" />
|
||
</div>
|
||
<h2 className="mb-2 text-2xl font-bold">输入您的品牌名称</h2>
|
||
<p className="text-muted-foreground">
|
||
输入您要在AI搜索中监控的品牌名称,我们将为您分析其曝光度
|
||
</p>
|
||
</div>
|
||
|
||
<Card className="w-full max-w-md">
|
||
<CardContent className="pt-6">
|
||
<form onSubmit={handleSubmit} className="space-y-6">
|
||
<div className="space-y-2">
|
||
<Label htmlFor="brandName" className="text-base">
|
||
品牌名称 <span className="text-destructive">*</span>
|
||
</Label>
|
||
<Input
|
||
id="brandName"
|
||
value={brandName}
|
||
onChange={(e) => {
|
||
setBrandName(e.target.value);
|
||
setError(null);
|
||
}}
|
||
placeholder="例如:华为、小米、苹果"
|
||
className="h-12 text-base"
|
||
maxLength={50}
|
||
autoFocus
|
||
/>
|
||
{error && (
|
||
<p className="text-sm text-destructive">{error}</p>
|
||
)}
|
||
<p className="text-xs text-muted-foreground">
|
||
品牌名称创建后可以修改,最多50个字符
|
||
</p>
|
||
</div>
|
||
|
||
<div className="flex flex-col gap-3">
|
||
<Button
|
||
type="submit"
|
||
size="lg"
|
||
className="w-full"
|
||
disabled={isValidating || !brandName.trim()}
|
||
>
|
||
{isValidating ? (
|
||
<>
|
||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||
验证中...
|
||
</>
|
||
) : (
|
||
<>
|
||
开始分析
|
||
<ArrowRight className="ml-2 h-4 w-4" />
|
||
</>
|
||
)}
|
||
</Button>
|
||
|
||
{onSkip && (
|
||
<Button
|
||
type="button"
|
||
variant="ghost"
|
||
onClick={onSkip}
|
||
className="w-full"
|
||
>
|
||
跳过,直接进入Dashboard
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</form>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<div className="mt-8 flex items-center gap-2 text-sm text-muted-foreground">
|
||
<div className="h-2 w-2 rounded-full bg-primary" />
|
||
<span>输入品牌名称后,系统将自动开始监控</span>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|