feat(ui): enhance footer with NutriScan branding and fix database path
- Redesigned Footer.tsx with comprehensive layout including brand section, navigation links, social media icons, and contact info to improve user engagement and brand visibility - Updated DATABASE_URL in .env to correct Prisma database path for proper configuration and connectivity - Updated dependencies to support new UI components and ensure compatibility with enhanced features
This commit is contained in:
1 parent
8d6cbeb0bb
commit
9a4e4c762e
51 files changed
+7389
-218
No files matched your search
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* Utilitário para detecção de país do usuário
|
||||
* Usa detecção de IP server-side via API Route
|
||||
*/
|
||||
|
||||
interface CountryInfo {
|
||||
code: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
// Cache para evitar múltiplas requisições
|
||||
const CACHE_KEY = "nutriscan_user_country";
|
||||
const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 horas
|
||||
|
||||
/**
|
||||
* Verifica se o cache ainda é válido
|
||||
*/
|
||||
function isCacheValid(): boolean {
|
||||
if (typeof window === "undefined") return false;
|
||||
|
||||
try {
|
||||
const cached = localStorage.getItem(CACHE_KEY);
|
||||
if (!cached) return false;
|
||||
|
||||
const { timestamp } = JSON.parse(cached);
|
||||
return Date.now() - timestamp < CACHE_DURATION;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtém país do cache
|
||||
*/
|
||||
function getCachedCountry(): CountryInfo | null {
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
try {
|
||||
const cached = localStorage.getItem(CACHE_KEY);
|
||||
if (!cached) return null;
|
||||
|
||||
const { data } = JSON.parse(cached);
|
||||
return data;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Salva país no cache
|
||||
*/
|
||||
function saveToCache(country: CountryInfo): void {
|
||||
if (typeof window === "undefined") return;
|
||||
|
||||
try {
|
||||
localStorage.setItem(
|
||||
CACHE_KEY,
|
||||
JSON.stringify({
|
||||
data: country,
|
||||
timestamp: Date.now(),
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn("Erro ao salvar cache:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detecta o país do usuário usando detecção de IP server-side
|
||||
* 1. Verifica cache local primeiro
|
||||
* 2. Chama API Route /api/location que usa ip-api.com
|
||||
* 3. Fallback para Brasil em caso de erro
|
||||
*/
|
||||
export async function detectUserCountry(
|
||||
forceRefresh: boolean = false
|
||||
): Promise<CountryInfo> {
|
||||
// 1. Verificar cache primeiro (a menos que forceRefresh seja true)
|
||||
if (!forceRefresh && isCacheValid()) {
|
||||
const cached = getCachedCountry();
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. Chamar API Route que detecta país por IP
|
||||
const response = await fetch("/api/location");
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API returned ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const countryInfo: CountryInfo = {
|
||||
code: data.countryCode,
|
||||
name: data.country,
|
||||
};
|
||||
|
||||
saveToCache(countryInfo);
|
||||
return countryInfo;
|
||||
} catch (error) {
|
||||
console.warn("Country detection failed:", error);
|
||||
|
||||
// 3. Fallback: Brasil
|
||||
const fallback: CountryInfo = { code: "br", name: "Brazil" };
|
||||
saveToCache(fallback);
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpa o cache de país
|
||||
*/
|
||||
export function clearCountryCache(): void {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.removeItem(CACHE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtém informações do país atual (síncrono)
|
||||
* Retorna null se não houver cache
|
||||
*/
|
||||
export function getCurrentCountry(): CountryInfo | null {
|
||||
if (isCacheValid()) {
|
||||
return getCachedCountry();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica se o usuário está no Brasil
|
||||
*/
|
||||
export function isBrazil(): boolean {
|
||||
const country = getCurrentCountry();
|
||||
return country?.code === "br" || country?.code === "brazil";
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtém o código do país para a API Open Food Facts
|
||||
*/
|
||||
export function getCountryCodeForAPI(): string {
|
||||
const country = getCurrentCountry();
|
||||
return country?.code || "br";
|
||||
}
|
||||
Reference in new issue
Block a user