fix(frontend): reduce auth noise on login

This commit is contained in:
GoHorse Deploy 2026-03-07 09:45:23 -03:00
parent 949dae0677
commit a9de51ede2
4 changed files with 30 additions and 16 deletions

View file

@ -65,13 +65,9 @@ export default function LoginPage() {
setLoading(true); setLoading(true);
try { try {
// Login sem passar role, o backend decide
console.log('🚀 [LOGIN FRONT] Tentando login com:', data.email);
const user = await login(data.email, data.password); const user = await login(data.email, data.password);
console.log('✅ [LOGIN FRONT] Sucesso:', user);
if (user) { if (user) {
// Se "lembrar de mim" estiver marcado, salvar no localStorage
if (data.rememberMe) { if (data.rememberMe) {
localStorage.setItem("rememberedEmail", data.email); localStorage.setItem("rememberedEmail", data.email);
} }
@ -81,9 +77,6 @@ export default function LoginPage() {
setError(t("auth.login.errors.invalidCredentials")); setError(t("auth.login.errors.invalidCredentials"));
} }
} catch (err: any) { } catch (err: any) {
console.error('🔥 [LOGIN FRONT] Erro no login:', err);
console.error('🔥 [LOGIN FRONT] Detalhes:', err.response?.data || err.message);
const errorMessage = err.message; const errorMessage = err.message;
if (errorMessage === "AUTH_INVALID_CREDENTIALS") { if (errorMessage === "AUTH_INVALID_CREDENTIALS") {
setError(t("auth.login.errors.invalidCredentials")); setError(t("auth.login.errors.invalidCredentials"));
@ -103,7 +96,6 @@ export default function LoginPage() {
return ( return (
<div className="min-h-screen flex flex-col lg:flex-row"> <div className="min-h-screen flex flex-col lg:flex-row">
{/* Left Side - Branding */}
<div className="lg:flex-1 bg-gradient-to-br from-primary to-primary/80 p-8 flex flex-col justify-center items-center text-primary-foreground"> <div className="lg:flex-1 bg-gradient-to-br from-primary to-primary/80 p-8 flex flex-col justify-center items-center text-primary-foreground">
<motion.div <motion.div
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
@ -151,7 +143,6 @@ export default function LoginPage() {
</motion.div> </motion.div>
</div> </div>
{/* Right Side - Login Form */}
<div className="lg:flex-1 flex items-center justify-center p-8 bg-background"> <div className="lg:flex-1 flex items-center justify-center p-8 bg-background">
<motion.div <motion.div
initial={{ opacity: 0, x: 20 }} initial={{ opacity: 0, x: 20 }}
@ -186,7 +177,11 @@ export default function LoginPage() {
<UserIcon className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" /> <UserIcon className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input <Input
id="email" id="email"
type="text" type="email"
autoComplete="username"
autoCapitalize="none"
autoCorrect="off"
spellCheck={false}
placeholder={t("auth.login.fields.usernamePlaceholder")} placeholder={t("auth.login.fields.usernamePlaceholder")}
className="pl-10" className="pl-10"
{...register("email")} {...register("email")}
@ -206,6 +201,7 @@ export default function LoginPage() {
<Input <Input
id="password" id="password"
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
autoComplete="current-password"
placeholder={t("auth.login.fields.passwordPlaceholder")} placeholder={t("auth.login.fields.passwordPlaceholder")}
className="pl-10 pr-10" className="pl-10 pr-10"
{...register("password")} {...register("password")}

View file

@ -1,6 +1,7 @@
"use client"; "use client";
import { createContext, useContext, useEffect, useState } from "react"; import { createContext, useContext, useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { refreshSession, User, getCurrentUser } from "@/lib/auth"; import { refreshSession, User, getCurrentUser } from "@/lib/auth";
interface AuthContextType { interface AuthContextType {
@ -18,6 +19,7 @@ const AuthContext = createContext<AuthContextType>({
export function AuthProvider({ children }: { children: React.ReactNode }) { export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null); const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const pathname = usePathname();
const checkSession = async () => { const checkSession = async () => {
try { try {
@ -27,6 +29,16 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
setUser(stored); setUser(stored);
} }
const isAuthPage =
pathname === "/login" ||
pathname === "/register" ||
pathname === "/forgot-password";
if (!stored && isAuthPage) {
setUser(null);
return;
}
// Then verify with backend (httpOnly cookie) // Then verify with backend (httpOnly cookie)
const refreshedUser = await refreshSession(); const refreshedUser = await refreshSession();
if (refreshedUser) { if (refreshedUser) {
@ -46,7 +58,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
useEffect(() => { useEffect(() => {
checkSession(); checkSession();
}, []); }, [pathname]);
return ( return (
<AuthContext.Provider value={{ user, loading, checkSession }}> <AuthContext.Provider value={{ user, loading, checkSession }}>

View file

@ -4,7 +4,7 @@ import React, { createContext, useContext, useState, useCallback, useEffect } fr
import { toast } from "sonner"; import { toast } from "sonner";
import type { Notification } from "@/lib/types"; import type { Notification } from "@/lib/types";
import { notificationsApi } from "@/lib/api"; import { notificationsApi } from "@/lib/api";
import { getCurrentUser } from "@/lib/auth"; import { useAuth } from "@/contexts/AuthContext";
interface NotificationContextType { interface NotificationContextType {
notifications: Notification[]; notifications: Notification[];
@ -28,12 +28,16 @@ export function NotificationProvider({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const [notifications, setNotifications] = useState<Notification[]>([]); const [notifications, setNotifications] = useState<Notification[]>([]);
const { user, loading } = useAuth();
useEffect(() => { useEffect(() => {
const loadNotifications = async () => { const loadNotifications = async () => {
// Only load notifications if user is authenticated if (loading) {
const user = getCurrentUser(); return;
}
if (!user) { if (!user) {
setNotifications([]);
return; return;
} }
@ -53,7 +57,7 @@ export function NotificationProvider({
} }
}; };
loadNotifications(); loadNotifications();
}, []); }, [loading, user]);
const addNotification = useCallback( const addNotification = useCallback(
(notification: Omit<Notification, "id" | "createdAt" | "read">) => { (notification: Omit<Notification, "id" | "createdAt" | "read">) => {

View file

@ -57,7 +57,9 @@ export async function initConfig(): Promise<RuntimeConfig> {
const response = await fetch('/api/config'); const response = await fetch('/api/config');
if (response.ok) { if (response.ok) {
cachedConfig = await response.json(); cachedConfig = await response.json();
console.log('[Config] Loaded runtime config:', cachedConfig); if (process.env.NODE_ENV === "development") {
console.log('[Config] Loaded runtime config:', cachedConfig);
}
} else { } else {
console.warn('[Config] Failed to fetch config, using defaults'); console.warn('[Config] Failed to fetch config, using defaults');
cachedConfig = defaultConfig; cachedConfig = defaultConfig;