feat: Agente-Marketing initial commit
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}Casa Hunter FL{% endblock %}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #1a3a5c;
|
||||
--accent: #e8a020;
|
||||
--light-bg: #f4f7fb;
|
||||
}
|
||||
body { background: var(--light-bg); font-family: 'Segoe UI', sans-serif; }
|
||||
.navbar { background: var(--primary) !important; }
|
||||
.navbar-brand { color: var(--accent) !important; font-weight: 700; font-size: 1.3rem; }
|
||||
.nav-link { color: rgba(255,255,255,.85) !important; }
|
||||
.nav-link:hover, .nav-link.active { color: var(--accent) !important; }
|
||||
.card { border: none; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,.07); }
|
||||
.score-badge { font-size: .75rem; font-weight: 700; padding: 4px 10px; border-radius: 20px; }
|
||||
.score-high { background: #d4edda; color: #155724; }
|
||||
.score-mid { background: #fff3cd; color: #856404; }
|
||||
.score-low { background: #f8d7da; color: #721c24; }
|
||||
.prop-price { font-size: 1.4rem; font-weight: 700; color: var(--primary); }
|
||||
.source-tag { font-size: .7rem; background: var(--primary); color: #fff; padding: 2px 8px; border-radius: 10px; }
|
||||
.lender-card .match-pct { font-size: 2rem; font-weight: 800; color: var(--accent); }
|
||||
.btn-primary { background: var(--primary); border-color: var(--primary); }
|
||||
.btn-primary:hover { background: #0f2540; }
|
||||
.btn-accent { background: var(--accent); border-color: var(--accent); color: #fff; }
|
||||
.stat-card { text-align: center; padding: 1.2rem; }
|
||||
.stat-card .number { font-size: 2rem; font-weight: 800; color: var(--primary); }
|
||||
.stat-card .label { font-size: .8rem; color: #6c757d; text-transform: uppercase; letter-spacing: 1px; }
|
||||
.action-kit { background: #e8f4fd; border-left: 4px solid var(--primary); border-radius: 8px; padding: 1rem; }
|
||||
footer { background: var(--primary); color: rgba(255,255,255,.6); padding: 1rem 0; margin-top: 3rem; font-size: .85rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/"><i class="fas fa-home me-2"></i>Casa Hunter FL</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#nav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="nav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item"><a class="nav-link {% if request.path=='/' %}active{% endif %}" href="/"><i class="fas fa-chart-line me-1"></i>Dashboard</a></li>
|
||||
<li class="nav-item"><a class="nav-link {% if '/properties' in request.path %}active{% endif %}" href="/properties"><i class="fas fa-building me-1"></i>Propiedades</a></li>
|
||||
<li class="nav-item"><a class="nav-link {% if '/lenders' in request.path %}active{% endif %}" href="/lenders"><i class="fas fa-handshake me-1"></i>Lenders</a></li>
|
||||
<li class="nav-item"><a class="nav-link {% if '/settings' in request.path %}active{% endif %}" href="/settings"><i class="fas fa-sliders-h me-1"></i>Preferencias</a></li>
|
||||
<li class="nav-item ms-2">
|
||||
<button class="btn btn-sm btn-accent" onclick="runScan()"><i class="fas fa-sync me-1"></i>Buscar Ahora</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container my-4">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for cat, msg in messages %}
|
||||
<div class="alert alert-{{ cat }} alert-dismissible fade show"><i class="fas fa-info-circle me-2"></i>{{ msg }}<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer><div class="container text-center">Casa Hunter FL — Tu buscador personal de oportunidades inmobiliarias • Prisa Yachts LLC</div></footer>
|
||||
|
||||
<div class="modal fade" id="scanModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body text-center py-4">
|
||||
<div class="spinner-border text-primary mb-3"></div>
|
||||
<p class="mb-1 fw-bold">Buscando oportunidades...</p>
|
||||
<small class="text-muted">HUD · Fannie Mae · Zillow · Remates</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
let _scanPoll = null;
|
||||
|
||||
function runScan() {
|
||||
const btn = document.querySelector('[onclick="runScan()"]');
|
||||
if (btn) { btn.disabled = true; btn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Buscando...'; }
|
||||
const prog = document.getElementById('scan-progress');
|
||||
const msg = document.getElementById('scan-msg');
|
||||
if (prog) prog.style.display = 'block';
|
||||
if (msg) msg.textContent = 'Abriendo Chrome y buscando propiedades...';
|
||||
|
||||
fetch('/scan', {method:'POST'})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (msg) msg.textContent = data.status === 'already_running'
|
||||
? 'Ya hay un scan en progreso...'
|
||||
: 'Chrome abierto — buscando en ' + (data.cities || []).length + ' ciudades...';
|
||||
_scanPoll = setInterval(pollScanStatus, 5000);
|
||||
})
|
||||
.catch(e => {
|
||||
if (btn) { btn.disabled = false; btn.innerHTML = '<i class="fas fa-search me-2"></i>Buscar Ahora'; }
|
||||
if (msg) msg.textContent = 'Error: ' + e;
|
||||
});
|
||||
}
|
||||
|
||||
function pollScanStatus() {
|
||||
fetch('/scan/status')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
const msg = document.getElementById('scan-msg');
|
||||
const bar = document.getElementById('scan-bar');
|
||||
const btn = document.querySelector('[onclick="runScan()"]');
|
||||
if (msg) msg.textContent = data.progress || 'Buscando...';
|
||||
if (!data.running) {
|
||||
clearInterval(_scanPoll);
|
||||
if (btn) { btn.disabled = false; btn.innerHTML = '<i class="fas fa-search me-2"></i>Buscar Ahora'; }
|
||||
if (bar) bar.classList.remove('progress-bar-animated');
|
||||
if (data.new > 0) {
|
||||
if (msg) msg.textContent = data.new + ' propiedades nuevas! Recargando...';
|
||||
setTimeout(() => location.reload(), 2000);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
const p = document.getElementById('scan-progress');
|
||||
if (p) p.style.display = 'none';
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user