feat: Add dynamic contact info and social media settings

This commit is contained in:
Erik
2025-11-29 15:52:21 -03:00
parent c06221331e
commit a14e7749b7
4 changed files with 301 additions and 28 deletions

View File

@@ -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
</button>
</div>
{/* Contact Information Settings */}
<div className="bg-white dark:bg-secondary p-8 rounded-2xl border border-gray-200 dark:border-white/10 shadow-sm">
<div className="flex items-start gap-4 mb-6">
<div className="w-12 h-12 bg-linear-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center shadow-lg shadow-blue-500/30">
<i className="ri-contacts-book-2-fill text-2xl text-white"></i>
</div>
<div className="flex-1">
<h2 className="text-xl font-bold text-secondary dark:text-white mb-1">Informações de Contato</h2>
<p className="text-gray-500 dark:text-gray-400 text-sm">
Configure as informações de contato que aparecem no rodapé do site.
</p>
</div>
</div>
<div className="space-y-4">
{/* Address */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-map-pin-line mr-2 text-primary"></i>
Endereço
</label>
<input
type="text"
value={address}
onChange={(e) => 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"
/>
</div>
{/* Phone */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-phone-line mr-2 text-primary"></i>
Telefone
</label>
<input
type="text"
value={phone}
onChange={(e) => 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"
/>
</div>
{/* Email */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-mail-line mr-2 text-primary"></i>
Email
</label>
<input
type="email"
value={email}
onChange={(e) => 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"
/>
</div>
</div>
</div>
{/* Social Media Settings */}
<div className="bg-white dark:bg-secondary p-8 rounded-2xl border border-gray-200 dark:border-white/10 shadow-sm">
<div className="flex items-start gap-4 mb-6">
<div className="w-12 h-12 bg-linear-to-br from-pink-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg shadow-pink-500/30">
<i className="ri-share-circle-fill text-2xl text-white"></i>
</div>
<div className="flex-1">
<h2 className="text-xl font-bold text-secondary dark:text-white mb-1">Redes Sociais</h2>
<p className="text-gray-500 dark:text-gray-400 text-sm">
Configure os links das suas redes sociais. Deixe em branco para ocultar.
</p>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* Instagram */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-instagram-line mr-2 text-pink-500"></i>
Instagram
</label>
<input
type="url"
value={instagram}
onChange={(e) => 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"
/>
</div>
{/* LinkedIn */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-linkedin-fill mr-2 text-blue-600"></i>
LinkedIn
</label>
<input
type="url"
value={linkedin}
onChange={(e) => 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"
/>
</div>
{/* Facebook */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-facebook-fill mr-2 text-blue-500"></i>
Facebook
</label>
<input
type="url"
value={facebook}
onChange={(e) => 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"
/>
</div>
{/* WhatsApp */}
<div>
<label className="block text-sm font-bold text-gray-700 dark:text-gray-300 mb-2">
<i className="ri-whatsapp-line mr-2 text-green-500"></i>
WhatsApp
</label>
<input
type="text"
value={whatsapp}
onChange={(e) => 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"
/>
</div>
</div>
{/* Save All Settings Button */}
<button
onClick={handleSaveSettings}
className="w-full mt-6 px-6 py-3 bg-primary text-white rounded-xl font-bold hover:opacity-90 transition-colors shadow-lg shadow-primary/20 flex items-center justify-center gap-2"
>
<i className="ri-save-line"></i>
Salvar Informações de Contato
</button>
</div>
</div>
)}

View File

@@ -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 })
}
});
}