feat(frontend): improve login error handling and user avatar

- Implemented more specific error messages for the login page, distinguishing between invalid credentials and server errors.
- Updated i18n files with new translations for login error messages.
- Improved the avatar fallback to use the user's email initials if their name is not available.
- Removed frontend-source.tar.gz from tracking.
- Chore: Added debug logs to the seeder-api location loader.
This commit is contained in:
Yamamoto 2026-01-03 18:28:12 -03:00
parent e59e15dd35
commit 08efbe4f2b
8 changed files with 32 additions and 12 deletions

Binary file not shown.

View file

@ -83,7 +83,15 @@ export default function LoginPage() {
} catch (err: any) {
console.error('🔥 [LOGIN FRONT] Erro no login:', err);
console.error('🔥 [LOGIN FRONT] Detalhes:', err.response?.data || err.message);
setError(err.message || t("auth.login.errors.generic"));
const errorMessage = err.message;
if (errorMessage === "AUTH_INVALID_CREDENTIALS") {
setError(t("auth.login.errors.invalidCredentials"));
} else if (errorMessage === "AUTH_SERVER_ERROR") {
setError(t("auth.login.errors.serverError"));
} else {
setError(t("auth.login.errors.generic"));
}
} finally {
setLoading(false);
}

View file

@ -69,7 +69,11 @@ export function DashboardHeader() {
alt={user?.name}
/>
<AvatarFallback className="bg-primary/10 text-primary">
{user?.name ? getInitials(user.name) : "U"}
{user?.name
? getInitials(user.name)
: user?.email
? getInitials(user.email.split('@')[0])
: "U"}
</AvatarFallback>
</Avatar>
</Button>

View file

@ -256,7 +256,8 @@
"password": "Password must be at least 3 characters"
},
"errors": {
"invalidCredentials": "Invalid username or password.",
"invalidCredentials": "Incorrect email or password. Please try again.",
"serverError": "Server error. Please try again later.",
"generic": "Error signing in. Please try again."
}
},

View file

@ -256,7 +256,8 @@
"password": "La contraseña debe tener al menos 3 caracteres"
},
"errors": {
"invalidCredentials": "Usuario o contraseña inválidos.",
"invalidCredentials": "Correo electrónico o contraseña incorrectos. Por favor inténtalo de nuevo.",
"serverError": "Error del servidor. Por favor inténtalo más tarde.",
"generic": "Error al iniciar sesión. Inténtalo de nuevo."
}
},

View file

@ -256,7 +256,8 @@
"password": "Senha deve ter pelo menos 3 caracteres"
},
"errors": {
"invalidCredentials": "Usuário ou senha inválidos.",
"invalidCredentials": "E-mail ou senha incorretos. Por favor, tente novamente.",
"serverError": "Erro no servidor. Por favor, tente mais tarde.",
"generic": "Erro ao fazer login. Tente novamente."
}
},

View file

@ -36,9 +36,9 @@ export async function login(
if (!res.ok) {
if (res.status === 401) {
throw new Error("Credenciais inválidas");
throw new Error("AUTH_INVALID_CREDENTIALS");
}
throw new Error("Erro no servidor");
throw new Error("AUTH_SERVER_ERROR");
}
const data: LoginResponse = await res.json();
@ -199,7 +199,7 @@ export async function registerCandidate(data: RegisterCandidateData): Promise<vo
if (!res.ok) {
const errorData = await res.json().catch(() => ({}));
console.error('[registerCandidate] Error response:', res.status, errorData);
throw new Error(errorData.message || `Erro no registro: ${res.status}`);
throw new Error(errorData.message || `Registration failed: ${res.status}`);
}
const responseData = await res.json().catch(() => ({}));
@ -246,7 +246,7 @@ export async function registerCompany(data: RegisterCompanyData): Promise<void>
if (!res.ok) {
const errorData = await res.json().catch(() => ({}));
console.error('[registerCompany] Error response:', res.status, errorData);
throw new Error(errorData.message || `Erro no registro: ${res.status}`);
throw new Error(errorData.message || `Registration failed: ${res.status}`);
}
const responseData = await res.json().catch(() => ({}));

View file

@ -73,8 +73,9 @@ function transformSubregionsInsert(stmt) {
// To: [id, name, continent_id, translations, created, updated, flag, wiki_data_id]
if (values.length >= 8) {
const [id, name, translations, region_id, created, updated, flag, wikiDataId] = values;
console.log(`DEBUG: Subregions reorder: id=${id}, region=${region_id}`);
const reordered = [id, name, region_id, translations, created, updated, flag, wikiDataId];
return `INSERT INTO subregions (id, name, continent_id, translations, created_at, updated_at, flag, wiki_data_id) VALUES (${reordered.join(', ')});`;
return `INSERT INTO public.subregions (id, name, continent_id, translations, created_at, updated_at, flag, wiki_data_id) VALUES (${reordered.join(', ')});`;
}
return stmt;
@ -92,7 +93,10 @@ function transformSubregionsInsert(stmt) {
*/
function transformCountriesInsert(stmt) {
const valuesMatch = stmt.match(/VALUES\s*\((.+)\);?$/is);
if (!valuesMatch) return stmt;
if (!valuesMatch) {
console.log('DEBUG: Regex failed for subregions!');
return stmt;
}
const valuesStr = valuesMatch[1];
const values = parseValues(valuesStr);
@ -313,7 +317,8 @@ async function executeSqlFile(filename, tableName) {
}
// Apply special transformations for subregions (column reordering)
if (pgStmt.includes('INSERT INTO subregions')) {
if (pgStmt.includes('INSERT INTO subregions') || pgStmt.includes('INSERT INTO public.subregions')) {
console.log('DEBUG: Transforming subregions insert...');
pgStmt = transformSubregionsInsert(pgStmt);
}