changes to the login and signup, similar to in the saas repo (#6577)

Co-authored-by: Anthony Stirling <[email protected]>
This commit is contained in:
EthanHealy01
2026-06-10 13:49:27 +01:00
committed by GitHub
co-authored by Anthony Stirling
parent 3675db5907
commit f15e405759
12 changed files with 534 additions and 194 deletions
@@ -17,12 +17,11 @@ import { useDocumentMeta } from "@app/hooks/useDocumentMeta";
import AuthLayout from "@app/routes/authShared/AuthLayout";
import { useBackendProbe } from "@app/hooks/useBackendProbe";
import apiClient from "@app/services/apiClient";
import { BASE_PATH } from "@app/constants/app";
import { BASE_PATH, withBasePath } from "@app/constants/app";
import { type OAuthProvider } from "@app/auth/oauthTypes";
import { updateSupportedLanguages } from "@app/i18n";
// Import login components
import LoginHeader from "@app/routes/login/LoginHeader";
import ErrorMessage from "@app/routes/login/ErrorMessage";
import EmailPasswordForm from "@app/routes/login/EmailPasswordForm";
import OAuthButtons, {
@@ -74,7 +73,6 @@ export default function Login() {
const autoLoginErrorRecorded = useRef(false);
const isUserPassAllowed = loginMethod === "all" || loginMethod === "normal";
const isSsoOnlyMode = loginMethod !== "all" && loginMethod !== "normal";
const isSingleSsoOnly = !isUserPassAllowed && enabledProviders.length === 1;
const AUTO_LOGIN_ATTEMPTS_KEY = "stirling_sso_auto_login_attempts";
const AUTO_LOGIN_ERRORS_KEY = "stirling_sso_auto_login_errors";
@@ -461,7 +459,6 @@ export default function Login() {
// If backend isn't ready yet, show a lightweight status screen instead of the form
if (backendProbe.status !== "up" && !loginDisabled) {
const backendTitle = t("backendStartup.notFoundTitle", "Backend not found");
const handleRetry = async () => {
const result = await backendProbe.probe();
if (result.status === "up") {
@@ -471,7 +468,18 @@ export default function Login() {
};
return (
<AuthLayout>
<LoginHeader title={backendTitle} />
<div className="auth-logo-block">
<img
src={withBasePath("/modern-logo/LoginLightModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--light"
/>
<img
src={withBasePath("/modern-logo/LoginDarkModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--dark"
/>
</div>
<div
className="auth-section"
style={{
@@ -555,10 +563,18 @@ export default function Login() {
return (
<AuthLayout>
<LoginHeader
title={isSingleSsoOnly ? "" : t("login.login") || "Sign in"}
centerOnly={isSingleSsoOnly}
/>
<div className="auth-logo-block">
<img
src={withBasePath("/modern-logo/LoginLightModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--light"
/>
<img
src={withBasePath("/modern-logo/LoginDarkModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--dark"
/>
</div>
{/* Success message */}
{successMessage && (
@@ -5,10 +5,9 @@ import { useDocumentMeta } from "@app/hooks/useDocumentMeta";
import { useAuth } from "@app/auth/UseSession";
import AuthLayout from "@app/routes/authShared/AuthLayout";
import "@app/routes/authShared/auth.css";
import { BASE_PATH } from "@app/constants/app";
import { BASE_PATH, withBasePath } from "@app/constants/app";
// Import signup components
import LoginHeader from "@app/routes/login/LoginHeader";
import ErrorMessage from "@app/routes/login/ErrorMessage";
import DividerWithText from "@app/components/shared/DividerWithText";
import SignupForm from "@app/routes/signup/SignupForm";
@@ -92,10 +91,18 @@ export default function Signup() {
return (
<AuthLayout>
<LoginHeader
title={t("signup.title", "Create an account")}
subtitle={t("signup.subtitle", "Join Stirling PDF")}
/>
<div className="auth-logo-block">
<img
src={withBasePath("/modern-logo/LoginLightModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--light"
/>
<img
src={withBasePath("/modern-logo/LoginDarkModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--dark"
/>
</div>
<ErrorMessage error={error} />
@@ -615,3 +615,90 @@
background-color: #af3434 !important;
opacity: 0.6 !important;
}
/* ── Logo block ─────────────────────────────────────────────────────── */
.auth-logo-block {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 2rem;
margin-top: 0.5rem;
animation: authFadeUp 0.4s ease both;
}
.auth-logo-header {
height: 8rem;
width: auto;
}
.auth-logo-header--dark {
display: none;
}
/* ── Page entrance animation ────────────────────────────────────────── */
@keyframes authFadeUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ── Expandable trigger button state ────────────────────────────────── */
.auth-expandable-trigger {
transition:
background-color 180ms ease,
box-shadow 180ms ease,
border-color 180ms ease;
}
.auth-expandable-trigger--active {
border-color: #af3434 !important;
box-shadow: 0 0 0 3px rgba(175, 52, 52, 0.12);
}
/* ── Animated expand/collapse via grid-template-rows ───────────────── */
.auth-expand-grid {
display: grid;
grid-template-rows: 0fr;
transition:
grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 220ms ease;
opacity: 0;
}
.auth-expand-grid--open {
grid-template-rows: 1fr;
opacity: 1;
}
.auth-expand-inner {
overflow: hidden;
min-height: 0;
}
/* ── Icon+label group — keeps icons vertically aligned across buttons ── */
.oauth-btn-group {
display: inline-flex;
align-items: center;
min-width: 12.5rem;
}
.oauth-btn-label {
flex: 1;
text-align: center;
}
/* ── Icon helpers inside oauth-button-fullwidth ─────────────────────── */
.auth-at-icon {
font-size: 1.25rem;
line-height: 1;
margin-right: 0.5rem;
display: inline-block;
width: 1.75rem;
text-align: center;
flex-shrink: 0;
}