From a14e7749b7dfdc49f08f1c2c0b5a74bd7800f5b0 Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 29 Nov 2025 15:52:21 -0300 Subject: [PATCH] feat: Add dynamic contact info and social media settings --- frontend/prisma/schema.prisma | 9 + frontend/src/app/admin/configuracoes/page.tsx | 181 +++++++++++++++++- frontend/src/app/api/settings/route.ts | 30 ++- frontend/src/components/Footer.tsx | 109 +++++++++-- 4 files changed, 301 insertions(+), 28 deletions(-) diff --git a/frontend/prisma/schema.prisma b/frontend/prisma/schema.prisma index 15dec01..78ed91a 100644 --- a/frontend/prisma/schema.prisma +++ b/frontend/prisma/schema.prisma @@ -93,5 +93,14 @@ model Settings { id String @id @default(cuid()) showPartnerBadge Boolean @default(false) partnerName String @default("Coca-Cola") + // Informações de Contato + address String? // Endereço completo + phone String? // Telefone + email String? // Email + // Redes Sociais + instagram String? // URL Instagram + linkedin String? // URL LinkedIn + facebook String? // URL Facebook + whatsapp String? // Número WhatsApp updatedAt DateTime @updatedAt } diff --git a/frontend/src/app/admin/configuracoes/page.tsx b/frontend/src/app/admin/configuracoes/page.tsx index 0f7c993..175b8c9 100644 --- a/frontend/src/app/admin/configuracoes/page.tsx +++ b/frontend/src/app/admin/configuracoes/page.tsx @@ -22,6 +22,14 @@ export default function ConfiguracoesPage() { const [customColor, setCustomColor] = useState('#FF6B35'); const [showPartnerBadge, setShowPartnerBadge] = useState(false); const [partnerName, setPartnerName] = useState('Coca-Cola'); + // Campos de contato + const [address, setAddress] = useState(''); + const [phone, setPhone] = useState(''); + const [email, setEmail] = useState(''); + const [instagram, setInstagram] = useState(''); + const [linkedin, setLinkedin] = useState(''); + const [facebook, setFacebook] = useState(''); + const [whatsapp, setWhatsapp] = useState(''); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -54,6 +62,13 @@ export default function ConfiguracoesPage() { const data = await response.json(); setShowPartnerBadge(data.showPartnerBadge || false); setPartnerName(data.partnerName || 'Coca-Cola'); + setAddress(data.address || ''); + setPhone(data.phone || ''); + setEmail(data.email || ''); + setInstagram(data.instagram || ''); + setLinkedin(data.linkedin || ''); + setFacebook(data.facebook || ''); + setWhatsapp(data.whatsapp || ''); } } catch (error) { console.error('Erro ao carregar settings:', error); @@ -65,16 +80,26 @@ export default function ConfiguracoesPage() { const response = await fetch('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ showPartnerBadge, partnerName }) + body: JSON.stringify({ + showPartnerBadge, + partnerName, + address: address || null, + phone: phone || null, + email: email || null, + instagram: instagram || null, + linkedin: linkedin || null, + facebook: facebook || null, + whatsapp: whatsapp || null + }) }); if (!response.ok) throw new Error('Erro ao salvar'); - success('Configurações do badge salvas!'); - // Dispatch event para atualizar o PartnerBadge em tempo real + success('Configurações salvas!'); + // Dispatch event para atualizar em tempo real window.dispatchEvent(new Event('settings:refresh')); } catch (error) { - showError('Erro ao salvar configurações do badge'); + showError('Erro ao salvar configurações'); } }; @@ -394,6 +419,154 @@ export default function ConfiguracoesPage() { Salvar Configurações do Badge + + {/* Contact Information Settings */} +
+
+
+ +
+
+

Informações de Contato

+

+ Configure as informações de contato que aparecem no rodapé do site. +

+
+
+ +
+ {/* Address */} +
+ + setAddress(e.target.value)} + placeholder="Ex: Rua das Flores, 123 - Centro, Vitória - ES" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+ + {/* Phone */} +
+ + setPhone(e.target.value)} + placeholder="Ex: (27) 99999-9999" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+ + {/* Email */} +
+ + setEmail(e.target.value)} + placeholder="Ex: contato@empresa.com.br" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+
+
+ + {/* Social Media Settings */} +
+
+
+ +
+
+

Redes Sociais

+

+ Configure os links das suas redes sociais. Deixe em branco para ocultar. +

+
+
+ +
+ {/* Instagram */} +
+ + setInstagram(e.target.value)} + placeholder="https://instagram.com/suaempresa" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+ + {/* LinkedIn */} +
+ + setLinkedin(e.target.value)} + placeholder="https://linkedin.com/company/suaempresa" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+ + {/* Facebook */} +
+ + setFacebook(e.target.value)} + placeholder="https://facebook.com/suaempresa" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+ + {/* WhatsApp */} +
+ + setWhatsapp(e.target.value)} + placeholder="Ex: (27) 99999-9999" + className="w-full px-4 py-3 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-xl text-gray-900 dark:text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all" + /> +
+
+ + {/* Save All Settings Button */} + +
)} diff --git a/frontend/src/app/api/settings/route.ts b/frontend/src/app/api/settings/route.ts index ae3cc19..6836821 100644 --- a/frontend/src/app/api/settings/route.ts +++ b/frontend/src/app/api/settings/route.ts @@ -66,7 +66,17 @@ export async function POST(request: NextRequest) { } const body = await request.json(); - const { showPartnerBadge, partnerName } = body; + const { + showPartnerBadge, + partnerName, + address, + phone, + email, + instagram, + linkedin, + facebook, + whatsapp + } = body; let settings = await prisma.settings.findFirst(); @@ -74,7 +84,14 @@ export async function POST(request: NextRequest) { settings = await prisma.settings.create({ data: { showPartnerBadge: showPartnerBadge ?? false, - partnerName: partnerName ?? 'Coca-Cola' + partnerName: partnerName ?? 'Coca-Cola', + address: address ?? null, + phone: phone ?? null, + email: email ?? null, + instagram: instagram ?? null, + linkedin: linkedin ?? null, + facebook: facebook ?? null, + whatsapp: whatsapp ?? null } }); } else { @@ -82,7 +99,14 @@ export async function POST(request: NextRequest) { where: { id: settings.id }, data: { ...(showPartnerBadge !== undefined && { showPartnerBadge }), - ...(partnerName !== undefined && { partnerName }) + ...(partnerName !== undefined && { partnerName }), + ...(address !== undefined && { address }), + ...(phone !== undefined && { phone }), + ...(email !== undefined && { email }), + ...(instagram !== undefined && { instagram }), + ...(linkedin !== undefined && { linkedin }), + ...(facebook !== undefined && { facebook }), + ...(whatsapp !== undefined && { whatsapp }) } }); } diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index 03b5b61..6022971 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -1,15 +1,56 @@ "use client"; +import { useEffect, useState } from 'react'; import Link from 'next/link'; import { useLocale } from '@/contexts/LocaleContext'; import { PartnerBadge } from './PartnerBadge'; +type ContactSettings = { + address?: string | null; + phone?: string | null; + email?: string | null; + instagram?: string | null; + linkedin?: string | null; + facebook?: string | null; + whatsapp?: string | null; +}; + export default function Footer() { const { locale, t } = useLocale(); + const [contact, setContact] = useState({}); // Prefixo para links const prefix = locale === 'pt' ? '' : `/${locale}`; + useEffect(() => { + const fetchSettings = async () => { + try { + const response = await fetch('/api/settings'); + if (response.ok) { + const data = await response.json(); + setContact({ + address: data.address, + phone: data.phone, + email: data.email, + instagram: data.instagram, + linkedin: data.linkedin, + facebook: data.facebook, + whatsapp: data.whatsapp + }); + } + } catch (error) { + console.error('Erro ao carregar configurações:', error); + } + }; + + fetchSettings(); + + // Atualizar quando settings mudar + const handleRefresh = () => fetchSettings(); + window.addEventListener('settings:refresh', handleRefresh); + return () => window.removeEventListener('settings:refresh', handleRefresh); + }, []); + return (