Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ const config: Config = {
position: 'left',
label: 'Tutorial',
},
{
to: '/servicos', // Novo item - Serviços
label: 'Serviços',
position: 'left'
},
{ to: '/blog', label: 'Blog', position: 'left' },
{
href: 'https://github.com/facebook/docusaurus',
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

175 changes: 175 additions & 0 deletions src/ChatWidget/ChatWidget.tsx
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coloca chatwidget dentro de components não na src

Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React, { useState } from 'react';
import styles from './styles.module.css';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

type ChatOption = 'whatsapp' | 'messenger' | 'internal';

interface ChatWidgetProps {
whatsappNumber?: string;
messengerPageId?: string;
initialMessage?: string;
}

const ChatWidget: React.FC<ChatWidgetProps> = ({
whatsappNumber = '5562996641935', // Substitua pelo número real de WhatsApp
messengerPageId = '123456789', // Substitua pelo ID da página do Facebook
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A gente tem messenger?

initialMessage = 'Olá! Como posso ajudar você hoje?',
}) => {
const [isOpen, setIsOpen] = useState(false);
const [chatOption, setChatOption] = useState<ChatOption | null>(null);
const [message, setMessage] = useState('');
const [chatHistory, setChatHistory] = useState<Array<{text: string; isUser: boolean}>>([
{ text: initialMessage, isUser: false }
]);

const { siteConfig } = useDocusaurusContext();
const siteName = siteConfig.title;

const toggleChat = () => {
setIsOpen(!isOpen);
if (!isOpen) {
setChatOption(null);
}
};

const selectChatOption = (option: ChatOption) => {
setChatOption(option);

if (option === 'whatsapp') {
// Abrir WhatsApp em uma nova aba
window.open(`https://wa.me/${whatsappNumber}?text=Olá! Estou entrando em contato pelo site ${siteName}`, '_blank');
setIsOpen(false);
} else if (option === 'messenger') {
// Abrir Messenger em uma nova aba
window.open(`https://m.me/${messengerPageId}`, '_blank');
setIsOpen(false);
}
// Para a opção 'internal', mantemos o chat aberto e mostramos a interface
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tira esse chat interno e o message

};

const sendMessage = (e: React.FormEvent) => {
e.preventDefault();
if (!message.trim()) return;

// Adicionar mensagem do usuário ao histórico
setChatHistory([...chatHistory, { text: message, isUser: true }]);

// Simular resposta automática após 1 segundo
setTimeout(() => {
setChatHistory(prev => [
...prev,
{
text: `Obrigado por sua mensagem! Um de nossos atendentes entrará em contato em breve.`,
isUser: false
}
]);
}, 1000);

setMessage('');
};

return (
<div className={styles.chatWidgetContainer}>
{isOpen && (
<div className={styles.chatWindow}>
{!chatOption ? (
<div className={styles.chatOptions}>
<h3>Como podemos ajudar?</h3>
<button
className={styles.optionButton}
onClick={() => selectChatOption('whatsapp')}
>
<img
src="/img/whatsapp-icon.png"
alt="WhatsApp"
className={styles.optionIcon}
onError={handleImageError}
/>
WhatsApp
</button>
<button
className={styles.optionButton}
onClick={() => selectChatOption('messenger')}
>
<img
src="/img/messenger-icon.png"
alt="Messenger"
className={styles.optionIcon}
onError={(e) => {
const target = e.target as HTMLImageElement;
target.onerror = null;
target.style.display = 'none';
}}
/>
Messenger
</button>
<button
className={styles.optionButton}
onClick={() => selectChatOption('internal')}
>
<img
src="/img/chat-icon.png"
alt="Chat"
className={styles.optionIcon}
onError={(e) => {
const target = e.target as HTMLImageElement;
target.onerror = null;
target.style.display = 'none';
}}
/>
Chat
</button>
</div>
) : chatOption === 'internal' && (
<div className={styles.internalChat}>
<div className={styles.chatHeader}>
<h3>Chat de Suporte</h3>
<button
className={styles.backButton}
onClick={() => setChatOption(null)}
>
Voltar
</button>
</div>
<div className={styles.chatMessages}>
{chatHistory.map((msg, index) => (
<div
key={index}
className={`${styles.message} ${msg.isUser ? styles.userMessage : styles.botMessage}`}
>
{msg.text}
</div>
))}
</div>
<form onSubmit={sendMessage} className={styles.chatInputForm}>
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Digite sua mensagem..."
className={styles.chatInput}
/>
<button type="submit" className={styles.sendButton}>
Enviar
</button>
</form>
</div>
)}
</div>
)}
<button
className={styles.chatToggleButton}
onClick={toggleChat}
aria-label="Abrir chat de suporte"
>
{isOpen ? (
<span className={styles.closeIcon}>×</span>
) : (
<span className={styles.chatIcon}>💬</span>
)}
</button>
</div>
);
};

export default ChatWidget;
1 change: 1 addition & 0 deletions src/ChatWidget/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ChatWidget';
186 changes: 186 additions & 0 deletions src/ChatWidget/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/* Contêiner principal do widget de chat */
.chatWidgetContainer {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

/* Botão de alternância do chat */
.chatToggleButton {
width: 60px;
height: 60px;
border-radius: 50%;
background-color: #4a86e8;
color: white;
border: none;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
cursor: pointer;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}

.chatToggleButton:hover {
transform: scale(1.1);
background-color: #3b78e7;
}

.chatIcon {
font-size: 28px;
}

.closeIcon {
font-size: 36px;
}

/* Janela de chat principal */
.chatWindow {
position: absolute;
bottom: 80px;
right: 0;
width: 320px;
max-height: 450px;
background-color: white;
border-radius: 10px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
overflow: hidden;
display: flex;
flex-direction: column;
}

/* Opções de chat */
.chatOptions {
padding: 16px;
}

.chatOptions h3 {
margin-top: 0;
margin-bottom: 16px;
text-align: center;
color: #333;
}

.optionButton {
display: flex;
align-items: center;
width: 100%;
padding: 12px 16px;
margin-bottom: 10px;
border: 1px solid #e0e0e0;
border-radius: 8px;
background-color: #f8f8f8;
cursor: pointer;
font-size: 16px;
transition: all 0.2s ease;
}

.optionButton:hover {
background-color: #f0f0f0;
border-color: #d0d0d0;
}

.optionIcon {
width: 24px;
height: 24px;
margin-right: 10px;
}

/* Chat interno */
.internalChat {
display: flex;
flex-direction: column;
height: 100%;
max-height: 450px;
}

.chatHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background-color: #4a86e8;
color: white;
}

.chatHeader h3 {
margin: 0;
font-size: 16px;
}

.backButton {
background: none;
border: none;
color: white;
cursor: pointer;
font-size: 14px;
text-decoration: underline;
padding: 0;
}

.chatMessages {
flex: 1;
padding: 16px;
overflow-y: auto;
max-height: 300px;
}

.message {
margin-bottom: 12px;
padding: 8px 12px;
border-radius: 8px;
max-width: 80%;
word-wrap: break-word;
}

.userMessage {
background-color: #e3f2fd;
margin-left: auto;
text-align: right;
}

.botMessage {
background-color: #f1f1f1;
}

.chatInputForm {
display: flex;
padding: 12px;
border-top: 1px solid #e0e0e0;
}

.chatInput {
flex: 1;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
font-size: 14px;
}

.sendButton {
background-color: #4a86e8;
color: white;
border: none;
border-radius: 20px;
padding: 8px 16px;
margin-left: 8px;
cursor: pointer;
font-size: 14px;
}

.sendButton:hover {
background-color: #3b78e7;
}

/* Responsividade para dispositivos móveis */
@media (max-width: 480px) {
.chatWindow {
width: 300px;
max-width: calc(100vw - 40px);
right: 0;
}
}
Loading