forked from 77media/video-flow
修复问题
This commit is contained in:
parent
c499d14167
commit
4bd097691c
@ -49,6 +49,7 @@ export const getUploadToken = async (timeoutMs: number = 10000): Promise<{ token
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${localStorage.getItem("token")}`
|
||||
},
|
||||
signal: controller.signal,
|
||||
mode: "cors",
|
||||
@ -103,7 +104,7 @@ export const generateUniqueFileName = (originalName: string): string => {
|
||||
|
||||
// 七牛云上传
|
||||
export const uploadToQiniu = async (
|
||||
file: File,
|
||||
file: File,
|
||||
token: string,
|
||||
onProgress?: (progress: number) => void
|
||||
): Promise<string> => {
|
||||
@ -153,4 +154,4 @@ export const uploadToQiniu = async (
|
||||
xhr.open("POST", "https://up-z2.qiniup.com")
|
||||
xhr.send(formData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,44 +181,7 @@ function HomeModule5() {
|
||||
))}
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,16 +5,20 @@ import { useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import { signInWithGoogle, registerUser } from "@/lib/auth";
|
||||
import { GradientText } from "@/components/ui/gradient-text";
|
||||
import { Eye, EyeOff } from "lucide-react";
|
||||
|
||||
export default function SignupPage() {
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [inviteCode, setInviteCode] = useState("");
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [formError, setFormError] = useState("");
|
||||
const [passwordError, setPasswordError] = useState("");
|
||||
const [confirmPasswordError, setConfirmPasswordError] = useState("");
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
/** Password validation function with English prompts */
|
||||
@ -31,7 +35,7 @@ export default function SignupPage() {
|
||||
return "";
|
||||
};
|
||||
|
||||
/** 处理密码输入变化 */
|
||||
/** 处理密码输入变化 */
|
||||
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newPassword = e.target.value;
|
||||
setPassword(newPassword);
|
||||
@ -42,9 +46,34 @@ export default function SignupPage() {
|
||||
} else {
|
||||
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();
|
||||
|
||||
// 验证密码
|
||||
@ -54,6 +83,12 @@ export default function SignupPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证确认密码
|
||||
if (password !== confirmPassword) {
|
||||
setConfirmPasswordError("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
setFormError("");
|
||||
|
||||
@ -76,9 +111,6 @@ export default function SignupPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleGoogleSignIn = () => {
|
||||
signInWithGoogle();
|
||||
};
|
||||
|
||||
return (
|
||||
<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="max-w-md w-full bg-black/40 backdrop-blur-lg border border-white/20 rounded-2xl p-8 shadow-2xl">
|
||||
<div className="text-center mb-6">
|
||||
<h2 className="text-2xl font-bold text-white mb-4">
|
||||
<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-4">
|
||||
<h2 className="text-2xl font-bold text-white mb-2">
|
||||
Sign Up, for free
|
||||
</h2>
|
||||
<p className="text-gray-300">Create your account to get started</p>
|
||||
@ -158,40 +190,70 @@ export default function SignupPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-white mb-1">
|
||||
Password
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
type={showPassword ? "text" : "password"}
|
||||
placeholder="8-18位英文字母+数字组合"
|
||||
value={password}
|
||||
onChange={handlePasswordChange}
|
||||
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 ${
|
||||
passwordError ? "border-red-500/50" : "border-white/20"
|
||||
}`}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
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"
|
||||
>
|
||||
{showPassword ? "👁️" : "👁️🗨️"}
|
||||
</button>
|
||||
</div>
|
||||
{passwordError && (
|
||||
<p className="mt-1 text-sm text-red-400">{passwordError}</p>
|
||||
)}
|
||||
{password && !passwordError && (
|
||||
<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>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-white mb-1">
|
||||
Password
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
type={showPassword ? "text" : "password"}
|
||||
placeholder="8-18 characters, letters and numbers"
|
||||
value={password}
|
||||
onChange={handlePasswordChange}
|
||||
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 ${
|
||||
passwordError ? "border-red-500/50" : "border-white/20"
|
||||
}`}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
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"
|
||||
>
|
||||
{showPassword ? <EyeOff size={20} /> : <Eye size={20} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-white mb-1 mt-3">
|
||||
Confirm Password
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
type={showConfirmPassword ? "text" : "password"}
|
||||
placeholder="Confirm your password"
|
||||
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>
|
||||
<label className="block text-sm font-medium text-white mb-1">
|
||||
@ -221,8 +283,8 @@ export default function SignupPage() {
|
||||
</Link>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting || !!passwordError || !password}
|
||||
className="flex-1 py-3 rounded-lg bg-purple-600 hover:bg-purple-700 text-white font-medium transition-colors disabled:opacity-70"
|
||||
disabled={isSubmitting || !!passwordError || !!confirmPasswordError || !password || !confirmPassword}
|
||||
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"}
|
||||
</button>
|
||||
|
||||
@ -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="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-header text-center mb-6">
|
||||
<h2 className="text-2xl font-bold text-white pb-4">Login</h2>
|
||||
<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-4">
|
||||
<h2 className="text-2xl font-bold text-white pb-2">Login</h2>
|
||||
<p className="text-gray-300">
|
||||
Enter your credentials to access your account
|
||||
</p>
|
||||
@ -177,7 +177,7 @@ export default function Login() {
|
||||
<label className="form-label">Password</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
placeholder="8-18位英文字母+数字组合"
|
||||
placeholder="8-18 characters, letters and numbers"
|
||||
required
|
||||
className={`form-control pr-10 ${
|
||||
passwordError ? "border-red-500/50" : ""
|
||||
@ -201,9 +201,7 @@ export default function Login() {
|
||||
{password && !passwordError && (
|
||||
<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">
|
||||
<a
|
||||
className="auth-link small"
|
||||
@ -223,7 +221,7 @@ export default function Login() {
|
||||
|
||||
<button
|
||||
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}
|
||||
>
|
||||
{isSubmitting ? "Logging in..." : "Login"}
|
||||
@ -247,7 +245,7 @@ export default function Login() {
|
||||
<div className="text-center mt-4">
|
||||
<p style={{ color: "rgba(255, 255, 255, 0.6)" }}>
|
||||
Don't have an account?{" "}
|
||||
<Link href="/signup" className="auth-link">
|
||||
<Link href="/signup" className="auth-link !text-[#C039F6]">
|
||||
Sign up
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user