Skip to content

Commit 1d92f00

Browse files
committed
Centralize auth redirect path and polish auth shell (workstream A).
1 parent 832da5b commit 1d92f00

5 files changed

Lines changed: 27 additions & 26 deletions

File tree

‎app/(auth)/layout.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ import { OrganizationConfigKey } from "@/lib/schema";
1010
const AUTH_CONFIG_KEYS = [
1111
OrganizationConfigKey.PrimaryColor,
1212
OrganizationConfigKey.SecondaryColor,
13-
OrganizationConfigKey.Tagline,
1413
OrganizationConfigKey.LogoUrl,
1514
] as const;
1615

1716
const AUTH_FOCUS =
18-
"[&_a:focus-visible]:outline-2 [&_a:focus-visible]:outline-offset-2 [&_a:focus-visible]:outline-brand-text [&_button:focus-visible]:outline-2 [&_button:focus-visible]:outline-offset-2 [&_button:focus-visible]:outline-brand-text";
17+
"[&_:is(a,button,input):focus-visible]:outline-2 [&_:is(a,button,input):focus-visible]:outline-offset-2 [&_:is(a,button,input):focus-visible]:outline-brand-text";
1918

2019
/**
2120
* Shared shell for signed-out pages: brand panel, card, and org-not-found gate.

‎app/(auth)/login/page.tsx‎

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,16 @@ import { AuthMessage } from "@/components/auth/authConstants";
1818
import authClient from "@/lib/authClient";
1919
import {
2020
hasErrors,
21-
safeRedirectPath,
2221
validateLogin,
2322
type FieldErrors,
2423
} from "@/lib/authValidation";
25-
import { useRedirectIfSignedIn } from "@/lib/hooks/useRedirectIfSignedIn";
24+
import {
25+
getRedirectPath,
26+
useRedirectIfSignedIn,
27+
} from "@/lib/hooks/useRedirectIfSignedIn";
2628

2729
const WRONG_CREDENTIALS_CODE = "INVALID_EMAIL_OR_PASSWORD";
2830

29-
function getRedirectPath() {
30-
return safeRedirectPath(
31-
new URLSearchParams(window.location.search).get("redirect"),
32-
window.location.origin,
33-
);
34-
}
35-
3631
export default function LoginPage() {
3732
const router = useRouter();
3833
const [email, setEmail] = useState("");
@@ -76,14 +71,13 @@ export default function LoginPage() {
7671
router.push(getRedirectPath());
7772
};
7873

79-
useRedirectIfSignedIn(getRedirectPath);
74+
useRedirectIfSignedIn();
8075

8176
return (
8277
<>
83-
<div className="flex flex-col gap-3 bg-page-bg">
84-
<AuthPageIntro title="Login" />
78+
<AuthPageIntro title="Login">
8579
<AuthOrgTagline />
86-
</div>
80+
</AuthPageIntro>
8781
<form className="flex flex-col gap-6" onSubmit={handleSubmit} noValidate>
8882
<AuthTextField
8983
label="Email"

‎app/(auth)/signup/page.tsx‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import SignupForm from "@/components/auth/SignupForm";
66
import { useRedirectIfSignedIn } from "@/lib/hooks/useRedirectIfSignedIn";
77

88
export default function SignupPage() {
9-
useRedirectIfSignedIn(() => "/");
9+
useRedirectIfSignedIn();
1010

1111
return (
1212
<>
13-
<div className="flex flex-col gap-3 bg-page-bg">
14-
<AuthPageIntro title="Sign Up" />
13+
<AuthPageIntro title="Sign Up">
1514
<AuthOrgTagline />
16-
</div>
15+
</AuthPageIntro>
1716
<SignupForm />
1817
</>
1918
);

‎components/auth/AuthPageIntro.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ import type { ReactNode } from "react";
44
export default function AuthPageIntro({
55
title,
66
description,
7+
children,
78
}: {
89
title: ReactNode;
910
description?: ReactNode;
11+
children?: ReactNode;
1012
}) {
1113
return (
1214
<div className="flex flex-col gap-3 bg-page-bg">
1315
<h1 className="font-display">{title}</h1>
1416
{description && <p className="text-grey-text-weak">{description}</p>}
17+
{children}
1518
</div>
1619
);
1720
}

‎lib/hooks/useRedirectIfSignedIn.ts‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,35 @@
33
import { useEffect } from "react";
44
import { useRouter } from "next/navigation";
55
import authClient from "@/lib/authClient";
6+
import { safeRedirectPath } from "@/lib/authValidation";
67
import { getSlugFromHost } from "@/lib/clientAuthUtils";
78
import { useActiveOrganization } from "@/lib/hooks/useActiveOrganization";
89

10+
export function getRedirectPath() {
11+
return safeRedirectPath(
12+
new URLSearchParams(window.location.search).get("redirect"),
13+
window.location.origin,
14+
);
15+
}
16+
917
/**
1018
* Sends someone already signed in to this host's org away from a signed-out
11-
* page (login, signup). `getPath` runs in the browser when redirecting.
19+
* page (login, signup).
1220
*/
13-
export function useRedirectIfSignedIn(getPath: () => string) {
21+
export function useRedirectIfSignedIn() {
1422
const router = useRouter();
1523
const org = useActiveOrganization();
1624

1725
useEffect(() => {
1826
const checkLoggedIn = async () => {
1927
const session = await authClient.getSession();
20-
if (!session?.data?.user) {
21-
return;
22-
}
28+
if (!session?.data?.user) return;
2329

2430
if (org?.slug === getSlugFromHost(window.location.host)) {
25-
router.replace(getPath());
31+
router.replace(getRedirectPath());
2632
}
2733
};
2834

2935
void checkLoggedIn();
30-
}, [org?.slug, router, getPath]);
36+
}, [org?.slug, router]);
3137
}

0 commit comments

Comments
 (0)