285 lines
9.6 KiB
TypeScript
285 lines
9.6 KiB
TypeScript
"use client";
|
||
|
||
import * as React from "react";
|
||
|
||
import { Loading } from "@/components/ui/loading";
|
||
import { FadeInStagger } from "@/components/landing/fade-in";
|
||
import { Input } from "@/components/ui/input";
|
||
import { toast } from "@/components/ui/toaster";
|
||
import { useRouter } from "next/navigation";
|
||
import service from "@/lib/http/service";
|
||
|
||
import Image from 'next/image';
|
||
import showImage from '@/components/images/show.png';
|
||
import { useTranslation } from "react-i18next";
|
||
|
||
|
||
export function MixSignUp(props: {
|
||
setError: (e: string | null) => void;
|
||
setVerification: (b: boolean) => void;
|
||
|
||
email: (value: string) => void;
|
||
password: (value: string) => void;
|
||
emailValue: string;
|
||
passwordValue: string;
|
||
}) {
|
||
|
||
const [isLoading, setIsLoading] = React.useState(false);
|
||
const [showPassword, setShowPassword] = React.useState(false);
|
||
const [showPassword2, setShowPassword2] = React.useState(false);
|
||
|
||
const [goPassword, setGoPassword] = React.useState(false);
|
||
const [_transferLoading, setTransferLoading] = React.useState(true);
|
||
|
||
const router = useRouter();
|
||
const { t } = useTranslation();
|
||
React.useEffect(() => {
|
||
const signUpFromParams = async () => {
|
||
const ticket = new URL(window.location.href).searchParams.get("__clerk_ticket");
|
||
const emailParam = new URL(window.location.href).searchParams.get("email");
|
||
|
||
if (!ticket && !emailParam) {
|
||
return;
|
||
}
|
||
|
||
if (ticket) {
|
||
// await signUp
|
||
// ?.create({
|
||
// strategy: "ticket",
|
||
// ticket,
|
||
// })
|
||
// .then((result) => {
|
||
// if (result.status === "complete" && result.createdSessionId) {
|
||
// setActive({ session: result.createdSessionId }).then(() => {
|
||
// router.push("/app/apis");
|
||
// });
|
||
// }
|
||
// })
|
||
// .catch((err) => {
|
||
// setTransferLoading(false);
|
||
// setError((err as Error).message);
|
||
// console.error(err);
|
||
// });
|
||
}
|
||
|
||
if (emailParam) {
|
||
// setVerification(true);
|
||
// await signUp
|
||
// ?.create({
|
||
// emailAddress: emailParam,
|
||
// })
|
||
// .then(async () => {
|
||
// await signUp.prepareEmailAddressVerification();
|
||
// // set verification to true so we can show the code input
|
||
// setVerification(true);
|
||
// setTransferLoading(false);
|
||
// })
|
||
// .catch((err) => {
|
||
// setTransferLoading(false);
|
||
// if (err.errors[0].code === "form_identifier_exists") {
|
||
// toast.error("Sorry, it looks like you have an account. Please use sign in");
|
||
// } else {
|
||
// console.log("Supress error");
|
||
// }
|
||
// });
|
||
}
|
||
};
|
||
signUpFromParams();
|
||
setTransferLoading(false);
|
||
}, []);
|
||
|
||
const signUpWithCode = async (username: string, password: string) => {
|
||
|
||
console.log("-------------username---------", username, "-------------password---------", password);
|
||
|
||
if (
|
||
isLoading ||
|
||
typeof username !== "string"
|
||
) {
|
||
return null;
|
||
}
|
||
|
||
setIsLoading(true)
|
||
|
||
try {
|
||
await service.post('/api/v1/common/auth-code', {
|
||
user_name: username,
|
||
email: username,
|
||
}).then(function (result: any) {
|
||
setIsLoading(false);
|
||
console.log("==================> result:", result);
|
||
|
||
// 如果返回的header中的code不为0,表示失败
|
||
if (result && result.header.code !== 0) {
|
||
toast.error(result.header.message); // 提示错误信息
|
||
return;
|
||
}
|
||
|
||
props.password(password); // 设置密码
|
||
toast.success(result.header.message); // 提示成功信息
|
||
props.setVerification(true); // 更新状态
|
||
|
||
}).catch((err: any) => {
|
||
setIsLoading(false);
|
||
|
||
// 更详细的错误信息
|
||
if (err.response) {
|
||
// 如果是网络请求返回的错误(如 4xx 或 5xx 错误)
|
||
console.error("Response Error:", err.response);
|
||
toast.error(`API 错误: ${err.response.status} - ${err.response.data.message || '未知错误'}`);
|
||
} else if (err.request) {
|
||
// 如果请求没有响应
|
||
console.error("Request Error:", err.request);
|
||
toast.error("请求超时或无法连接到服务器");
|
||
} else {
|
||
// 其他错误(如代码错误)
|
||
console.error("General Error:", err.message);
|
||
toast.error(`发生了一个错误: ${err.message}`);
|
||
}
|
||
});
|
||
} catch (err) {
|
||
setIsLoading(false);
|
||
console.error("Unexpected Error:", err);
|
||
toast.error("发生了一个意外错误");
|
||
}
|
||
|
||
};
|
||
|
||
return (
|
||
<FadeInStagger>
|
||
{!goPassword ?
|
||
<form className="grid gap-2" onSubmit={(e) => {
|
||
e.preventDefault();
|
||
const regname = new FormData(e.currentTarget).get("regname");
|
||
|
||
if (
|
||
typeof regname !== "string"
|
||
) {
|
||
return null;
|
||
}
|
||
|
||
console.log("------1", regname)
|
||
props.email(regname)
|
||
|
||
setGoPassword(true)
|
||
}}>
|
||
<div className="grid gap-4 mb-0">
|
||
<div className="flex flex-col items-start gap-2">
|
||
|
||
<label htmlFor="regname" className="text-xs text-black/50">
|
||
{t("mixaccount")}
|
||
</label>
|
||
|
||
<Input
|
||
name="regname"
|
||
placeholder={t("auth.mixplacehoder")}
|
||
type="text"
|
||
defaultValue={props.emailValue}
|
||
autoCapitalize="none"
|
||
autoComplete="on"
|
||
autoCorrect="off"
|
||
required
|
||
className="h-10 text-black duration-500 bg-transparent focus:text-black border-black/20 focus:bg-white focus:border-black rounded hover:bg-white/20 hover:border-black/40 placeholder:black/20 "
|
||
/>
|
||
|
||
<label htmlFor="referralcode" className="text-xs text-black/50">
|
||
{t("refcode")}
|
||
</label>
|
||
|
||
<Input
|
||
name="referralcode"
|
||
placeholder={t("auth.refcodeplaceholder")}
|
||
type="text"
|
||
defaultValue={props.emailValue}
|
||
autoCapitalize="none"
|
||
autoComplete="on"
|
||
autoCorrect="off"
|
||
className="h-10 text-black duration-500 bg-transparent focus:text-black border-black/20 focus:bg-white focus:border-black rounded hover:bg-white/20 hover:border-black/40 placeholder:black/20 "
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
type="submit"
|
||
className="flex items-center justify-center h-10 gap-2 px-4 mt-8 text-sm font-semibold text-white duration-200 bg-black border border-black rounded hover:border-black/30 hover:bg-black/80 hover:text-white"
|
||
disabled={isLoading}
|
||
>
|
||
{t("next")}
|
||
</button>
|
||
|
||
</form> : <form className="grid gap-2" onSubmit={async (e) => {
|
||
e.preventDefault();
|
||
const password = new FormData(e.currentTarget).get("password");
|
||
const confirmPassword = new FormData(e.currentTarget).get("confirmPassword");
|
||
|
||
console.log("------1", props.emailValue, password, confirmPassword)
|
||
|
||
if (typeof password !== "string" || password != confirmPassword) {
|
||
toast.error("two passwords do not match")
|
||
return
|
||
}
|
||
|
||
await signUpWithCode(props.emailValue, password)
|
||
|
||
setGoPassword(false)
|
||
}} >
|
||
|
||
<div className="grid gap-4 mb-4">
|
||
<label htmlFor="password" className="text-xs text-black/50">
|
||
{t("password")}
|
||
</label>
|
||
<div className="grid gap-1 relative">
|
||
<Input
|
||
name="password"
|
||
placeholder={t("password")}
|
||
type={showPassword ? "text" : "password"}
|
||
autoCapitalize="none"
|
||
autoComplete="email"
|
||
autoCorrect="off"
|
||
required
|
||
className="h-10 rounded text-black duration-500 bg-transparent focus:text-black border-black/20 focus:bg-white focus:border-black hover:bg-white/20 hover:border-black/40 placeholder:black/20 "
|
||
/>
|
||
<Image src={showImage} width={16} alt="show" className="absolute right-4 top-3" onClick={() => {
|
||
setShowPassword(!showPassword)
|
||
}} />
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid gap-4 mb-4">
|
||
|
||
<label htmlFor="password" className="text-xs text-black/50">
|
||
{t("confirm_password")}
|
||
</label>
|
||
|
||
<div className="grid gap-1 relative">
|
||
<Input
|
||
name="confirmPassword"
|
||
placeholder={t("confirm_password")}
|
||
type={showPassword2 ? "text" : "password"}
|
||
autoCapitalize="none"
|
||
autoComplete="password"
|
||
autoCorrect="off"
|
||
required
|
||
className="h-10 rounded text-black duration-500 bg-transparent focus:text-black border-black/20 focus:bg-white focus:border-black hover:bg-white/20 hover:border-black/40 placeholder:black/20 "
|
||
/>
|
||
<Image src={showImage} width={16} alt="show" className="absolute right-4 top-3" onClick={() => {
|
||
setShowPassword2(!showPassword2)
|
||
}} />
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<button
|
||
type="submit"
|
||
className="flex items-center justify-center h-10 gap-2 px-4 mt-8 text-sm font-semibold text-white duration-200 bg-black border border-black rounded hover:border-black/30 hover:bg-black/80 hover:text-white"
|
||
disabled={isLoading}
|
||
>
|
||
{isLoading ? <Loading className="w-4 h-4 animate-spin" /> : "Next"}
|
||
</button>
|
||
|
||
</form>}
|
||
|
||
</FadeInStagger>
|
||
);
|
||
};
|