feat: Add last used indicator on login page (#3376)

Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
DivyanshuLohani
2024-10-11 11:11:22 +05:30
committed by GitHub
parent fe8c1fbc47
commit f1b9a82192
7 changed files with 63 additions and 10 deletions
@@ -9,6 +9,7 @@ import { useRouter, useSearchParams } from "next/navigation";
import { useEffect, useMemo, useRef, useState } from "react";
import { Controller, FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { cn } from "@formbricks/lib/cn";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
import { Button } from "@formbricks/ui/components/Button";
import { PasswordInput } from "@formbricks/ui/components/PasswordInput";
import { AzureButton } from "@formbricks/ui/components/SignupOptions/components/AzureButton";
@@ -53,7 +54,9 @@ export const SigninForm = ({
const callbackUrl = searchParams?.get("callbackUrl");
const onSubmit: SubmitHandler<TSigninFormState> = async (data) => {
setLoggingIn(true);
if (typeof window !== "undefined") {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, "Email");
}
try {
const signInResponse = await signIn("credentials", {
callbackUrl: callbackUrl ?? "/",
@@ -104,6 +107,13 @@ export const SigninForm = ({
const formRef = useRef<HTMLFormElement>(null);
const error = searchParams?.get("error");
const inviteToken = callbackUrl ? new URL(callbackUrl).searchParams.get("token") : null;
const [lastLoggedInWith, setLastLoginWith] = useState("");
useEffect(() => {
if (typeof window !== "undefined") {
setLastLoginWith(localStorage.getItem(FORMBRICKS_LOGGED_IN_WITH_LS) || "");
}
}, []);
useEffect(() => {
if (error) {
@@ -139,6 +149,7 @@ export const SigninForm = ({
<FormProvider {...formMethods}>
<div className="text-center">
<h1 className="mb-4 text-slate-700">{formLabel}</h1>
<div className="space-y-2">
<form onSubmit={formMethods.handleSubmit(onSubmit)} className="space-y-2">
{TwoFactorComponent}
@@ -209,34 +220,41 @@ export const SigninForm = ({
formRef.current.requestSubmit();
}
}}
className="w-full justify-center"
className="relative w-full justify-center"
loading={loggingIn}>
{totpLogin ? "Submit" : "Login with Email"}
{lastLoggedInWith && lastLoggedInWith === "Email" ? (
<span className="absolute right-3 text-xs">Last Used</span>
) : null}
</Button>
)}
</form>
{googleOAuthEnabled && !totpLogin && (
<>
<GoogleButton inviteUrl={callbackUrl} />
<GoogleButton inviteUrl={callbackUrl} lastUsed={lastLoggedInWith === "Google"} />
</>
)}
{githubOAuthEnabled && !totpLogin && (
<>
<GithubButton inviteUrl={callbackUrl} />
<GithubButton inviteUrl={callbackUrl} lastUsed={lastLoggedInWith === "Github"} />
</>
)}
{azureOAuthEnabled && !totpLogin && (
<>
<AzureButton inviteUrl={callbackUrl} />
<AzureButton inviteUrl={callbackUrl} lastUsed={lastLoggedInWith === "Azure"} />
</>
)}
{oidcOAuthEnabled && !totpLogin && (
<>
<OpenIdButton inviteUrl={callbackUrl} text={`Continue with ${oidcDisplayName}`} />
<OpenIdButton
inviteUrl={callbackUrl}
text={`Continue with ${oidcDisplayName}`}
lastUsed={lastLoggedInWith === "OpenID"}
/>
</>
)}
</div>
+5
View File
@@ -1,10 +1,15 @@
import formbricks from "@formbricks/js";
import { env } from "@formbricks/lib/env";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
export const formbricksEnabled =
typeof env.NEXT_PUBLIC_FORMBRICKS_API_HOST && env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID;
export const formbricksLogout = async () => {
const loggedInWith = localStorage.getItem(FORMBRICKS_LOGGED_IN_WITH_LS);
localStorage.clear();
if (loggedInWith) {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, loggedInWith);
}
return await formbricks.logout();
};
+1
View File
@@ -1,2 +1,3 @@
export const FORMBRICKS_SURVEYS_FILTERS_KEY_LS = "formbricks-surveys-filters";
export const FORMBRICKS_ENVIRONMENT_ID_LS = "formbricks-environment-id";
export const FORMBRICKS_LOGGED_IN_WITH_LS = "formbricks-logged-in-with";
@@ -1,5 +1,6 @@
import { signIn } from "next-auth/react";
import { useCallback, useEffect } from "react";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
import { Button } from "../../Button";
import { MicrosoftIcon } from "../../icons";
@@ -7,12 +8,18 @@ export const AzureButton = ({
text = "Continue with Azure",
inviteUrl,
directRedirect = false,
lastUsed,
}: {
text?: string;
inviteUrl?: string | null;
directRedirect?: boolean;
lastUsed?: boolean;
}) => {
const handleLogin = useCallback(async () => {
if (typeof window !== "undefined") {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, "Azure");
}
await signIn("azure-ad", {
redirect: true,
callbackUrl: inviteUrl ? inviteUrl : "/",
@@ -32,8 +39,9 @@ export const AzureButton = ({
startIconClassName="ml-2"
onClick={handleLogin}
variant="secondary"
className="w-full justify-center">
className="relative w-full justify-center">
{text}
{lastUsed && <span className="absolute right-3 text-xs">Last Used</span>}
</Button>
);
};
@@ -1,17 +1,23 @@
"use client";
import { signIn } from "next-auth/react";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
import { Button } from "../../Button";
import { GithubIcon } from "../../icons";
export const GithubButton = ({
text = "Continue with Github",
inviteUrl,
lastUsed,
}: {
text?: string;
inviteUrl?: string | null;
lastUsed?: boolean;
}) => {
const handleLogin = async () => {
if (typeof window !== "undefined") {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, "Github");
}
await signIn("github", {
redirect: true,
callbackUrl: inviteUrl ? inviteUrl : "/", // redirect after login to /
@@ -25,8 +31,9 @@ export const GithubButton = ({
startIconClassName="ml-2"
onClick={handleLogin}
variant="secondary"
className="w-full justify-center">
className="relative w-full justify-center">
{text}
{lastUsed && <span className="absolute right-3 text-xs">Last Used</span>}
</Button>
);
};
@@ -1,17 +1,23 @@
"use client";
import { signIn } from "next-auth/react";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
import { Button } from "../../Button";
import { GoogleIcon } from "../../icons";
export const GoogleButton = ({
text = "Continue with Google",
inviteUrl,
lastUsed,
}: {
text?: string;
inviteUrl?: string | null;
lastUsed?: boolean;
}) => {
const handleLogin = async () => {
if (typeof window !== "undefined") {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, "Google");
}
await signIn("google", {
redirect: true,
callbackUrl: inviteUrl ? inviteUrl : "/", // redirect after login to /
@@ -25,8 +31,9 @@ export const GoogleButton = ({
startIconClassName="ml-3"
onClick={handleLogin}
variant="secondary"
className="w-full justify-center">
className="relative w-full justify-center">
{text}
{lastUsed && <span className="absolute right-3 text-xs">Last Used</span>}
</Button>
);
};
@@ -1,17 +1,23 @@
import { signIn } from "next-auth/react";
import { useCallback, useEffect } from "react";
import { FORMBRICKS_LOGGED_IN_WITH_LS } from "@formbricks/lib/localStorage";
import { Button } from "../../Button";
export const OpenIdButton = ({
text = "Continue with OpenId Connect",
inviteUrl,
directRedirect = false,
lastUsed,
}: {
text?: string;
inviteUrl?: string | null;
directRedirect?: boolean;
lastUsed?: boolean;
}) => {
const handleLogin = useCallback(async () => {
if (typeof window !== "undefined") {
localStorage.setItem(FORMBRICKS_LOGGED_IN_WITH_LS, "OpenID");
}
await signIn("openid", {
redirect: true,
callbackUrl: inviteUrl ? inviteUrl : "/",
@@ -30,8 +36,9 @@ export const OpenIdButton = ({
startIconClassName="ml-2"
onClick={handleLogin}
variant="secondary"
className="w-full justify-center">
className="relative w-full justify-center">
{text}
{lastUsed && <span className="absolute right-3 text-xs">Last Used</span>}
</Button>
);
};