geo/frontend/app/(dashboard)/onboarding/Step1BrandName.tsx

137 lines
4.2 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.

"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>
);
}