Files
Stirling-PDF/frontend/src/desktop/components/SetupWizard/SaaSLoginScreen.tsx
T
James Brunton 8ab060a4be Prettier 2: Electric Boogaloo (#6113)
# Description of Changes
When I added Prettier formatting in #6052, my aim was to use just the
default settings in Prettier. Turns out, Prettier looks _really hard_
for any config files if it's not explicitly given one, which means that
if a developer has some sort of Prettier config file lying around on
their system, Prettier might find it and use it. Also, Prettier changes
its defaults based on stuff in `.editorconfig` without any good way of
disabling that behaviour explicitly in its config file.

To solve both of these issues, I've introduced a `.prettierrc` file
which sets Prettier's defaults explicitly, and then reformatted all our
code _again_ in Prettier's actual default settings. This should achieve
the aim of #6052 and remove the possibility for it breaking on different
dev computers.
2026-04-17 09:50:16 +00:00

143 lines
3.9 KiB
TypeScript

import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import LoginHeader from "@app/routes/login/LoginHeader";
import ErrorMessage from "@app/routes/login/ErrorMessage";
import EmailPasswordForm from "@app/routes/login/EmailPasswordForm";
import DividerWithText from "@app/components/shared/DividerWithText";
import { DesktopOAuthButtons } from "@app/components/SetupWizard/DesktopOAuthButtons";
import { SelfHostedLink } from "@app/components/SetupWizard/SelfHostedLink";
import { UserInfo } from "@app/services/authService";
import "@app/routes/authShared/auth.css";
interface SaaSLoginScreenProps {
serverUrl: string;
onLogin: (username: string, password: string) => Promise<void>;
onOAuthSuccess: (userInfo: UserInfo) => Promise<void>;
onSelfHostedClick: () => void;
onSwitchToSignup: () => void;
onSkipSignIn?: () => void;
onClose?: () => void;
loading: boolean;
error: string | null;
}
export const SaaSLoginScreen: React.FC<SaaSLoginScreenProps> = ({
serverUrl,
onLogin,
onOAuthSuccess,
onSelfHostedClick,
onSwitchToSignup,
onSkipSignIn,
onClose,
loading,
error,
}) => {
const { t } = useTranslation();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [validationError, setValidationError] = useState<string | null>(null);
const handleEmailPasswordSubmit = async () => {
// Validation
if (!email.trim()) {
setValidationError(
t("setup.login.error.emptyEmail", "Please enter your email"),
);
return;
}
if (!password) {
setValidationError(
t("setup.login.error.emptyPassword", "Please enter your password"),
);
return;
}
setValidationError(null);
await onLogin(email.trim(), password);
};
const handleOAuthError = (errorMessage: string) => {
setValidationError(errorMessage);
};
const displayError = error || validationError;
return (
<>
<LoginHeader
title={t("setup.saas.title", "Sign in to Stirling Cloud")}
onClose={onClose}
/>
<ErrorMessage error={displayError} />
<DesktopOAuthButtons
onOAuthSuccess={onOAuthSuccess}
onError={handleOAuthError}
isDisabled={loading}
serverUrl={serverUrl}
mode="saas"
providers={[{ id: "google" }, { id: "github" }]}
/>
<DividerWithText
text={t("setup.login.orContinueWith", "Or continue with email")}
respondsToDarkMode={false}
opacity={0.4}
/>
<EmailPasswordForm
email={email}
password={password}
setEmail={(value) => {
setEmail(value);
setValidationError(null);
}}
setPassword={(value) => {
setPassword(value);
setValidationError(null);
}}
onSubmit={handleEmailPasswordSubmit}
isSubmitting={loading}
submitButtonText={t("setup.login.submit", "Login")}
/>
<div
className="navigation-link-container"
style={{ marginTop: "0.5rem", textAlign: "right" }}
>
<button
type="button"
onClick={() => {
setValidationError(null);
onSwitchToSignup();
}}
className="navigation-link-button"
disabled={loading}
>
{t("signup.signUp", "Sign Up")}
</button>
</div>
<SelfHostedLink onClick={onSelfHostedClick} disabled={loading} />
{onSkipSignIn && (
<div
className="navigation-link-container"
style={{ marginTop: "0.5rem", textAlign: "center" }}
>
<button
type="button"
onClick={onSkipSignIn}
className="navigation-link-button"
disabled={loading}
>
{t("setup.login.skipSignIn", "Continue without signing in")}
</button>
</div>
)}
</>
);
};