diff --git a/apps/dashboard/src/app/login/_components/email-form.tsx b/apps/dashboard/src/app/login/_components/email-form.tsx
index a4eb4972..bb4313c6 100644
--- a/apps/dashboard/src/app/login/_components/email-form.tsx
+++ b/apps/dashboard/src/app/login/_components/email-form.tsx
@@ -1,18 +1,41 @@
"use client";
+import { Button } from "@openstatus/ui/components/ui/button";
import { Input } from "@openstatus/ui/components/ui/input";
-import { useActionState } from "react";
+import { Separator } from "@openstatus/ui/components/ui/separator";
+import { useActionState, useEffect, useState } from "react";
import { type EmailFormState, continueWithEmail } from "./actions";
-import { LoginButton } from "./login-button";
+import { LoginButton, STORAGE_KEY } from "./login-button";
const initialState: EmailFormState = {};
-export function EmailForm({ redirectTo }: { redirectTo?: string }) {
+type Mode = "closed" | "sso" | "email";
+
+/**
+ * One form, two doors: "Continue with SSO" sits with the OAuth buttons, the
+ * magic link hides behind a text link so OAuth stays the obvious path. Both
+ * submit the same action, which routes verified SSO domains server-side.
+ * Reopens by itself for returning email/SSO users.
+ */
+export function EmailForm({
+ redirectTo,
+ sso,
+}: {
+ redirectTo?: string;
+ sso: boolean;
+}) {
const [state, formAction, isPending] = useActionState(
continueWithEmail,
initialState,
);
+ const [mode, setMode] = useState("closed");
+
+ useEffect(() => {
+ const last = localStorage.getItem(STORAGE_KEY);
+ if (last === "email") setMode("email");
+ if (last === "sso" && sso) setMode("sso");
+ }, [sso]);
if (state.sent) {
return (
@@ -25,7 +48,7 @@ export function EmailForm({ redirectTo }: { redirectTo?: string }) {
);
}
- return (
+ const form = (
);
+
+ return (
+ <>
+ {sso ? (
+ mode === "sso" ? (
+ form
+ ) : (
+
+ )
+ ) : null}
+
+
+ or
+
+
+ {mode === "email" ? (
+ form
+ ) : (
+
+ )}
+ >
+ );
}
diff --git a/apps/dashboard/src/app/login/_components/login-button.tsx b/apps/dashboard/src/app/login/_components/login-button.tsx
index 327cf1dc..2225549e 100644
--- a/apps/dashboard/src/app/login/_components/login-button.tsx
+++ b/apps/dashboard/src/app/login/_components/login-button.tsx
@@ -5,15 +5,16 @@ import { Button } from "@openstatus/ui/components/ui/button";
import { cn } from "@openstatus/ui/lib/utils";
import { useEffect, useState } from "react";
-const STORAGE_KEY = "openstatus:last-login-provider";
+export const STORAGE_KEY = "openstatus:last-login-provider";
-type Provider = "github" | "google" | "oidc" | "email";
+type Provider = "github" | "google" | "oidc" | "sso" | "email";
export function LoginButton({
provider,
children,
onClick,
className,
+ variant = "secondary",
...props
}: {
provider: Provider;
@@ -27,7 +28,7 @@ export function LoginButton({
return (
) : null}
-
-
-
-
-
-
-
+
+
+
{process.env.AUTH_OIDC_ISSUER ? (
) : null}
+
By clicking continue, you agree to our{" "}