fix: added spinner in login and register page

This commit is contained in:
Anish Sarkar 2026-01-25 16:28:34 +05:30
parent c7c9eb3eb2
commit 86f2e798a9
5 changed files with 24 additions and 19 deletions

View file

@ -12,6 +12,7 @@ import { getAuthErrorDetails, isNetworkError, shouldRetry } from "@/lib/auth-err
import { AUTH_TYPE } from "@/lib/env-config"; import { AUTH_TYPE } from "@/lib/env-config";
import { ValidationError } from "@/lib/error"; import { ValidationError } from "@/lib/error";
import { trackLoginAttempt, trackLoginFailure, trackLoginSuccess } from "@/lib/posthog/events"; import { trackLoginAttempt, trackLoginFailure, trackLoginSuccess } from "@/lib/posthog/events";
import { Spinner } from "@/components/ui/spinner";
export function LocalLoginForm() { export function LocalLoginForm() {
const t = useTranslations("auth"); const t = useTranslations("auth");
@ -42,9 +43,6 @@ export function LocalLoginForm() {
// Track login attempt // Track login attempt
trackLoginAttempt("local"); trackLoginAttempt("local");
// Show loading toast
const loadingToast = toast.loading(tCommon("loading"));
try { try {
const data = await login({ const data = await login({
username, username,
@ -62,8 +60,7 @@ export function LocalLoginForm() {
// Success toast // Success toast
toast.success(t("login_success"), { toast.success(t("login_success"), {
id: loadingToast, description: "Redirecting to dashboard",
description: "Redirecting to dashboard...",
duration: 2000, duration: 2000,
}); });
@ -76,7 +73,6 @@ export function LocalLoginForm() {
trackLoginFailure("local", err.message); trackLoginFailure("local", err.message);
setError({ title: err.name, message: err.message }); setError({ title: err.name, message: err.message });
toast.error(err.name, { toast.error(err.name, {
id: loadingToast,
description: err.message, description: err.message,
duration: 6000, duration: 6000,
}); });
@ -106,7 +102,6 @@ export function LocalLoginForm() {
// Show error toast with conditional retry action // Show error toast with conditional retry action
const toastOptions: any = { const toastOptions: any = {
id: loadingToast,
description: errorDetails.description, description: errorDetails.description,
duration: 6000, duration: 6000,
}; };
@ -244,9 +239,16 @@ export function LocalLoginForm() {
<button <button
type="submit" type="submit"
disabled={isLoggingIn} disabled={isLoggingIn}
className="w-full rounded-md bg-blue-600 px-4 py-1.5 md:py-2 text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 transition-all text-sm md:text-base" className="w-full rounded-md bg-blue-600 px-4 py-1.5 md:py-2 text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 transition-all text-sm md:text-base flex items-center justify-center gap-2"
> >
{isLoggingIn ? tCommon("loading") : t("sign_in")} {isLoggingIn ? (
<>
<Spinner size="sm" className="text-white" />
<span>{t("signing_in")}</span>
</>
) : (
t("sign_in")
)}
</button> </button>
</form> </form>

View file

@ -18,6 +18,7 @@ import {
trackRegistrationSuccess, trackRegistrationSuccess,
} from "@/lib/posthog/events"; } from "@/lib/posthog/events";
import { AmbientBackground } from "../login/AmbientBackground"; import { AmbientBackground } from "../login/AmbientBackground";
import { Spinner } from "@/components/ui/spinner";
export default function RegisterPage() { export default function RegisterPage() {
const t = useTranslations("auth"); const t = useTranslations("auth");
@ -60,9 +61,6 @@ export default function RegisterPage() {
// Track registration attempt // Track registration attempt
trackRegistrationAttempt(); trackRegistrationAttempt();
// Show loading toast
const loadingToast = toast.loading(t("creating_account"));
try { try {
await register({ await register({
email, email,
@ -77,7 +75,6 @@ export default function RegisterPage() {
// Success toast // Success toast
toast.success(t("register_success"), { toast.success(t("register_success"), {
id: loadingToast,
description: t("redirecting_login"), description: t("redirecting_login"),
duration: 2000, duration: 2000,
}); });
@ -95,7 +92,6 @@ export default function RegisterPage() {
trackRegistrationFailure("Registration disabled"); trackRegistrationFailure("Registration disabled");
setError({ title: "Registration is disabled", message: friendlyMessage }); setError({ title: "Registration is disabled", message: friendlyMessage });
toast.error("Registration is disabled", { toast.error("Registration is disabled", {
id: loadingToast,
description: friendlyMessage, description: friendlyMessage,
duration: 6000, duration: 6000,
}); });
@ -109,7 +105,6 @@ export default function RegisterPage() {
trackRegistrationFailure(err.message); trackRegistrationFailure(err.message);
setError({ title: err.name, message: err.message }); setError({ title: err.name, message: err.message });
toast.error(err.name, { toast.error(err.name, {
id: loadingToast,
description: err.message, description: err.message,
duration: 6000, duration: 6000,
}); });
@ -137,7 +132,6 @@ export default function RegisterPage() {
// Show error toast with conditional retry action // Show error toast with conditional retry action
const toastOptions: any = { const toastOptions: any = {
id: loadingToast,
description: errorDetails.description, description: errorDetails.description,
duration: 6000, duration: 6000,
}; };
@ -295,9 +289,16 @@ export default function RegisterPage() {
<button <button
type="submit" type="submit"
disabled={isRegistering} disabled={isRegistering}
className="w-full rounded-md bg-blue-600 px-4 py-1.5 md:py-2 text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 transition-all text-sm md:text-base" className="w-full rounded-md bg-blue-600 px-4 py-1.5 md:py-2 text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 transition-all text-sm md:text-base flex items-center justify-center gap-2"
> >
{isRegistering ? t("creating_account_btn") : t("register")} {isRegistering ? (
<>
<Spinner size="sm" className="text-white" />
<span>{t("creating_account_btn")}</span>
</>
) : (
t("register")
)}
</button> </button>
</form> </form>

View file

@ -184,7 +184,7 @@ function GetStartedButton() {
return ( return (
<motion.div whileHover={{ scale: 1.02, y: -2 }} whileTap={{ scale: 0.98 }}> <motion.div whileHover={{ scale: 1.02, y: -2 }} whileTap={{ scale: 0.98 }}>
<Link <Link
href="/register" href="/login"
className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-black px-6 py-2.5 text-sm font-semibold text-white shadow-lg transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-white dark:text-black" className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-black px-6 py-2.5 text-sm font-semibold text-white shadow-lg transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-white dark:text-black"
> >
Get Started Get Started

View file

@ -46,6 +46,7 @@
"hide_password": "Hide password", "hide_password": "Hide password",
"remember_me": "Remember Me", "remember_me": "Remember Me",
"sign_in": "Sign In", "sign_in": "Sign In",
"signing_in": "Signing in",
"sign_up": "Sign Up", "sign_up": "Sign Up",
"sign_in_with": "Sign in with {provider}", "sign_in_with": "Sign in with {provider}",
"dont_have_account": "Don't have an account?", "dont_have_account": "Don't have an account?",

View file

@ -46,6 +46,7 @@
"hide_password": "隐藏密码", "hide_password": "隐藏密码",
"remember_me": "记住我", "remember_me": "记住我",
"sign_in": "登录", "sign_in": "登录",
"signing_in": "正在登录",
"sign_up": "注册", "sign_up": "注册",
"sign_in_with": "使用 {provider} 登录", "sign_in_with": "使用 {provider} 登录",
"dont_have_account": "还没有账户?", "dont_have_account": "还没有账户?",