修复问题

This commit is contained in:
海龙 2025-08-29 05:19:54 +08:00
parent c499d14167
commit 4bd097691c
4 changed files with 116 additions and 92 deletions

View File

@ -49,6 +49,7 @@ export const getUploadToken = async (timeoutMs: number = 10000): Promise<{ token
headers: { headers: {
Accept: "application/json", Accept: "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": `Bearer ${localStorage.getItem("token")}`
}, },
signal: controller.signal, signal: controller.signal,
mode: "cors", mode: "cors",
@ -103,7 +104,7 @@ export const generateUniqueFileName = (originalName: string): string => {
// 七牛云上传 // 七牛云上传
export const uploadToQiniu = async ( export const uploadToQiniu = async (
file: File, file: File,
token: string, token: string,
onProgress?: (progress: number) => void onProgress?: (progress: number) => void
): Promise<string> => { ): Promise<string> => {
@ -153,4 +154,4 @@ export const uploadToQiniu = async (
xhr.open("POST", "https://up-z2.qiniup.com") xhr.open("POST", "https://up-z2.qiniup.com")
xhr.send(formData) xhr.send(formData)
}) })
} }

View File

@ -181,44 +181,7 @@ function HomeModule5() {
))} ))}
</div> </div>
{/* 额外价格卡片 */}
<div className="flex gap-[1.5rem] w-[90%] px-[12rem]">
<div className="flex-1 bg-black rounded-lg p-[1.5rem] border border-white/20">
<h3 className="text-white text-[1.5rem] font-bold mb-[0.5rem]">
Free
</h3>
<div className="mb-[1rem]">
<span className="text-white text-[2.5rem] font-bold">$0</span>
</div>
<p className="text-white text-[0.875rem] mb-[1.5rem] leading-relaxed">
10 Video mins and 1 AI credit per week, 1 Express avatar, 4 Exports
per week with invideo watermark.
</p>
<p className="text-white text-[0.875rem] mb-[1.5rem] leading-relaxed">
No access to generative features.
</p>
<button className="w-[9rem] bg-[#262626] text-white py-[0.75rem] rounded-full hover:bg-white hover:text-black transition-colors border border-white/20">
Try For Free
</button>
</div>
<div className="flex-1 bg-black rounded-lg p-[1.5rem] border border-white/20">
<h3 className="text-white text-[1.5rem] font-bold mb-[0.5rem]">
Enterprise
</h3>
<p className="text-white text-[2.5rem] mb-[1rem]">Custom</p>
<p className="text-white text-[0.875rem] mb-[1.5rem] leading-relaxed">
Custom solutions for large organizations. Advanced security and
flexible pricing based on your needs.
</p>
<p className="text-white text-[0.875rem] mb-[1.5rem] leading-relaxed">
on your needs.
</p>
<button className="w-[9rem] bg-[#262626] text-white py-[0.75rem] rounded-full hover:bg-white hover:text-black transition-colors border border-white/20">
Contact Us
</button>
</div>
</div>
</div> </div>
); );
} }

View File

@ -5,16 +5,20 @@ import { useRouter } from "next/navigation";
import Link from "next/link"; import Link from "next/link";
import { signInWithGoogle, registerUser } from "@/lib/auth"; import { signInWithGoogle, registerUser } from "@/lib/auth";
import { GradientText } from "@/components/ui/gradient-text"; import { GradientText } from "@/components/ui/gradient-text";
import { Eye, EyeOff } from "lucide-react";
export default function SignupPage() { export default function SignupPage() {
const [name, setName] = useState(""); const [name, setName] = useState("");
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [inviteCode, setInviteCode] = useState(""); const [inviteCode, setInviteCode] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [formError, setFormError] = useState(""); const [formError, setFormError] = useState("");
const [passwordError, setPasswordError] = useState(""); const [passwordError, setPasswordError] = useState("");
const [confirmPasswordError, setConfirmPasswordError] = useState("");
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const router = useRouter(); const router = useRouter();
/** Password validation function with English prompts */ /** Password validation function with English prompts */
@ -31,7 +35,7 @@ export default function SignupPage() {
return ""; return "";
}; };
/** 处理密码输入变化 */ /** 处理密码输入变化 */
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newPassword = e.target.value; const newPassword = e.target.value;
setPassword(newPassword); setPassword(newPassword);
@ -42,9 +46,34 @@ export default function SignupPage() {
} else { } else {
setPasswordError(""); setPasswordError("");
} }
// 如果确认密码已输入,重新验证确认密码
if (confirmPassword) {
if (newPassword !== confirmPassword) {
setConfirmPasswordError("Passwords do not match");
} else {
setConfirmPasswordError("");
}
}
}; };
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { /** 处理确认密码输入变化 */
const handleConfirmPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newConfirmPassword = e.target.value;
setConfirmPassword(newConfirmPassword);
if (newConfirmPassword) {
if (password !== newConfirmPassword) {
setConfirmPasswordError("Passwords do not match");
} else {
setConfirmPasswordError("");
}
} else {
setConfirmPasswordError("");
}
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
// 验证密码 // 验证密码
@ -54,6 +83,12 @@ export default function SignupPage() {
return; return;
} }
// 验证确认密码
if (password !== confirmPassword) {
setConfirmPasswordError("Passwords do not match");
return;
}
setIsSubmitting(true); setIsSubmitting(true);
setFormError(""); setFormError("");
@ -76,9 +111,6 @@ export default function SignupPage() {
} }
}; };
const handleGoogleSignIn = () => {
signInWithGoogle();
};
return ( return (
<div className="min-h-screen relative overflow-hidden"> <div className="min-h-screen relative overflow-hidden">
@ -121,9 +153,9 @@ export default function SignupPage() {
{/* 注册框 - 居中显示 */} {/* 注册框 - 居中显示 */}
<div className="relative bottom-4 z-10 flex items-center justify-center min-h-screen p-4"> <div className="relative bottom-4 z-10 flex items-center justify-center min-h-screen p-4">
<div className="max-w-md w-full bg-black/40 backdrop-blur-lg border border-white/20 rounded-2xl p-8 shadow-2xl"> <div className="max-w-md w-full bg-black/40 backdrop-blur-lg border border-white/20 rounded-2xl p-6 shadow-2xl">
<div className="text-center mb-6"> <div className="text-center mb-4">
<h2 className="text-2xl font-bold text-white mb-4"> <h2 className="text-2xl font-bold text-white mb-2">
Sign Up, for free Sign Up, for free
</h2> </h2>
<p className="text-gray-300">Create your account to get started</p> <p className="text-gray-300">Create your account to get started</p>
@ -158,40 +190,70 @@ export default function SignupPage() {
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-white mb-1"> <label className="block text-sm font-medium text-white mb-1">
Password Password
</label> </label>
<div className="relative"> <div className="relative">
<input <input
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
placeholder="8-18位英文字母+数字组合" placeholder="8-18 characters, letters and numbers"
value={password} value={password}
onChange={handlePasswordChange} onChange={handlePasswordChange}
required required
className={`w-full px-4 py-3 pr-12 rounded-lg bg-black/30 border text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent ${ className={`w-full px-4 py-3 pr-12 rounded-lg bg-black/30 border text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent ${
passwordError ? "border-red-500/50" : "border-white/20" passwordError ? "border-red-500/50" : "border-white/20"
}`} }`}
/> />
<button <button
type="button" type="button"
onClick={() => setShowPassword(!showPassword)} onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-white transition-colors" className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-white transition-colors"
data-alt="toggle-password-visibility" data-alt="toggle-password-visibility"
> >
{showPassword ? "👁️" : "👁️‍🗨️"} {showPassword ? <EyeOff size={20} /> : <Eye size={20} />}
</button> </button>
</div> </div>
{passwordError && (
<p className="mt-1 text-sm text-red-400">{passwordError}</p> <div>
)} <label className="block text-sm font-medium text-white mb-1 mt-3">
{password && !passwordError && ( Confirm Password
<p className="mt-1 text-sm text-green-400"> Password format is correct</p> </label>
)} <div className="relative">
<p className="mt-1 text-xs text-gray-400"> <input
Password requirements: 8-18 characters, must contain letters and numbers type={showConfirmPassword ? "text" : "password"}
</p> placeholder="Confirm your password"
</div> value={confirmPassword}
onChange={handleConfirmPasswordChange}
required
className={`w-full px-4 py-3 pr-12 rounded-lg bg-black/30 border text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent ${
confirmPasswordError ? "border-red-500/50" : "border-white/20"
}`}
/>
<button
type="button"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-white transition-colors"
data-alt="toggle-confirm-password-visibility"
>
{showConfirmPassword ? <EyeOff size={20} /> : <Eye size={20} />}
</button>
</div>
</div>
{passwordError && (
<p className="mt-1 text-sm text-red-400">{passwordError}</p>
)}
{confirmPasswordError && (
<p className="mt-1 text-sm text-red-400">{confirmPasswordError}</p>
)}
{password && !passwordError && (
<p className="mt-1 text-sm text-green-400"> Password format is correct</p>
)}
{confirmPassword && !confirmPasswordError && (
<p className="mt-1 text-sm text-green-400"> Passwords match</p>
)}
</div>
<div> <div>
<label className="block text-sm font-medium text-white mb-1"> <label className="block text-sm font-medium text-white mb-1">
@ -221,8 +283,8 @@ export default function SignupPage() {
</Link> </Link>
<button <button
type="submit" type="submit"
disabled={isSubmitting || !!passwordError || !password} disabled={isSubmitting || !!passwordError || !!confirmPasswordError || !password || !confirmPassword}
className="flex-1 py-3 rounded-lg bg-purple-600 hover:bg-purple-700 text-white font-medium transition-colors disabled:opacity-70" className="flex-1 py-3 rounded-lg cursor-pointer bg-[#C039F6] hover:bg-[#C039F6]/80 text-white font-medium transition-colors disabled:opacity-70"
> >
{isSubmitting ? "Signing up..." : "Sign Up"} {isSubmitting ? "Signing up..." : "Sign Up"}
</button> </button>

View File

@ -147,9 +147,9 @@ export default function Login() {
{/* 登录框 - 居中显示 */} {/* 登录框 - 居中显示 */}
<div className="relative bottom-4 z-10 flex items-center justify-center min-h-screen p-4"> <div className="relative bottom-4 z-10 flex items-center justify-center min-h-screen p-4">
<div className="auth-container max-w-md w-full !bg-black/60 backdrop-blur-lg border border-white/20 rounded-2xl p-8 shadow-2xl"> <div className="auth-container max-w-md w-full !bg-black/40 backdrop-blur-lg border border-white/20 rounded-2xl p-6 shadow-2xl">
<div className="auth-header text-center mb-6"> <div className="auth-header text-center mb-4">
<h2 className="text-2xl font-bold text-white pb-4">Login</h2> <h2 className="text-2xl font-bold text-white pb-2">Login</h2>
<p className="text-gray-300"> <p className="text-gray-300">
Enter your credentials to access your account Enter your credentials to access your account
</p> </p>
@ -177,7 +177,7 @@ export default function Login() {
<label className="form-label">Password</label> <label className="form-label">Password</label>
<div className="relative"> <div className="relative">
<input <input
placeholder="8-18位英文字母+数字组合" placeholder="8-18 characters, letters and numbers"
required required
className={`form-control pr-10 ${ className={`form-control pr-10 ${
passwordError ? "border-red-500/50" : "" passwordError ? "border-red-500/50" : ""
@ -201,9 +201,7 @@ export default function Login() {
{password && !passwordError && ( {password && !passwordError && (
<p className="mt-1 text-sm text-green-400"> Password format is correct</p> <p className="mt-1 text-sm text-green-400"> Password format is correct</p>
)} )}
<p className="mt-1 text-xs text-gray-400">
Password requirements: 8-18 characters, must contain letters and numbers
</p>
{/* <div className="flex justify-end mt-2"> {/* <div className="flex justify-end mt-2">
<a <a
className="auth-link small" className="auth-link small"
@ -223,7 +221,7 @@ export default function Login() {
<button <button
type="submit" type="submit"
className="w-full mt-4 btn btn-primary" className="w-full mt-4 btn py-3 rounded-lg cursor-pointer !bg-[#C039F6] hover:!bg-[#C039F6]/80"
disabled={isSubmitting || !!passwordError || !password} disabled={isSubmitting || !!passwordError || !password}
> >
{isSubmitting ? "Logging in..." : "Login"} {isSubmitting ? "Logging in..." : "Login"}
@ -247,7 +245,7 @@ export default function Login() {
<div className="text-center mt-4"> <div className="text-center mt-4">
<p style={{ color: "rgba(255, 255, 255, 0.6)" }}> <p style={{ color: "rgba(255, 255, 255, 0.6)" }}>
Don't have an account?{" "} Don't have an account?{" "}
<Link href="/signup" className="auth-link"> <Link href="/signup" className="auth-link !text-[#C039F6]">
Sign up Sign up
</Link> </Link>
</p> </p>