From c5f6b1317eab8209e4cc7d8dd8c1384fad9aa3fb Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Mon, 23 Feb 2026 09:45:26 -0600 Subject: [PATCH] fix(frontend): resolve hydration mismatch and unauthorized api calls --- frontend/src/components/job-card.tsx | 14 ++++++++++++-- frontend/src/lib/i18n.tsx | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/job-card.tsx b/frontend/src/components/job-card.tsx index f3683f7..a4d5c28 100644 --- a/frontend/src/components/job-card.tsx +++ b/frontend/src/components/job-card.tsx @@ -24,6 +24,7 @@ import { useState, useEffect } from "react"; import { useNotify } from "@/contexts/notification-context"; import { useTranslation } from "@/lib/i18n"; import { jobsApi } from "@/lib/api"; +import { useAuth } from "@/contexts/AuthContext"; interface JobCardProps { job: Job; @@ -33,12 +34,17 @@ interface JobCardProps { export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) { const { t } = useTranslation(); + const { user } = useAuth(); const [isFavorited, setIsFavorited] = useState(false); const [isLoading, setIsLoading] = useState(true); const notify = useNotify(); useEffect(() => { const checkFavorite = async () => { + if (!user) { + setIsLoading(false); + return; + } try { const res = await jobsApi.checkFavorite(job.id); setIsFavorited(res.isFavorite); @@ -49,11 +55,15 @@ export function JobCard({ job, isApplied, applicationStatus }: JobCardProps) { } }; checkFavorite(); - }, [job.id]); + }, [job.id, user]); const handleFavorite = async () => { if (isLoading) return; - + if (!user) { + notify.error("Erro", "Faça login para salvar vagas."); + return; + } + try { if (isFavorited) { await jobsApi.removeFavorite(job.id); diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx index 09301f2..8e55e44 100644 --- a/frontend/src/lib/i18n.tsx +++ b/frontend/src/lib/i18n.tsx @@ -63,7 +63,22 @@ function resolveKey(dict: Record, key: string): string | undefi } export function I18nProvider({ children }: { children: ReactNode }) { - const [locale, setLocaleState] = useState(getInitialLocale); + const [locale, setLocaleState] = useState('pt-BR'); + + useEffect(() => { + let initialLocale: Locale = 'pt-BR'; + try { + const storedLocale = localStorage.getItem(localeStorageKey); + if (storedLocale && VALID_LOCALES.includes(storedLocale as Locale)) { + initialLocale = storedLocale as Locale; + } else if (navigator.language) { + initialLocale = normalizeLocale(navigator.language); + } + } catch { + // localStorage might be blocked + } + setLocaleState(initialLocale); + }, []); const setLocale = (newLocale: Locale) => { setLocaleState(newLocale);