mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
artcraft signup as first step and allow skipping open ai login
This commit is contained in:
1 parent
cb868c7275
commit
bc90084b37
1 file changed
+130
-117
@@ -39,8 +39,18 @@ export function LoginModal({
|
||||
const [isLoggedInArtCraft, setIsLoggedInArtCraft] = useState(false);
|
||||
const [isSignUp, setIsSignUp] = useState(true);
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const totalSteps = isLoggedInArtCraft ? 3 : 4;
|
||||
const artCraftFormRef = useRef<HTMLFormElement>(null);
|
||||
const [initialArtCraftLoginStatusForUI, setInitialArtCraftLoginStatusForUI] =
|
||||
useState<boolean | null>(null);
|
||||
|
||||
const uiTotalSteps = initialArtCraftLoginStatusForUI ? 3 : 4;
|
||||
let uiCurrentStep = step;
|
||||
|
||||
if (initialArtCraftLoginStatusForUI) {
|
||||
if (step === 1) uiCurrentStep = 1;
|
||||
else if (step === 3) uiCurrentStep = 2;
|
||||
else if (step === 4) uiCurrentStep = 3;
|
||||
}
|
||||
|
||||
const initSession = async () => {
|
||||
const result = await CheckSoraSession();
|
||||
@@ -60,7 +70,7 @@ export function LoginModal({
|
||||
if (isLoggedInArtCraft) {
|
||||
setStep(4);
|
||||
} else {
|
||||
setStep(3);
|
||||
setStep(2);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,115 +79,43 @@ export function LoginModal({
|
||||
// Run both checks in parallel
|
||||
Promise.all([initSession(), checkArtCraftLogin()]).then(
|
||||
([soraSessionExists, loggedIn]) => {
|
||||
setInitialArtCraftLoginStatusForUI(loggedIn || false); // Set initial status for UI step counting
|
||||
|
||||
if (soraSessionExists && !loggedIn) {
|
||||
// Sora session exists, but not logged in to ArtCraft
|
||||
setIsOpen(true);
|
||||
setStep(3);
|
||||
setStep(2);
|
||||
setIsLoggedInArtCraft(false);
|
||||
} else if (!soraSessionExists && loggedIn) {
|
||||
// No Sora session, but logged in to ArtCraft
|
||||
setIsOpen(true);
|
||||
setStep(2);
|
||||
setStep(3);
|
||||
setIsLoggedInArtCraft(true);
|
||||
// setIsOpen(false);
|
||||
} else if (!soraSessionExists) {
|
||||
// No Sora session, start at step 1
|
||||
setIsOpen(true);
|
||||
setStep(1);
|
||||
setIsLoggedInArtCraft(false); // Ensure this is also set
|
||||
} else if (loggedIn) {
|
||||
// Already logged in, no need to show modal
|
||||
setIsLoggedInArtCraft(true);
|
||||
// setIsOpen(false);
|
||||
// setIsOpen(false); // This would prevent modal from showing if fully logged in
|
||||
}
|
||||
}
|
||||
);
|
||||
}, []);
|
||||
}, []); // Empty dependency array ensures this runs once on mount
|
||||
|
||||
useEffect(() => {
|
||||
if (onOpenChange) onOpenChange(isOpen);
|
||||
}, [isOpen, onOpenChange]);
|
||||
|
||||
const handleArtCraftAuth = async (
|
||||
username: string,
|
||||
email: string,
|
||||
password: string,
|
||||
passwordConfirmation: string
|
||||
) => {
|
||||
setIsLoading(true);
|
||||
const usersApi = new UsersApi();
|
||||
try {
|
||||
let signupResponse, loginResponse;
|
||||
if (isSignUp) {
|
||||
// Sign up
|
||||
signupResponse = await usersApi.Signup({
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
passwordConfirmation,
|
||||
});
|
||||
if (!signupResponse.success) {
|
||||
// TODO: Add error handling UI
|
||||
console.error(signupResponse.errorMessage || "Signup failed");
|
||||
setErrorMessage(
|
||||
signupResponse.errorMessage || "Signup failed, please try again."
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Automatically login after successful signup
|
||||
loginResponse = await usersApi.Login({
|
||||
usernameOrEmail: username || email,
|
||||
password,
|
||||
});
|
||||
if (!loginResponse.success) {
|
||||
// TODO: Add error handling UI
|
||||
console.error(
|
||||
loginResponse.errorMessage || "Login after signup failed"
|
||||
);
|
||||
setErrorMessage(
|
||||
loginResponse.errorMessage ||
|
||||
"Login after signup failed, please try again. "
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Login
|
||||
loginResponse = await usersApi.Login({
|
||||
usernameOrEmail: username || email,
|
||||
password,
|
||||
});
|
||||
if (!loginResponse.success) {
|
||||
// TODO: Add error handling UI
|
||||
console.error(loginResponse.errorMessage || "Login failed");
|
||||
setErrorMessage(
|
||||
loginResponse.errorMessage || "Login failed, please try again."
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setStep(4);
|
||||
|
||||
const session = await usersApi.GetSession();
|
||||
const userInfo = session.data?.user;
|
||||
if (onArtCraftAuthSuccess && userInfo) {
|
||||
onArtCraftAuthSuccess(userInfo);
|
||||
}
|
||||
} catch (e) {
|
||||
// handle error (show error message, etc.)
|
||||
// TODO: Add error handling UI
|
||||
console.error(e);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setIsOpen(false);
|
||||
onClose();
|
||||
};
|
||||
|
||||
const handleNext = async () => {
|
||||
if (step === 2) {
|
||||
if (step === 3) {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (IsDesktopApp()) {
|
||||
@@ -201,7 +139,7 @@ export function LoginModal({
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
} else if (step === 3) {
|
||||
} else if (step === 2) {
|
||||
// Trigger the form submit in ArtCraftSignUp
|
||||
if (artCraftFormRef.current) {
|
||||
artCraftFormRef.current.requestSubmit();
|
||||
@@ -218,11 +156,11 @@ export function LoginModal({
|
||||
// Progress bar rendering
|
||||
const renderProgress = () => (
|
||||
<div className="flex items-center justify-center gap-2 mb-2">
|
||||
{[...Array(totalSteps)].map((_, idx) => (
|
||||
{[...Array(uiTotalSteps)].map((_, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={`h-1.5 rounded transition-all duration-300 w-16 ${
|
||||
idx < step ? "bg-primary" : "bg-white/30"
|
||||
idx < uiCurrentStep ? "bg-primary" : "bg-white/30"
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
@@ -231,8 +169,8 @@ export function LoginModal({
|
||||
|
||||
// Step content rendering
|
||||
const renderStepContent = () => {
|
||||
if (step === 3 && isLoggedInArtCraft) {
|
||||
setStep(4);
|
||||
if (step === 2 && isLoggedInArtCraft) {
|
||||
setStep(3);
|
||||
return null;
|
||||
}
|
||||
switch (step) {
|
||||
@@ -282,6 +220,82 @@ export function LoginModal({
|
||||
</div>
|
||||
);
|
||||
case 2:
|
||||
return (
|
||||
<ArtCraftSignUp
|
||||
onSubmit={async (
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
passwordConfirmation
|
||||
) => {
|
||||
setIsLoading(true);
|
||||
const usersApi = new UsersApi();
|
||||
try {
|
||||
let signupResponse, loginResponse;
|
||||
if (isSignUp) {
|
||||
signupResponse = await usersApi.Signup({
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
passwordConfirmation,
|
||||
});
|
||||
if (!signupResponse.success) {
|
||||
setErrorMessage(
|
||||
signupResponse.errorMessage ||
|
||||
"Signup failed, please try again."
|
||||
);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
loginResponse = await usersApi.Login({
|
||||
usernameOrEmail: username || email,
|
||||
password,
|
||||
});
|
||||
if (!loginResponse.success) {
|
||||
setErrorMessage(
|
||||
loginResponse.errorMessage ||
|
||||
"Login after signup failed, please try again. "
|
||||
);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
loginResponse = await usersApi.Login({
|
||||
usernameOrEmail: username || email,
|
||||
password,
|
||||
});
|
||||
if (!loginResponse.success) {
|
||||
setErrorMessage(
|
||||
loginResponse.errorMessage ||
|
||||
"Login failed, please try again."
|
||||
);
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
setIsLoggedInArtCraft(true);
|
||||
if (onArtCraftAuthSuccess) {
|
||||
const session = await usersApi.GetSession();
|
||||
const userInfo = session.data?.user;
|
||||
if (userInfo) onArtCraftAuthSuccess(userInfo);
|
||||
}
|
||||
setStep(3);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setErrorMessage(
|
||||
"An unexpected error occurred. Please try again."
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
isSignUp={isSignUp}
|
||||
onToggleMode={() => setIsSignUp((prev) => !prev)}
|
||||
formRef={artCraftFormRef}
|
||||
errorMessage={errorMessage}
|
||||
/>
|
||||
);
|
||||
case 3:
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
<h2 className="text-3xl font-bold mb-2 text-center">
|
||||
@@ -300,16 +314,6 @@ export function LoginModal({
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
case 3:
|
||||
return (
|
||||
<ArtCraftSignUp
|
||||
onSubmit={handleArtCraftAuth}
|
||||
isSignUp={isSignUp}
|
||||
onToggleMode={() => setIsSignUp((prev) => !prev)}
|
||||
formRef={artCraftFormRef}
|
||||
errorMessage={errorMessage}
|
||||
/>
|
||||
);
|
||||
case 4:
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
@@ -366,7 +370,7 @@ export function LoginModal({
|
||||
>
|
||||
<div className="flex flex-col gap-4 p-8 h-full">
|
||||
<span className="text-sm text-center opacity-60 font-medium">
|
||||
Step {step} of {totalSteps}
|
||||
Step {uiCurrentStep} of {uiTotalSteps}
|
||||
</span>
|
||||
{renderProgress()}
|
||||
{renderStepContent()}
|
||||
@@ -380,25 +384,16 @@ export function LoginModal({
|
||||
Back
|
||||
</Button>
|
||||
) : null}
|
||||
{step < totalSteps ? (
|
||||
<>
|
||||
<Button
|
||||
icon={step === 2 ? faRightToBracket : faArrowRight}
|
||||
iconFlip={step !== 2}
|
||||
onClick={handleNext}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{step === 2
|
||||
? "Login with OpenAI"
|
||||
: step === 3
|
||||
? isSignUp
|
||||
? "Sign up"
|
||||
: "Login"
|
||||
: "Continue"}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
{step === 3 && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={handleClose}
|
||||
disabled={isLoading}
|
||||
>
|
||||
Skip for now
|
||||
</Button>
|
||||
)}
|
||||
{step === 4 ? (
|
||||
<Button
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
@@ -406,6 +401,24 @@ export function LoginModal({
|
||||
>
|
||||
Start Creating Now
|
||||
</Button>
|
||||
) : (
|
||||
<>
|
||||
<Button
|
||||
icon={step === 3 ? faRightToBracket : faArrowRight}
|
||||
iconFlip={step !== 3}
|
||||
onClick={handleNext}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{step === 1
|
||||
? "Continue"
|
||||
: step === 2
|
||||
? isSignUp
|
||||
? "Sign up"
|
||||
: "Login"
|
||||
: "Login with OpenAI"}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user