mirror of
https://github.com/lukevella/rallly.git
synced 2025-08-06 01:48:32 +02:00
♻️ Clean up login page code (#1525)
This commit is contained in:
parent
fa3f5a9df3
commit
0117464344
5 changed files with 50 additions and 107 deletions
|
@ -1,8 +1,12 @@
|
||||||
"use client";
|
|
||||||
import { Button } from "@rallly/ui/button";
|
import { Button } from "@rallly/ui/button";
|
||||||
import { signIn } from "next-auth/react";
|
import { signIn } from "next-auth/react";
|
||||||
|
import { Trans } from "react-i18next/TransWithoutContext";
|
||||||
|
|
||||||
|
import { getTranslation } from "@/i18n/server";
|
||||||
|
|
||||||
|
export async function LoginWithOIDC({ name }: { name: string }) {
|
||||||
|
const { t } = await getTranslation();
|
||||||
|
|
||||||
export function LoginWithOIDC({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -10,7 +14,13 @@ export function LoginWithOIDC({ children }: { children: React.ReactNode }) {
|
||||||
}}
|
}}
|
||||||
variant="link"
|
variant="link"
|
||||||
>
|
>
|
||||||
{children}
|
<Trans
|
||||||
|
t={t}
|
||||||
|
i18nKey="continueWithProvider"
|
||||||
|
ns="app"
|
||||||
|
defaultValue="Login with {{provider}}"
|
||||||
|
values={{ provider: name }}
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
export function OrDivider({ text }: { text: string }) {
|
import { getTranslation } from "@/i18n/server";
|
||||||
|
|
||||||
|
export async function OrDivider() {
|
||||||
|
const { t } = await getTranslation();
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-x-2.5">
|
<div className="flex items-center gap-x-2.5">
|
||||||
<hr className="grow border-gray-100" />
|
<hr className="grow border-gray-100" />
|
||||||
<div className="text-muted-foreground lowercase">{text}</div>
|
<div className="text-muted-foreground lowercase">{t("or")}</div>
|
||||||
<hr className="grow border-gray-100" />
|
<hr className="grow border-gray-100" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { unstable_cache } from "next/cache";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { getProviders } from "next-auth/react";
|
|
||||||
import { Trans } from "react-i18next/TransWithoutContext";
|
import { Trans } from "react-i18next/TransWithoutContext";
|
||||||
|
|
||||||
|
import { getOAuthProviders } from "@/auth";
|
||||||
import { getTranslation } from "@/i18n/server";
|
import { getTranslation } from "@/i18n/server";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -17,44 +16,20 @@ import { AuthErrors } from "./components/auth-errors";
|
||||||
import { LoginWithEmailForm } from "./components/login-email-form";
|
import { LoginWithEmailForm } from "./components/login-email-form";
|
||||||
import { LoginWithOIDC } from "./components/login-with-oidc";
|
import { LoginWithOIDC } from "./components/login-with-oidc";
|
||||||
import { OrDivider } from "./components/or-divider";
|
import { OrDivider } from "./components/or-divider";
|
||||||
import { SSOProviders } from "./sso-providers";
|
import { SSOProvider } from "./components/sso-provider";
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
export const revalidate = 0;
|
|
||||||
|
|
||||||
async function getOAuthProviders() {
|
|
||||||
const providers = await getProviders();
|
|
||||||
if (!providers) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.values(providers)
|
|
||||||
.filter((provider) => provider.type === "oauth")
|
|
||||||
.map((provider) => ({
|
|
||||||
id: provider.id,
|
|
||||||
name: provider.name,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache the OAuth providers to avoid re-fetching them on every page load
|
|
||||||
const getCachedOAuthProviders = unstable_cache(
|
|
||||||
getOAuthProviders,
|
|
||||||
["oauth-providers"],
|
|
||||||
{
|
|
||||||
revalidate: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export default async function LoginPage() {
|
export default async function LoginPage() {
|
||||||
const { t } = await getTranslation();
|
const { t } = await getTranslation();
|
||||||
const oAuthProviders = await getCachedOAuthProviders();
|
const oAuthProviders = getOAuthProviders();
|
||||||
const socialProviders = oAuthProviders.filter(
|
|
||||||
(provider) => provider.id !== "oidc",
|
const hasAlternateLoginMethods = oAuthProviders.length > 0;
|
||||||
);
|
|
||||||
|
|
||||||
const oidcProvider = oAuthProviders.find(
|
const oidcProvider = oAuthProviders.find(
|
||||||
(provider) => provider.id === "oidc",
|
(provider) => provider.id === "oidc",
|
||||||
);
|
);
|
||||||
|
const socialProviders = oAuthProviders.filter(
|
||||||
|
(provider) => provider.id !== "oidc",
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthPageContainer>
|
<AuthPageContainer>
|
||||||
|
@ -73,25 +48,19 @@ export default async function LoginPage() {
|
||||||
</AuthPageHeader>
|
</AuthPageHeader>
|
||||||
<AuthPageContent>
|
<AuthPageContent>
|
||||||
<LoginWithEmailForm />
|
<LoginWithEmailForm />
|
||||||
{oidcProvider ? (
|
{hasAlternateLoginMethods ? <OrDivider /> : null}
|
||||||
<div className="text-center">
|
{oidcProvider ? <LoginWithOIDC name={oidcProvider.name} /> : null}
|
||||||
<LoginWithOIDC>
|
{socialProviders ? (
|
||||||
<Trans
|
<div className="grid gap-4">
|
||||||
t={t}
|
{socialProviders.map((provider) => (
|
||||||
i18nKey="continueWithProvider"
|
<SSOProvider
|
||||||
ns="app"
|
key={provider.id}
|
||||||
defaultValue="Login with {{provider}}"
|
providerId={provider.id}
|
||||||
values={{ provider: oidcProvider.name }}
|
name={provider.name}
|
||||||
/>
|
/>
|
||||||
</LoginWithOIDC>
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{socialProviders.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<OrDivider text={t("or")} />
|
|
||||||
<SSOProviders />
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</AuthPageContent>
|
</AuthPageContent>
|
||||||
<AuthErrors />
|
<AuthErrors />
|
||||||
<AuthPageExternal>
|
<AuthPageExternal>
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
import { unstable_cache } from "next/cache";
|
|
||||||
import { getProviders } from "next-auth/react";
|
|
||||||
|
|
||||||
import { SSOProvider } from "./components/sso-provider";
|
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
export const revalidate = 0;
|
|
||||||
|
|
||||||
async function getOAuthProviders() {
|
|
||||||
const providers = await getProviders();
|
|
||||||
if (!providers) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.values(providers)
|
|
||||||
.filter((provider) => provider.type === "oauth")
|
|
||||||
.map((provider) => ({
|
|
||||||
id: provider.id,
|
|
||||||
name: provider.name,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache the OAuth providers to avoid re-fetching them on every page load
|
|
||||||
const getCachedOAuthProviders = unstable_cache(
|
|
||||||
getOAuthProviders,
|
|
||||||
["oauth-providers"],
|
|
||||||
{
|
|
||||||
revalidate: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export async function SSOProviders() {
|
|
||||||
const oAuthProviders = await getCachedOAuthProviders();
|
|
||||||
const socialProviders = oAuthProviders.filter(
|
|
||||||
(provider) => provider.id !== "oidc",
|
|
||||||
);
|
|
||||||
|
|
||||||
if (socialProviders.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="grid gap-4">
|
|
||||||
{socialProviders.map((provider) => (
|
|
||||||
<SSOProvider
|
|
||||||
key={provider.id}
|
|
||||||
providerId={provider.id}
|
|
||||||
name={provider.name}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -355,3 +355,17 @@ export const isEmailBlocked = (email: string) => {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getOAuthProviders(): {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[] {
|
||||||
|
return providers
|
||||||
|
.filter((provider) => provider.type === "oauth")
|
||||||
|
.map((provider) => {
|
||||||
|
return {
|
||||||
|
id: provider.id,
|
||||||
|
name: provider.options?.name || provider.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue