import { useTranslation } from "react-i18next" // 导入 useTranslation import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { PROFILE_DISPLAY_NAME_MAX, PROFILE_USERNAME_MAX, PROFILE_USERNAME_MIN } from "@/db/limits" import { IconCircleCheckFilled, IconCircleXFilled, IconLoader2 } from "@tabler/icons-react" import { FC, useCallback, useState } from "react" import { LimitDisplay } from "../ui/limit-display" import { toast } from "sonner" interface ProfileStepProps { username: string usernameAvailable: boolean displayName: string onUsernameAvailableChange: (isAvailable: boolean) => void onUsernameChange: (username: string) => void onDisplayNameChange: (name: string) => void } export const ProfileStep: FC = ({ username, usernameAvailable, displayName, onUsernameAvailableChange, onUsernameChange, onDisplayNameChange }) => { const { t } = useTranslation() // 使用 t 函数来获取翻译内容 const [loading, setLoading] = useState(false) const debounce = (func: (...args: any[]) => void, wait: number) => { let timeout: NodeJS.Timeout | null return (...args: any[]) => { const later = () => { if (timeout) clearTimeout(timeout) func(...args) } if (timeout) clearTimeout(timeout) timeout = setTimeout(later, wait) } } const checkUsernameAvailability = useCallback( debounce(async (username: string) => { if (!username) return if (username.length < PROFILE_USERNAME_MIN) { onUsernameAvailableChange(false) return } if (username.length > PROFILE_USERNAME_MAX) { onUsernameAvailableChange(false) return } const usernameRegex = /^[a-zA-Z0-9_]+$/ if (!usernameRegex.test(username)) { onUsernameAvailableChange(false) toast.error( t("login.usernameError") //"Username must be letters, numbers, or underscores only - no other characters or spacing allowed." ) return } setLoading(true) const response = await fetch(`/api/username/available`, { method: "POST", body: JSON.stringify({ username }) }) const data = await response.json() const isAvailable = data.isAvailable onUsernameAvailableChange(isAvailable) setLoading(false) }, 500), [] ) return ( <>
{usernameAvailable ? (
{t("login.available")}
) : (
{t("login.unavailable")}
)}
{ onUsernameChange(e.target.value) checkUsernameAvailability(e.target.value) }} minLength={PROFILE_USERNAME_MIN} maxLength={PROFILE_USERNAME_MAX} />
{loading ? ( ) : usernameAvailable ? ( ) : ( )}
onDisplayNameChange(e.target.value)} maxLength={PROFILE_DISPLAY_NAME_MAX} />
) }