Consolidação do swipe file
This commit is contained in:
parent
323c9aa2b1
commit
37b736ae53
@ -6,7 +6,7 @@ let user_id = null;
|
|||||||
let expires = null;
|
let expires = null;
|
||||||
|
|
||||||
// URL base da API do Bubble no Launchr
|
// URL base da API do Bubble no Launchr
|
||||||
const API_URL = 'https://launchr.com.br/version-test/api/1.1/wf';
|
const API_URL = 'https://launchr.com.br/api/1.1/wf';
|
||||||
|
|
||||||
// Recuperar o token e informações armazenadas ao iniciar a extensão
|
// Recuperar o token e informações armazenadas ao iniciar a extensão
|
||||||
chrome.storage.local.get(['authToken', 'negocios_id', 'negocios_nome', 'user_id', 'expires'], (result) => {
|
chrome.storage.local.get(['authToken', 'negocios_id', 'negocios_nome', 'user_id', 'expires'], (result) => {
|
||||||
@ -21,12 +21,13 @@ chrome.storage.local.get(['authToken', 'negocios_id', 'negocios_nome', 'user_id'
|
|||||||
|
|
||||||
// Função para lidar com erros de autenticação
|
// Função para lidar com erros de autenticação
|
||||||
function handleAuthError() {
|
function handleAuthError() {
|
||||||
// Remover o token e informações armazenadas
|
|
||||||
authToken = null;
|
authToken = null;
|
||||||
chrome.storage.local.remove(['authToken', 'negocios_id', 'negocios_nome', 'user_id', 'expires'], () => {
|
chrome.storage.local.remove(
|
||||||
console.log('Token de autenticação removido.');
|
['authToken', 'negocios_id', 'negocios_nome', 'user_id', 'expires'],
|
||||||
// Opcional: Notificar o usuário sobre a necessidade de login
|
() => {
|
||||||
});
|
console.log('Token removido devido a erro de autenticação');
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listener para mensagens
|
// Listener para mensagens
|
||||||
@ -194,24 +195,64 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (request.action === 'saveSwipeFile') {
|
} else if (request.action === 'saveSwipeFile') {
|
||||||
|
// Verificar se temos um token válido
|
||||||
|
if (!authToken) {
|
||||||
|
sendResponse({
|
||||||
|
success: false,
|
||||||
|
error: 'Usuário não autenticado. Por favor, faça login novamente.'
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
fetch(`${API_URL}/novo_swipe_file`, {
|
fetch(`${API_URL}/novo_swipe_file`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': authToken
|
'Authorization': authToken // Garantir que o token está no formato correto
|
||||||
},
|
},
|
||||||
body: JSON.stringify(request.data)
|
body: JSON.stringify({
|
||||||
|
negocio_id: request.data.negocio_id,
|
||||||
|
conteudo: request.data.conteudo,
|
||||||
|
nome_autor: request.data.nome_autor,
|
||||||
|
link_autor: request.data.link_autor,
|
||||||
|
link_post: request.data.link_post
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!response.ok) throw new Error('Erro na requisição');
|
if (response.status === 401) {
|
||||||
|
// Token expirado ou inválido
|
||||||
|
handleAuthError(); // Função que limpa o token e força novo login
|
||||||
|
throw new Error('Sessão expirada. Por favor, faça login novamente.');
|
||||||
|
}
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Erro na requisição: ' + response.status);
|
||||||
|
}
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
sendResponse({ success: true, data });
|
if (data.response && data.response.swipe_file_id) {
|
||||||
|
chrome.storage.local.set({
|
||||||
|
lastSwipeFileId: data.response.swipe_file_id
|
||||||
|
});
|
||||||
|
sendResponse({
|
||||||
|
success: true,
|
||||||
|
swipeFileId: data.response.swipe_file_id
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error('Resposta inválida da API');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Erro ao salvar swipe file:', error);
|
console.error('Erro ao salvar swipe file:', error);
|
||||||
sendResponse({ success: false, error: error.message });
|
sendResponse({
|
||||||
|
success: false,
|
||||||
|
error: error.message || 'Erro ao salvar o swipe file'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Se for erro de autenticação, redirecionar para login
|
||||||
|
if (error.message.includes('401') || error.message.includes('expirada')) {
|
||||||
|
chrome.runtime.sendMessage({ action: 'showLogin' });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
95
popup.html
95
popup.html
@ -5,6 +5,47 @@
|
|||||||
<title>Launchr</title>
|
<title>Launchr</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
<style>
|
||||||
|
.modal-content {
|
||||||
|
border-radius: 1rem;
|
||||||
|
border: none;
|
||||||
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
border: none;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #4F46E5;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #4338CA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-success {
|
||||||
|
color: #10B981 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-light" style="width: 400px; min-height: 500px;">
|
<body class="bg-light" style="width: 400px; min-height: 500px;">
|
||||||
<!-- Área de Login -->
|
<!-- Área de Login -->
|
||||||
@ -12,14 +53,14 @@
|
|||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<div class="d-flex align-items-center mb-4">
|
<div class="d-flex align-items-center mb-4">
|
||||||
<img src="./images/logo.png" alt="Launchr" height="32" class="me-2">
|
<img src="./images/logo.png" alt="Launchr" height="32" class="me-2">
|
||||||
<small class="text-muted">Version 1.3.6</small>
|
<small class="text-muted">Versão 1.3.6</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="display-6 text-primary mb-4">Let's get started</h1>
|
<h1 class="display-6 text-primary mb-4">Vamos começar</h1>
|
||||||
|
|
||||||
<form id="loginForm">
|
<form id="loginForm">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="email" class="form-label">Email</label>
|
<label for="email" class="form-label">E-mail</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<i class="bi bi-envelope"></i>
|
<i class="bi bi-envelope"></i>
|
||||||
@ -29,7 +70,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="password" class="form-label">Password</label>
|
<label for="password" class="form-label">Senha</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<i class="bi bi-lock"></i>
|
<i class="bi bi-lock"></i>
|
||||||
@ -39,14 +80,14 @@
|
|||||||
<i class="bi bi-eye"></i>
|
<i class="bi bi-eye"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" class="text-decoration-none small d-block mt-2">Forgot password?</a>
|
<a href="#" class="text-decoration-none small d-block mt-2">Esqueceu sua senha?</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary w-100 py-2 mt-3">LOGIN</button>
|
<button type="submit" class="btn btn-primary w-100 py-2 mt-3">ENTRAR</button>
|
||||||
|
|
||||||
<div class="text-center mt-4">
|
<div class="text-center mt-4">
|
||||||
<span class="text-muted">New here? </span>
|
<span class="text-muted">Novo por aqui? </span>
|
||||||
<a href="#" class="text-decoration-none">Create your account</a>
|
<a href="#" class="text-decoration-none">Criar uma conta</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -71,7 +112,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Avatar do usuário com dropdown -->
|
<!-- Avatar do usuário com menu -->
|
||||||
<div class="navbar-nav">
|
<div class="navbar-nav">
|
||||||
<div class="nav-item dropdown">
|
<div class="nav-item dropdown">
|
||||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center"
|
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center"
|
||||||
@ -82,12 +123,10 @@
|
|||||||
<span class="text-white fw-medium">IL</span>
|
<span class="text-white fw-medium">IL</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="dropdown-menu dropdown-menu-end py-2" style="min-width: 200px;" aria-labelledby="userDropdown">
|
<ul class="dropdown-menu dropdown-menu-end py-2" style="min-width: 200px;" aria-labelledby="userDropdown">
|
||||||
<!-- Seleção de Negócio -->
|
<!-- Nome do Negócio -->
|
||||||
<li class="px-3 mb-2">
|
<li class="px-3 mb-2">
|
||||||
<small class="text-muted d-block mb-1">Selecione o Negócio</small>
|
<small class="text-muted d-block mb-1">Negócio</small>
|
||||||
<select id="negociosSelect" class="form-select form-select-sm">
|
<span id="negocioNome" class="d-block text-truncate"></span>
|
||||||
<!-- Opções serão preenchidas via JavaScript -->
|
|
||||||
</select>
|
|
||||||
</li>
|
</li>
|
||||||
<li><hr class="dropdown-divider"></li>
|
<li><hr class="dropdown-divider"></li>
|
||||||
<li><button class="dropdown-item text-danger" id="logoutButton">Sair</button></li>
|
<li><button class="dropdown-item text-danger" id="logoutButton">Sair</button></li>
|
||||||
@ -104,7 +143,13 @@
|
|||||||
<form id="postForm" class="bg-white p-4 rounded shadow-sm">
|
<form id="postForm" class="bg-white p-4 rounded shadow-sm">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="author" class="form-label">Autor</label>
|
<label for="author" class="form-label">Autor</label>
|
||||||
<input type="text" class="form-control" id="author" readonly>
|
<input type="text" class="form-control" id="author">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="postLink" class="form-label">Link do Post</label>
|
||||||
|
<input type="url" class="form-control" id="postLink"
|
||||||
|
placeholder="https://www.linkedin.com/posts_...">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@ -113,7 +158,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" id="saveSwipeFileButton" class="btn btn-primary w-100">
|
<button type="button" id="saveSwipeFileButton" class="btn btn-primary w-100">
|
||||||
Enviar Post
|
Salvar Post
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -139,6 +184,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal de Sucesso -->
|
||||||
|
<div class="modal fade" id="successModal" tabindex="-1" aria-labelledby="successModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body text-center p-4">
|
||||||
|
<div class="mb-4">
|
||||||
|
<i class="bi bi-check-circle-fill text-success" style="font-size: 3rem;"></i>
|
||||||
|
</div>
|
||||||
|
<h5 class="modal-title mb-3" id="successModalLabel">Seu Swipe File foi criado com sucesso</h5>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fechar janela</button>
|
||||||
|
<a href="#" id="viewPostLink" class="btn btn-primary" target="_blank">Visualizar Post</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="lib/bootstrap.bundle.min.js"></script>
|
<script src="lib/bootstrap.bundle.min.js"></script>
|
||||||
<script src="popup.js"></script>
|
<script src="popup.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
68
popup.js
68
popup.js
@ -161,6 +161,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
(response) => {
|
(response) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
showLoggedInSection();
|
showLoggedInSection();
|
||||||
|
updateNegocioDisplay(); // Atualizar nome do negócio
|
||||||
loadPostData();
|
loadPostData();
|
||||||
} else {
|
} else {
|
||||||
alert(response.error || 'Erro ao fazer login');
|
alert(response.error || 'Erro ao fazer login');
|
||||||
@ -172,9 +173,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
// Gerenciar envio do post
|
// Gerenciar envio do post
|
||||||
document.getElementById('saveSwipeFileButton')?.addEventListener('click', async () => {
|
document.getElementById('saveSwipeFileButton')?.addEventListener('click', async () => {
|
||||||
const content = document.getElementById('content').value;
|
const content = document.getElementById('content').value;
|
||||||
|
const author = document.getElementById('author').value;
|
||||||
|
|
||||||
// Buscar ID do negócio do storage
|
// Buscar dados do negócio do storage
|
||||||
chrome.storage.local.get(['negocios_id'], async (result) => {
|
chrome.storage.local.get(['negocios_id', 'negocios_nome'], async (result) => {
|
||||||
if (!result.negocios_id) {
|
if (!result.negocios_id) {
|
||||||
alert('Erro ao identificar o negócio.');
|
alert('Erro ao identificar o negócio.');
|
||||||
return;
|
return;
|
||||||
@ -184,14 +186,24 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const response = await chrome.runtime.sendMessage({
|
const response = await chrome.runtime.sendMessage({
|
||||||
action: 'saveSwipeFile',
|
action: 'saveSwipeFile',
|
||||||
data: {
|
data: {
|
||||||
negocio: result.negocios_id,
|
negocio_id: result.negocios_id,
|
||||||
conteudo: content
|
conteudo: content,
|
||||||
|
nome_autor: author,
|
||||||
|
link_autor: document.getElementById('authorProfileLink')?.value || '',
|
||||||
|
link_post: document.getElementById('postLink')?.value || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
alert('Post salvo com sucesso!');
|
// Construir URL do post
|
||||||
window.close();
|
const postUrl = `https://launchr.com.br/posts/${result.negocios_nome}-${result.negocios_id}?tab=Swipe%20File`;
|
||||||
|
|
||||||
|
// Atualizar link no modal
|
||||||
|
document.getElementById('viewPostLink').href = postUrl;
|
||||||
|
|
||||||
|
// Mostrar modal
|
||||||
|
const successModal = new bootstrap.Modal(document.getElementById('successModal'));
|
||||||
|
successModal.show();
|
||||||
} else {
|
} else {
|
||||||
throw new Error(response.error || 'Erro ao salvar o post');
|
throw new Error(response.error || 'Erro ao salvar o post');
|
||||||
}
|
}
|
||||||
@ -202,6 +214,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fechar popup quando clicar em "Continuar"
|
||||||
|
document.querySelector('#successModal .btn-secondary')?.addEventListener('click', () => {
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
|
||||||
// Gerenciar logout
|
// Gerenciar logout
|
||||||
const logoutButton = document.getElementById('logoutButton');
|
const logoutButton = document.getElementById('logoutButton');
|
||||||
logoutButton?.addEventListener('click', () => {
|
logoutButton?.addEventListener('click', () => {
|
||||||
@ -238,4 +255,43 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
document.getElementById('content').value = result.currentPostData.content || '';
|
document.getElementById('content').value = result.currentPostData.content || '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Atualizar nome do negócio na interface
|
||||||
|
function updateNegocioDisplay() {
|
||||||
|
chrome.storage.local.get(['negocios_nome'], (result) => {
|
||||||
|
const negocioNomeElement = document.getElementById('negocioNome');
|
||||||
|
if (negocioNomeElement && result.negocios_nome) {
|
||||||
|
negocioNomeElement.textContent = result.negocios_nome;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atualizar interface após login bem-sucedido
|
||||||
|
loginForm?.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const email = document.getElementById('email').value;
|
||||||
|
const password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
chrome.runtime.sendMessage(
|
||||||
|
{
|
||||||
|
action: 'login',
|
||||||
|
data: { email, password }
|
||||||
|
},
|
||||||
|
(response) => {
|
||||||
|
if (response.success) {
|
||||||
|
showLoggedInSection();
|
||||||
|
updateNegocioDisplay(); // Atualizar nome do negócio
|
||||||
|
loadPostData();
|
||||||
|
} else {
|
||||||
|
alert(response.error || 'Erro ao fazer login');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Atualizar nome do negócio ao carregar a página
|
||||||
|
if (document.getElementById('loggedInSection').classList.contains('d-none') === false) {
|
||||||
|
updateNegocioDisplay();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Loading…
Reference in New Issue
Block a user