From b493f1d4d9913cc8f690a631b620b05f9502ecbd Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 29 Nov 2025 16:18:24 -0300 Subject: [PATCH] refactor: Remove contact page from admin, redirect to settings tab --- frontend/src/app/admin/configuracoes/page.tsx | 5 +- .../src/app/admin/paginas/contato/page.tsx | 716 ------------------ frontend/src/app/admin/paginas/page.tsx | 32 +- 3 files changed, 29 insertions(+), 724 deletions(-) delete mode 100644 frontend/src/app/admin/paginas/contato/page.tsx diff --git a/frontend/src/app/admin/configuracoes/page.tsx b/frontend/src/app/admin/configuracoes/page.tsx index 1e8f72d..d6edb00 100644 --- a/frontend/src/app/admin/configuracoes/page.tsx +++ b/frontend/src/app/admin/configuracoes/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useEffect } from 'react'; +import { useSearchParams } from 'next/navigation'; import { useToast } from '@/contexts/ToastContext'; import { BackupManager } from '@/components/admin/BackupManager'; @@ -17,7 +18,9 @@ const PRESET_COLORS = [ export default function ConfiguracoesPage() { const { success, error: showError } = useToast(); - const [activeTab, setActiveTab] = useState<'personalizacao' | 'logotipo' | 'contato' | 'backup'>('personalizacao'); + const searchParams = useSearchParams(); + const tabFromUrl = searchParams.get('tab') as 'personalizacao' | 'logotipo' | 'contato' | 'backup' | null; + const [activeTab, setActiveTab] = useState<'personalizacao' | 'logotipo' | 'contato' | 'backup'>(tabFromUrl || 'personalizacao'); const [primaryColor, setPrimaryColor] = useState('#FF6B35'); const [customColor, setCustomColor] = useState('#FF6B35'); const [showPartnerBadge, setShowPartnerBadge] = useState(false); diff --git a/frontend/src/app/admin/paginas/contato/page.tsx b/frontend/src/app/admin/paginas/contato/page.tsx deleted file mode 100644 index d8edadd..0000000 --- a/frontend/src/app/admin/paginas/contato/page.tsx +++ /dev/null @@ -1,716 +0,0 @@ -"use client"; - -import { useState, useEffect } from 'react'; -import Link from 'next/link'; -import { useRouter } from 'next/navigation'; -import { useToast } from '@/contexts/ToastContext'; -import { CharLimitBadge } from '@/components/admin/CharLimitBadge'; - -const AVAILABLE_ICONS = [ - // Pessoas e Equipe - { value: 'ri-team-line', label: 'Equipe', category: 'pessoas' }, - { value: 'ri-user-star-line', label: 'Destaque', category: 'pessoas' }, - { value: 'ri-user-follow-line', label: 'Seguir', category: 'pessoas' }, - { value: 'ri-group-line', label: 'Grupo', category: 'pessoas' }, - - // Segurança - { value: 'ri-shield-check-line', label: 'Segurança', category: 'segurança' }, - { value: 'ri-shield-star-line', label: 'Proteção Premium', category: 'segurança' }, - { value: 'ri-lock-line', label: 'Cadeado', category: 'segurança' }, - { value: 'ri-hard-hat-line', label: 'Capacete', category: 'segurança' }, - - // Serviços - { value: 'ri-service-line', label: 'Atendimento', category: 'serviço' }, - { value: 'ri-customer-service-line', label: 'Suporte', category: 'serviço' }, - { value: 'ri-tools-line', label: 'Ferramentas', category: 'serviço' }, - { value: 'ri-settings-3-line', label: 'Engrenagem', category: 'serviço' }, - - // Transporte - { value: 'ri-car-line', label: 'Veículo', category: 'transporte' }, - { value: 'ri-truck-line', label: 'Caminhão', category: 'transporte' }, - { value: 'ri-bus-line', label: 'Ônibus', category: 'transporte' }, - { value: 'ri-motorbike-line', label: 'Moto', category: 'transporte' }, - - // Documentos - { value: 'ri-file-list-3-line', label: 'Documentos', category: 'documentos' }, - { value: 'ri-file-text-line', label: 'Arquivo', category: 'documentos' }, - { value: 'ri-clipboard-line', label: 'Prancheta', category: 'documentos' }, - { value: 'ri-contract-line', label: 'Contrato', category: 'documentos' }, - - // Conquistas - { value: 'ri-award-line', label: 'Prêmio', category: 'conquista' }, - { value: 'ri-trophy-line', label: 'Troféu', category: 'conquista' }, - { value: 'ri-medal-line', label: 'Medalha', category: 'conquista' }, - { value: 'ri-vip-crown-line', label: 'Coroa', category: 'conquista' }, - - // Inovação - { value: 'ri-lightbulb-line', label: 'Ideia', category: 'inovação' }, - { value: 'ri-flashlight-line', label: 'Lanterna', category: 'inovação' }, - { value: 'ri-rocket-line', label: 'Foguete', category: 'inovação' }, - { value: 'ri-flask-line', label: 'Experimento', category: 'inovação' }, - - // Status - { value: 'ri-checkbox-circle-line', label: 'Confirmado', category: 'status' }, - { value: 'ri-check-double-line', label: 'Verificado', category: 'status' }, - { value: 'ri-star-line', label: 'Estrela', category: 'status' }, - { value: 'ri-thumb-up-line', label: 'Aprovado', category: 'status' }, - - // Dados - { value: 'ri-pie-chart-line', label: 'Gráfico Pizza', category: 'dados' }, - { value: 'ri-bar-chart-line', label: 'Gráfico Barras', category: 'dados' }, - { value: 'ri-line-chart-line', label: 'Gráfico Linha', category: 'dados' }, - { value: 'ri-dashboard-line', label: 'Dashboard', category: 'dados' }, - - // Performance - { value: 'ri-speed-line', label: 'Velocidade', category: 'performance' }, - { value: 'ri-timer-line', label: 'Cronômetro', category: 'performance' }, - { value: 'ri-time-line', label: 'Relógio', category: 'performance' }, - { value: 'ri-pulse-line', label: 'Pulso', category: 'performance' }, - - // Negócios - { value: 'ri-building-line', label: 'Empresa', category: 'negócios' }, - { value: 'ri-briefcase-line', label: 'Maleta', category: 'negócios' }, - { value: 'ri-money-dollar-circle-line', label: 'Dinheiro', category: 'negócios' }, - { value: 'ri-hand-coin-line', label: 'Pagamento', category: 'negócios' }, - - // Cálculo - { value: 'ri-calculator-line', label: 'Calculadora', category: 'cálculo' }, - { value: 'ri-percent-line', label: 'Porcentagem', category: 'cálculo' }, - { value: 'ri-functions', label: 'Funções', category: 'cálculo' }, - - // Comunicação - { value: 'ri-message-3-line', label: 'Mensagem', category: 'comunicação' }, - { value: 'ri-chat-3-line', label: 'Chat', category: 'comunicação' }, - { value: 'ri-phone-line', label: 'Telefone', category: 'comunicação' }, - { value: 'ri-mail-line', label: 'Email', category: 'comunicação' }, - { value: 'ri-whatsapp-line', label: 'WhatsApp', category: 'comunicação' }, - { value: 'ri-mail-send-line', label: 'Enviar Email', category: 'comunicação' }, - - // Localização - { value: 'ri-map-pin-line', label: 'Localização', category: 'local' }, - { value: 'ri-navigation-line', label: 'Navegação', category: 'local' }, - { value: 'ri-roadster-line', label: 'Estrada', category: 'local' }, - { value: 'ri-compass-line', label: 'Bússola', category: 'local' }, -]; - -interface IconSelectorProps { - value: string; - onChange: (icon: string) => void; - label: string; -} - -function IconSelector({ value, onChange, label }: IconSelectorProps) { - const [isOpen, setIsOpen] = useState(false); - const [search, setSearch] = useState(''); - - const filteredIcons = AVAILABLE_ICONS.filter(icon => - icon.label.toLowerCase().includes(search.toLowerCase()) || - icon.category.toLowerCase().includes(search.toLowerCase()) - ); - - return ( -
- - - - {isOpen && ( -
-
-
- - setSearch(e.target.value)} - placeholder="Buscar ícone..." - className="w-full pl-10 pr-4 py-2 bg-gray-50 dark:bg-white/5 border border-gray-200 dark:border-white/10 rounded-lg text-sm focus:outline-none focus:border-primary" - onClick={(e) => e.stopPropagation()} - /> -
-
-
- {filteredIcons.map((icon) => ( - - ))} -
-
- )} -
- ); -} - -const CONTACT_TEXT_LIMITS = { - hero: { pretitle: 32, title: 70, subtitle: 200 }, - info: { - title: 36, - subtitle: 80, - description: 200, - itemTitle: 40, - itemDescription: 160, - link: 120, - linkText: 32, - }, -} as const; - -type LabelWithLimitProps = { - label: string; - value?: string; - limit: number; -}; - -function LabelWithLimit({ label, value, limit }: LabelWithLimitProps) { - return ( -
- {label} - -
- ); -} - -interface ContactInfo { - icon: string; - title: string; - description: string; - link: string; - linkText: string; -} - -interface ContactContent { - hero: { - pretitle: string; - title: string; - subtitle: string; - }; - info: { - title: string; - subtitle: string; - description: string; - items: ContactInfo[]; - }; -} - -export default function EditContactPage() { - const router = useRouter(); - const [loading, setLoading] = useState(false); - const [initialLoading, setInitialLoading] = useState(true); - const [activeTab, setActiveTab] = useState('hero'); - const { success, error: showError } = useToast(); - - const scrollToPreview = (sectionId: string) => { - const element = document.getElementById(`preview-${sectionId}`); - if (element) { - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }; - - const handleTabChange = (tab: string) => { - setActiveTab(tab); - setTimeout(() => scrollToPreview(tab), 100); - }; - - const [formData, setFormData] = useState({ - hero: { - pretitle: 'Fale Conosco', - title: 'Entre em Contato', - subtitle: 'Nossa equipe está pronta para atender você e transformar suas ideias em realidade.' - }, - info: { - title: 'Informações de Contato', - subtitle: 'Estamos à disposição', - description: 'Estamos à disposição para atender sua empresa com a excelência técnica que seu projeto exige.', - items: [ - { - icon: 'ri-whatsapp-line', - title: 'WhatsApp', - description: 'Atendimento rápido e direto', - link: 'https://wa.me/5527999999999', - linkText: '(27) 99999-9999' - }, - { - icon: 'ri-mail-send-line', - title: 'E-mail', - description: 'Envie sua mensagem', - link: 'mailto:contato@octto.com.br', - linkText: 'contato@octto.com.br' - }, - { - icon: 'ri-map-pin-line', - title: 'Endereço', - description: 'Av. Nossa Senhora da Penha, 1234\nSanta Lúcia, Vitória - ES\nCEP: 29056-000', - link: 'https://maps.google.com', - linkText: 'Ver no mapa' - } - ] - } - }); - - useEffect(() => { - fetchPageContent(); - }, []); - - const fetchPageContent = async () => { - try { - const response = await fetch('/api/pages/contact'); - if (response.ok) { - const data = await response.json(); - if (data.content) { - setFormData(prevData => ({ - hero: data.content.hero || prevData.hero, - info: data.content.info || prevData.info - })); - } - } - } catch (err) { - console.log('Nenhum conteúdo salvo ainda, usando padrão'); - } finally { - setInitialLoading(false); - } - }; - - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setLoading(true); - - try { - const response = await fetch('/api/pages/contact', { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content: formData }) - }); - - if (!response.ok) throw new Error('Erro ao salvar'); - - await response.json(); - success('Conteúdo salvo com sucesso!'); - if (typeof window !== 'undefined') { - window.dispatchEvent(new Event('translation:refresh')); - } - } catch (err) { - showError('Erro ao salvar alterações'); - } finally { - setLoading(false); - } - }; - - if (initialLoading) { - return ( -
-
-
- ); - } - - return ( - <> - -
- {/* Formulário de Edição - Coluna Esquerda 30% */} -
-
- -
-

Editar Página Contato

-

- Personalize informações de contato -

-
- - {/* Navigation Tabs */} -
-
- - -
- - -
- - -
-
- -
- - {/* Hero Section */} - {activeTab === 'hero' && ( -
-

- - Banner Principal -

- -
-
- - setFormData({...formData, hero: {...formData.hero, pretitle: e.target.value}})} - maxLength={CONTACT_TEXT_LIMITS.hero.pretitle} - 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" - /> -
- -
- - setFormData({...formData, hero: {...formData.hero, title: e.target.value}})} - maxLength={CONTACT_TEXT_LIMITS.hero.title} - 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" - /> -
- -
- - -
-
-
- )} - - {/* Info Section */} - {activeTab === 'info' && ( -
-

- - Informações de Contato -

- -
-
- - setFormData({...formData, info: {...formData.info, title: e.target.value}})} - maxLength={CONTACT_TEXT_LIMITS.info.title} - 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" - /> -
-
- - setFormData({...formData, info: {...formData.info, subtitle: e.target.value}})} - maxLength={CONTACT_TEXT_LIMITS.info.subtitle} - 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" - /> -
-
- - -
-
- -
- {formData.info.items.map((item, index) => ( -
-
-

Contato {index + 1}

-
-
- { - const newItems = [...formData.info.items]; - newItems[index].icon = icon; - setFormData({...formData, info: {...formData.info, items: newItems}}); - }} - /> -
- - { - const newItems = [...formData.info.items]; - newItems[index].title = e.target.value; - setFormData({...formData, info: {...formData.info, items: newItems}}); - }} - maxLength={CONTACT_TEXT_LIMITS.info.itemTitle} - className="w-full px-4 py-3 bg-white dark:bg-secondary 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" - /> -
-
- - -
-
- - { - const newItems = [...formData.info.items]; - newItems[index].link = e.target.value; - setFormData({...formData, info: {...formData.info, items: newItems}}); - }} - placeholder="https://..." - maxLength={CONTACT_TEXT_LIMITS.info.link} - className="w-full px-4 py-3 bg-white dark:bg-secondary 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" - /> -
-
- - { - const newItems = [...formData.info.items]; - newItems[index].linkText = e.target.value; - setFormData({...formData, info: {...formData.info, items: newItems}}); - }} - maxLength={CONTACT_TEXT_LIMITS.info.linkText} - className="w-full px-4 py-3 bg-white dark:bg-secondary 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" - /> -
-
-
- ))} -
-
- )} - - {/* Actions */} -
- - Cancelar - - -
-
-
- - {/* Preview em Tempo Real - Coluna Direita Grande */} -
-
-
-
-

- - Preview em Tempo Real -

-

Visualização aproximada da página pública

-
- - - Ver Página Real - -
-
- -
- {/* Hero Preview */} - {activeTab === 'hero' && ( -
-
- - {formData.hero.pretitle} -
-

- {formData.hero.title} -

-

- {formData.hero.subtitle} -

-
- )} - - {/* Info Preview */} - {activeTab === 'info' && ( -
-
-

{formData.info.title}

-

{formData.info.subtitle}

-

- {formData.info.description} -

-
- -
- {formData.info.items.map((item, index) => ( -
-
-
- -
-
-

{item.title}

-

{item.description}

- - {item.linkText} - -
-
-
- ))} -
-
- )} -
-
-
- - ); -} diff --git a/frontend/src/app/admin/paginas/page.tsx b/frontend/src/app/admin/paginas/page.tsx index df2121d..ee0ae32 100644 --- a/frontend/src/app/admin/paginas/page.tsx +++ b/frontend/src/app/admin/paginas/page.tsx @@ -29,12 +29,6 @@ export default function PagesList() { desc: 'História da empresa, missão, visão e valores.', icon: 'ri-team-line' }, - { - title: 'Contato', - slug: 'contato', - desc: 'Endereço, telefones, emails e horário de funcionamento.', - icon: 'ri-contacts-book-line' - }, ]; useEffect(() => { @@ -97,13 +91,37 @@ export default function PagesList() { Editar Conteúdo ); })} + + {/* Card especial para Contato - redireciona para Configurações */} +
+
+
+ +
+ + + Configurações + +
+ +

Contato

+

Endereço, telefones, emails e redes sociais.

+ + + + Ir para Configurações + +
);