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: {
|
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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user