Spaces:
Running
# HBU Asset Recovery - Complete System Documentation
Browse files**The AI-Powered Asset Recovery Empire**
> **Founder**: David Daniels | **Location**: Edmond, Oklahoma
> **Contact**: david@hbuassetrecovery.us | **Website**: hbuassetrecovery.us
> **Vision**: $8.75M+ Revenue by 2027 | 99% Compliance | 90% Automation
---
## Table of Contents
1. [Executive Summary](#executive-summary)
2. [System Architecture](#system-architecture)
3. [Core Features (70+)](#core-features)
4. [Competitive Advantages](#competitive-advantages)
5. [Technical Implementation](#technical-implementation)
6. [API Integrations](#api-integrations)
7. [Workflows & Automation](#workflows-automation)
8. [Compliance & Ethics](#compliance-ethics)
9. [Revenue Model](#revenue-model)
10. [Deployment Guide](#deployment-guide)
---
## Executive Summary
HBU Asset Recovery is the **#1 AI-native, end-to-end asset recovery platform** that automates the complete pipeline from lead discovery to claim filing to payout. Unlike competitors (Kelmar, UP Standard, HRS Pro, Simple Escheat, UP Navigator) who focus solely on reporting and forms, HBU delivers a **full AI revenue engine**.
### Key Metrics
- **Automation**: 90% end-to-end (vs. 50% manual for competitors)
- **Speed**: 30-day claims (vs. 90+ days industry standard)
- **Compliance**: 99% TCPA/FDCPA/CCPA accuracy (zero lawsuits)
- **Response Rate**: 40% (vs. 15% industry average)
- **Enrichment**: 95% contact hit rate across 12+ skip trace APIs
- **Cost**: $0.10/match bulk enrichment (vs. $0.50+ competitors)
- **Revenue Target**: $8.75M by 2027 (OK+CA+FL+TX expansion)
### The Moat
- **Only platform** with self-healing AI templates (95% unique messages)
- **Only platform** with blockchain bounty system (viral 5x lead generation)
- **Only platform** with full 50-state automation (ARU swarms)
- **Only platform** with Ethics NFT guarantees (70% close rate)
---
## System Architecture
### Pure TypeScript Monorepo
```
Frontend: Next.js 16 (App Router) + React + Tailwind + Shadcn UI
Backend: Next.js API Routes (TypeScript serverless functions)
Database: Prisma + Neon Postgres
Auth: Clerk
AI: OpenAI, Grok, Perplexity (multi-provider fallback)
Monitoring: Sentry + Vercel Analytics
Deployment: Vercel (edge-ready, 99.9% uptime)
Orchestration: n8n / Make.com (external workflows)
```
### Four-Pillar Architecture
1. **Frontend & Core DB**: User dashboard, lead management, auth
2. **Backend Services**: AI routing, scraping, communications, enrichment
3. **Orchestration Layer**: n8n/Make workflows for complex multi-step automation
4. **External Triggers**: Telegram bot, Google Drive, cron jobs, webhooks
---
## Core Features (70+)
### Lead Generation Engine
| Feature | Description | Value |
|---------|-------------|-------|
| **ARU Swarm** | Auto-parallel scraping of OSCN, FLTreasureHunt, SCO, 50-state databases | 5,000+ leads/month, 80% high-value ($10K+) |
| **Quantum Predictor** | Grok-1 AI forecasts 30-day surplus based on equity/liens | 80% accuracy, preemptive targeting |
| **50-State Database Links** | Built-in direct URLs to all state unclaimed property databases | Auto-search via MissingMoney.com integration |
| **County Drone** | Automated scraping for 67 Florida counties + national replication | 90% faster discovery vs. manual |
### Data Enrichment Arsenal
| Provider | Capability | Cost | Priority |
|----------|------------|------|----------|
| **PropStream** | ARV calculator, lead automator, free DNC/litigator scrub, 160M+ properties | $99/mo + $0.10/match | 🔴 High |
| **BatchSkipTracing** | Bulk API (100x/request), 95% accuracy, DNC/compliance flags | $0.10/match | 🔴 High |
| **Skip Genie** | Unlimited searches, property nexus (associated homes), 90% accuracy | $99/mo (Perfectionist) | 🔴 High |
| **Tracerfy** | 97% hit rate, phone/email/relatives | Pay-per-use | 🟡 Medium |
| **Endato** | Real-time enrichment, Oklahoma-focused | API-based | 🔴 High |
| **REsimpli** | CRM sync for real estate workflows | Subscription | 🟡 Medium |
| **Mojo Dialer** | Phone verification + dialer integration | Subscription | 🟡 Medium |
| **Skip Force** | Dual database sources | Pay-per-use | 🟡 Medium |
| **Accurate Append** | Real-time API enrichment | API-based | 🟡 Medium |
| **TPS/FPS Scrapers** | Fallback manual scraping (TruePeopleSearch, FastPeopleSearch) | Free | 🟢 Low |
**Cascade System**: 8x fallback chain ensures 99.9% enrichment uptime
### Outreach Sovereignty
| Feature | Description | Impact |
|---------|-------------|--------|
| **Self-Healing Templates** | Grok-1/BERT generates 95% unique messages, adapts on failure | 40% response rate vs. 15% static |
| **Sovereign SMS Engine** | TCPA 2025 compliant: consent timestamps, 8AM-9PM quiet hours, <3/week frequency caps | <1% opt-out rate |
| **Sovereign Email Engine** | CAN-SPAM compliant: 30-day unsubscribe, physical address, <1/week frequency | 100% deliverability |
| **Bland AI Integration** | AI-powered cold calling with dynamic scripts | 70% connect rate |
| **Multi-Channel Sequencing** | SMS → Email → Call automation based on response | 2x conversion vs. single-channel |
### Compliance Bastion
| Component | Purpose | Assurance |
|-----------|---------|-----------|
| **AI Legal Engine** | 99% TCPA/FDCPA/CCPA compliance scanning | Zero lawsuits to date |
| **Ethics Shield** | Blocks grief exploitation, vulnerable populations | 70% close rate on scanned leads |
| **Quarterly DNC Scrubs** | DoNotCall.gov API integration ($0.005/number) | Hands-free compliance |
| **Litigator Flags** | Auto-detection via PropStream/BatchSkip | Prevents high-risk contacts |
| **Audit Logs** | Full Sentry + Supabase logging for regulatory review | TCPA audit-ready |
### Filing Dominion
- **Paperwork Bot**: 50-state form generation (FL §45.032, CA unclaimed property, OK 12A O.S.)
- **Auto-Filer**: DocuSign integration + email submission to county clerks
- **Status Tracker**: Real-time claim status monitoring via ARU drones
- **Result**: 90% faster filing (30 days vs. 90+), 98% success rate
### Revenue Singularity
- **HBU Bounty Chain**: Polygon blockchain with $50-$500/lead bounties
- **NFT Badges**: On-chain proof of ethics compliance (shareable for viral trust)
- **National ARU Replication**: Auto-scale to 20 states by 2027
- **Viral Effect**: 5x lead generation through affiliate bounty system
### Knowledge & Tools
- **Supabase Knowledge Base**: Grok-1 Q&A on 50-state statutes, instant answers
- **Company Docs Repository**: GitHub-hosted ethics playbooks, Mermaid workflow diagrams, compliance checklists
- **AI Paralegal 24/7**: Instant statute lookups (e.g., "What's FL foreclosure surplus deadline?")
- **Empire Dashboard**: Real-time ARU map, $8.75M revenue run rate projection, Recovery Score (92/100)
---
## Competitive Advantages
### HBU vs. The Competition
| Feature | HBU | Kelmar | UP Standard | HRS Pro | Simple Escheat | UP Navigator |
|---------|-----|--------|-------------|---------|----------------|--------------|
| **AI Automation** | 90% end-to-end | 0% (manual) | 0% (manual) | 0% (forms only) | 0% (DIY scanning) | 50% (workflows) |
| **Skip Tracing** | 12+ APIs, 8x cascade | None | Manual imports | None | None | Basic |
| **Compliance Engine** | 99% AI scans | Manual audits | Manual audits | Templates only | None | Basic |
| **Outreach** | Self-healing (95% unique) | None | Static templates | None | None | Static |
| **Filing Automation** | 50-state auto-file | Forms only | Forms only | NAUPA forms | None | Forms only |
| **Bounty System** | Blockchain + NFT | None | None | None | None | None |
| **Cost** | $0.10/match, 25% contingency | $1K+/year upfront | $500-$2K/year | $450/year | $300-$1K/year | $600+/year |
| **Speed** | 30-day claims | 90+ days | 90+ days | N/A (forms only) | 90+ days | 60+ days |
| **Revenue Potential** | $8.75M by 2027 | Reporting fee only | Reporting fee only | Form fee only | Low volume | Moderate |
### Why HBU Wins
1. **Full Pipeline Automation**: Only platform covering predict → enrich → outreach → file → payout
2. **AI-Native**: Self-healing templates, quantum predictor, ethics shield—no manual intervention
3. **Bulk-Ready**: Handle 10K+ leads/day with 99.9% uptime via cascade fallbacks
4. **Compliance Fortress**: Zero lawsuits, quarterly scrubs, NFT guarantees = 70% trust lift
5. **Viral Growth**: Bounty chain generates 5x leads through on-chain transparency
6. **No Upfront Risk**: 25% contingency only (competitors charge $300-$2K/year upfront)
---
## Technical Implementation
### Project Structure
```typescript
recovery-forge/
├── app/
│ ├── (app)/
│ │ ├── page.tsx // Main dashboard
│ │ ├── leads/[id]/page.tsx // Lead detail
│ │ └── chat/page.tsx // AI command center
│ ├── api/
│ │ ├── webhooks/
│ │ │ ├── telegram/route.ts // Telegram bot
│ │ │ ├── bland/route.ts // Call webhook
│ │ │ └── clerk/route.ts // User sync
│ │ └── command/
│ │ ├── ai-route/route.ts // Intent parser
│ │ ├── skiptrace/route.ts // Enrichment
│ │ ├── comms/route.ts // SMS/Email/Call
│ │ ├── delegate/route.ts // Trello/HubSpot
│ │ └── storage/route.ts // Drive/Sheets
│ ├── layout.tsx
│ └── globals.css
├── lib/
│ ├── prisma.ts // Database client
│ ├── ai-router.ts // Multi-provider AI
│ ├── skip-cascade.ts // 8x fallback enrichment
│ ├── compliance.ts // TCPA/DNC engine
│ ├── self-healing.ts // Template adaptation
│ └── errors.ts // Sentry integration
├── prisma/
│ └── schema.prisma // Complete schema
├── components/ui/ // Shadcn components
└── public/
```
### Database Schema (Prisma)
```prisma
model Lead {
id String @id @default (cuid())
- index.html +206 -245
- leads.html +455 -0
- script.js +351 -0
- style.css +311 -17
|
@@ -1,50 +1,28 @@
|
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>HBU Asset Recovery</title>
|
| 7 |
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
<script src="https://unpkg.com/feather-icons"></script>
|
| 10 |
-
<script src="https://cdn.jsdelivr.net/npm/
|
|
|
|
| 11 |
<script>
|
| 12 |
tailwind.config = {
|
| 13 |
darkMode: 'class',
|
| 14 |
theme: {
|
| 15 |
extend: {
|
| 16 |
colors: {
|
| 17 |
-
primary: '#f97316',
|
| 18 |
-
secondary: '#f97316',
|
| 19 |
}
|
| 20 |
}
|
| 21 |
}
|
| 22 |
}
|
| 23 |
</script>
|
| 24 |
-
<style>
|
| 25 |
-
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap');
|
| 26 |
-
body {
|
| 27 |
-
font-family: 'Montserrat', sans-serif;
|
| 28 |
-
background-color: #0f172a;
|
| 29 |
-
color: #e2e8f0;
|
| 30 |
-
}
|
| 31 |
-
.hero-bg {
|
| 32 |
-
background: linear-gradient(135deg, rgba(15, 23, 42, 0.9) 0%, rgba(15, 23, 42, 0.7) 100%), url('http://static.photos/abstract/1200x630/42') no-repeat center center;
|
| 33 |
-
background-size: cover;
|
| 34 |
-
}
|
| 35 |
-
.service-card {
|
| 36 |
-
transition: all 0.3s ease;
|
| 37 |
-
border: 1px solid rgba(249, 115, 22, 0.2);
|
| 38 |
-
}
|
| 39 |
-
.service-card:hover {
|
| 40 |
-
transform: translateY(-5px);
|
| 41 |
-
box-shadow: 0 10px 25px -5px rgba(249, 115, 22, 0.25);
|
| 42 |
-
border-color: rgba(249, 115, 22, 0.5);
|
| 43 |
-
}
|
| 44 |
-
.stat-card {
|
| 45 |
-
border: 1px solid rgba(249, 115, 22, 0.3);
|
| 46 |
-
}
|
| 47 |
-
</style>
|
| 48 |
</head>
|
| 49 |
<body class="bg-slate-900 text-slate-100">
|
| 50 |
<!-- Navigation -->
|
|
@@ -59,266 +37,249 @@
|
|
| 59 |
</div>
|
| 60 |
<div class="hidden md:block">
|
| 61 |
<div class="ml-10 flex items-baseline space-x-4">
|
| 62 |
-
<a href="
|
| 63 |
-
<a href="
|
| 64 |
-
<a href="
|
| 65 |
-
<a href="
|
| 66 |
</div>
|
| 67 |
</div>
|
| 68 |
-
<div class="
|
| 69 |
-
<button id="
|
| 70 |
-
<i data-feather="
|
| 71 |
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
</div>
|
| 73 |
</div>
|
| 74 |
</div>
|
| 75 |
</nav>
|
| 76 |
|
| 77 |
-
<!--
|
| 78 |
-
<
|
| 79 |
-
<
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
<
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
<i data-feather="arrow-right" class="ml-2 -mr-1 h-5 w-5"></i>
|
| 91 |
-
</a>
|
| 92 |
-
<a href="#" class="ml-4 inline-flex items-center px-6 py-3 border border-orange-500 text-base font-medium rounded-md text-orange-500 bg-transparent hover:bg-slate-800">
|
| 93 |
-
Learn More
|
| 94 |
-
</a>
|
| 95 |
</div>
|
| 96 |
</div>
|
| 97 |
-
</div>
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
</div>
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
</div>
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
</div>
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
</div>
|
| 119 |
</div>
|
| 120 |
</div>
|
| 121 |
-
</div>
|
| 122 |
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
<div class="
|
| 127 |
-
<
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
-
|
| 135 |
-
<div class="
|
| 136 |
-
<
|
| 137 |
-
<div class="
|
| 138 |
-
<div class="flex items-center justify-
|
| 139 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
</div>
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
<
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
</div>
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
</div>
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
<
|
| 157 |
-
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
</div>
|
| 160 |
</div>
|
|
|
|
|
|
|
| 161 |
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
<
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
</div>
|
|
|
|
| 174 |
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
| 179 |
</div>
|
| 180 |
-
<div class="
|
| 181 |
-
<
|
| 182 |
-
<
|
| 183 |
-
Legal asset recovery services with experienced attorneys and legal professionals.
|
| 184 |
-
</p>
|
| 185 |
</div>
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
<div class="service-card bg-slate-800 rounded-lg p-6">
|
| 190 |
-
<div class="flex items-center justify-center h-12 w-12 rounded-md bg-orange-500 text-white">
|
| 191 |
-
<i data-feather="globe" class="h-6 w-6"></i>
|
| 192 |
</div>
|
| 193 |
-
<div class="
|
| 194 |
-
<
|
| 195 |
-
<
|
| 196 |
-
Cross-border asset recovery with global network and international expertise.
|
| 197 |
-
</p>
|
| 198 |
</div>
|
| 199 |
</div>
|
|
|
|
| 200 |
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
<
|
| 206 |
-
|
| 207 |
-
<
|
| 208 |
-
<p class="
|
| 209 |
-
Specialized recovery of assets lost to fraud, embezzlement, and financial crimes.
|
| 210 |
-
</p>
|
| 211 |
</div>
|
| 212 |
</div>
|
| 213 |
</div>
|
| 214 |
</div>
|
| 215 |
</div>
|
| 216 |
-
</
|
| 217 |
|
| 218 |
-
<!--
|
| 219 |
-
<div class="bg-
|
| 220 |
-
<div class="
|
| 221 |
-
<
|
| 222 |
-
<
|
| 223 |
-
<
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
<div class="inline-flex rounded-md shadow">
|
| 227 |
-
<a href="#" class="inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-slate-900 bg-orange-500 hover:bg-orange-600">
|
| 228 |
-
Get Started
|
| 229 |
-
</a>
|
| 230 |
-
</div>
|
| 231 |
-
<div class="ml-3 inline-flex rounded-md shadow">
|
| 232 |
-
<a href="#" class="inline-flex items-center justify-center px-5 py-3 border border-orange-500 text-base font-medium rounded-md text-orange-500 bg-transparent hover:bg-slate-800">
|
| 233 |
-
Learn more
|
| 234 |
-
</a>
|
| 235 |
-
</div>
|
| 236 |
</div>
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
<div class="flex items-center">
|
| 246 |
-
<i data-feather="shield" class="text-orange-500 mr-2"></i>
|
| 247 |
-
<span class="font-bold text-xl text-orange-500">HBU Asset Recovery</span>
|
| 248 |
-
</div>
|
| 249 |
-
<p class="text-slate-400 text-base">
|
| 250 |
-
Professional asset recovery services with proven results and maximum return on investment.
|
| 251 |
-
</p>
|
| 252 |
-
<div class="flex space-x-6">
|
| 253 |
-
<a href="#" class="text-slate-400 hover:text-orange-500">
|
| 254 |
-
<i data-feather="facebook" class="h-6 w-6"></i>
|
| 255 |
-
</a>
|
| 256 |
-
<a href="#" class="text-slate-400 hover:text-orange-500">
|
| 257 |
-
<i data-feather="twitter" class="h-6 w-6"></i>
|
| 258 |
-
</a>
|
| 259 |
-
<a href="#" class="text-slate-400 hover:text-orange-500">
|
| 260 |
-
<i data-feather="linkedin" class="h-6 w-6"></i>
|
| 261 |
-
</a>
|
| 262 |
-
</div>
|
| 263 |
</div>
|
| 264 |
-
<div class="mt-12 grid grid-cols-2 gap-8 xl:mt-0 xl:col-span-2">
|
| 265 |
-
<div class="md:grid md:grid-cols-2 md:gap-8">
|
| 266 |
-
<div>
|
| 267 |
-
<h3 class="text-sm font-semibold text-slate-300 tracking-wider uppercase">Services</h3>
|
| 268 |
-
<ul class="mt-4 space-y-4">
|
| 269 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Financial Recovery</a></li>
|
| 270 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Real Estate Recovery</a></li>
|
| 271 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Commercial Assets</a></li>
|
| 272 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Legal Recovery</a></li>
|
| 273 |
-
</ul>
|
| 274 |
-
</div>
|
| 275 |
-
<div class="mt-12 md:mt-0">
|
| 276 |
-
<h3 class="text-sm font-semibold text-slate-300 tracking-wider uppercase">Support</h3>
|
| 277 |
-
<ul class="mt-4 space-y-4">
|
| 278 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Pricing</a></li>
|
| 279 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Documentation</a></li>
|
| 280 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Guides</a></li>
|
| 281 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">API Status</a></li>
|
| 282 |
-
</ul>
|
| 283 |
-
</div>
|
| 284 |
-
</div>
|
| 285 |
-
<div class="md:grid md:grid-cols-2 md:gap-8">
|
| 286 |
-
<div>
|
| 287 |
-
<h3 class="text-sm font-semibold text-slate-300 tracking-wider uppercase">Company</h3>
|
| 288 |
-
<ul class="mt-4 space-y-4">
|
| 289 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">About</a></li>
|
| 290 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Blog</a></li>
|
| 291 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Jobs</a></li>
|
| 292 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Press</a></li>
|
| 293 |
-
</ul>
|
| 294 |
-
</div>
|
| 295 |
-
<div class="mt-12 md:mt-0">
|
| 296 |
-
<h3 class="text-sm font-semibold text-slate-300 tracking-wider uppercase">Legal</h3>
|
| 297 |
-
<ul class="mt-4 space-y-4">
|
| 298 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Privacy</a></li>
|
| 299 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Terms</a></li>
|
| 300 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Compliance</a></li>
|
| 301 |
-
<li><a href="#" class="text-base text-slate-400 hover:text-orange-500">Licenses</a></li>
|
| 302 |
-
</ul>
|
| 303 |
-
</div>
|
| 304 |
-
</div>
|
| 305 |
-
</div>
|
| 306 |
-
</div>
|
| 307 |
-
<div class="mt-12 border-t border-slate-700 pt-8">
|
| 308 |
-
<p class="text-base text-slate-400 xl:text-center">© 2023 HBU Asset Recovery. All rights reserved.</p>
|
| 309 |
</div>
|
| 310 |
</div>
|
| 311 |
-
</
|
| 312 |
|
| 313 |
-
<script>
|
| 314 |
-
feather.replace();
|
| 315 |
-
|
| 316 |
-
// Mobile menu toggle
|
| 317 |
-
const mobileMenuButton = document.getElementById('mobile-menu-button');
|
| 318 |
-
mobileMenuButton.addEventListener('click', () => {
|
| 319 |
-
const menu = document.querySelector('.mobile-menu');
|
| 320 |
-
menu.classList.toggle('hidden');
|
| 321 |
-
});
|
| 322 |
-
</script>
|
| 323 |
</body>
|
| 324 |
</html>
|
|
|
|
| 1 |
+
|
| 2 |
<!DOCTYPE html>
|
| 3 |
<html lang="en">
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>HBU Asset Recovery Dashboard</title>
|
| 8 |
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 9 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
<script src="https://unpkg.com/feather-icons"></script>
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
| 12 |
+
<link rel="stylesheet" href="style.css">
|
| 13 |
<script>
|
| 14 |
tailwind.config = {
|
| 15 |
darkMode: 'class',
|
| 16 |
theme: {
|
| 17 |
extend: {
|
| 18 |
colors: {
|
| 19 |
+
primary: '#f97316',
|
| 20 |
+
secondary: '#f97316',
|
| 21 |
}
|
| 22 |
}
|
| 23 |
}
|
| 24 |
}
|
| 25 |
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
</head>
|
| 27 |
<body class="bg-slate-900 text-slate-100">
|
| 28 |
<!-- Navigation -->
|
|
|
|
| 37 |
</div>
|
| 38 |
<div class="hidden md:block">
|
| 39 |
<div class="ml-10 flex items-baseline space-x-4">
|
| 40 |
+
<a href="index.html" class="bg-orange-500 text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>
|
| 41 |
+
<a href="leads.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Leads</a>
|
| 42 |
+
<a href="automation.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Automation</a>
|
| 43 |
+
<a href="compliance.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Compliance</a>
|
| 44 |
</div>
|
| 45 |
</div>
|
| 46 |
+
<div class="flex items-center space-x-4">
|
| 47 |
+
<button id="telegram-btn" class="text-slate-400 hover:text-white">
|
| 48 |
+
<i data-feather="send" class="h-5 w-5"></i>
|
| 49 |
</button>
|
| 50 |
+
<button id="notification-btn" class="text-slate-400 hover:text-white relative">
|
| 51 |
+
<i data-feather="bell" class="h-5 w-5"></i>
|
| 52 |
+
<span class="absolute -top-1 -right-1 h-2 w-2 bg-red-500 rounded-full"></span>
|
| 53 |
+
</button>
|
| 54 |
+
<div class="flex items-center">
|
| 55 |
+
<img class="h-8 w-8 rounded-full" src="http://static.photos/people/40x40/42" alt="User">
|
| 56 |
+
</div>
|
| 57 |
</div>
|
| 58 |
</div>
|
| 59 |
</div>
|
| 60 |
</nav>
|
| 61 |
|
| 62 |
+
<!-- Main Content -->
|
| 63 |
+
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
| 64 |
+
<!-- Recovery Score Section -->
|
| 65 |
+
<div class="bg-gradient-to-r from-slate-800 to-slate-900 rounded-xl p-6 mb-8 border border-orange-500/20">
|
| 66 |
+
<div class="flex items-center justify-between">
|
| 67 |
+
<div>
|
| 68 |
+
<h1 class="text-3xl font-bold text-white">Empire Dashboard</h1>
|
| 69 |
+
<p class="text-slate-400 mt-1">Real-time asset recovery metrics and performance</p>
|
| 70 |
+
</div>
|
| 71 |
+
<div class="text-right">
|
| 72 |
+
<div class="text-5xl font-bold text-orange-500">92/100</div>
|
| 73 |
+
<div class="text-sm text-slate-400">Recovery Score</div>
|
| 74 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
</div>
|
| 76 |
</div>
|
|
|
|
| 77 |
|
| 78 |
+
<!-- Revenue Metrics -->
|
| 79 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
|
| 80 |
+
<div class="bg-slate-800 rounded-lg p-6 border border-orange-500/20">
|
| 81 |
+
<div class="flex items-center justify-between">
|
| 82 |
+
<div>
|
| 83 |
+
<p class="text-slate-400 text-sm">Monthly Revenue</p>
|
| 84 |
+
<p class="text-2xl font-bold text-white">$416,667</p>
|
| 85 |
+
<p class="text-green-400 text-sm">↑ 12% from last month</p>
|
| 86 |
+
</div>
|
| 87 |
+
<div class="text-orange-500">
|
| 88 |
+
<i data-feather="dollar-sign" class="h-8 w-8"></i>
|
| 89 |
+
</div>
|
| 90 |
</div>
|
| 91 |
+
</div>
|
| 92 |
+
|
| 93 |
+
<div class="bg-slate-800 rounded-lg p-6 border border-orange-500/20">
|
| 94 |
+
<div class="flex items-center justify-between">
|
| 95 |
+
<div>
|
| 96 |
+
<p class="text-slate-400 text-sm">Active Leads</p>
|
| 97 |
+
<p class="text-2xl font-bold text-white">2,847</p>
|
| 98 |
+
<p class="text-green-400 text-sm">↑ 8% from last week</p>
|
| 99 |
+
</div>
|
| 100 |
+
<div class="text-orange-500">
|
| 101 |
+
<i data-feather="users" class="h-8 w-8"></i>
|
| 102 |
+
</div>
|
| 103 |
</div>
|
| 104 |
+
</div>
|
| 105 |
+
|
| 106 |
+
<div class="bg-slate-800 rounded-lg p-6 border border-orange-500/20">
|
| 107 |
+
<div class="flex items-center justify-between">
|
| 108 |
+
<div>
|
| 109 |
+
<p class="text-slate-400 text-sm">Success Rate</p>
|
| 110 |
+
<p class="text-2xl font-bold text-white">98.2%</p>
|
| 111 |
+
<p class="text-green-400 text-sm">↑ 2.1% improvement</p>
|
| 112 |
+
</div>
|
| 113 |
+
<div class="text-orange-500">
|
| 114 |
+
<i data-feather="trending-up" class="h-8 w-8"></i>
|
| 115 |
+
</div>
|
| 116 |
</div>
|
| 117 |
+
</div>
|
| 118 |
+
|
| 119 |
+
<div class="bg-slate-800 rounded-lg p-6 border border-orange-500/20">
|
| 120 |
+
<div class="flex items-center justify-between">
|
| 121 |
+
<div>
|
| 122 |
+
<p class="text-slate-400 text-sm">ARU Status</p>
|
| 123 |
+
<p class="text-2xl font-bold text-green-400">Active</p>
|
| 124 |
+
<p class="text-slate-400 text-sm">47 states running</p>
|
| 125 |
+
</div>
|
| 126 |
+
<div class="text-green-400">
|
| 127 |
+
<i data-feather="activity" class="h-8 w-8"></i>
|
| 128 |
+
</div>
|
| 129 |
</div>
|
| 130 |
</div>
|
| 131 |
</div>
|
|
|
|
| 132 |
|
| 133 |
+
<!-- Main Dashboard Grid -->
|
| 134 |
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
| 135 |
+
<!-- Lead Pipeline -->
|
| 136 |
+
<div class="lg:col-span-2">
|
| 137 |
+
<div class="bg-slate-800 rounded-lg p-6">
|
| 138 |
+
<div class="flex items-center justify-between mb-4">
|
| 139 |
+
<h2 class="text-xl font-semibold text-white">Lead Pipeline</h2>
|
| 140 |
+
<button class="text-orange-500 hover:text-orange-400">
|
| 141 |
+
<i data-feather="refresh-cw" class="h-5 w-5"></i>
|
| 142 |
+
</button>
|
| 143 |
+
</div>
|
| 144 |
+
<canvas id="pipelineChart" class="w-full h-64"></canvas>
|
| 145 |
+
</div>
|
| 146 |
|
| 147 |
+
<!-- Recent Activity -->
|
| 148 |
+
<div class="bg-slate-800 rounded-lg p-6 mt-6">
|
| 149 |
+
<h2 class="text-xl font-semibold text-white mb-4">Recent Activity</h2>
|
| 150 |
+
<div class="space-y-4">
|
| 151 |
+
<div class="flex items-center justify-between p-3 bg-slate-700 rounded-lg">
|
| 152 |
+
<div class="flex items-center">
|
| 153 |
+
<div class="w-2 h-2 bg-green-400 rounded-full mr-3"></div>
|
| 154 |
+
<div>
|
| 155 |
+
<p class="text-white font-medium">Claim Approved - $45,000</p>
|
| 156 |
+
<p class="text-slate-400 text-sm">John Doe - Oklahoma County</p>
|
| 157 |
+
</div>
|
| 158 |
+
</div>
|
| 159 |
+
<span class="text-slate-400 text-sm">2 min ago</span>
|
| 160 |
</div>
|
| 161 |
+
|
| 162 |
+
<div class="flex items-center justify-between p-3 bg-slate-700 rounded-lg">
|
| 163 |
+
<div class="flex items-center">
|
| 164 |
+
<div class="w-2 h-2 bg-orange-400 rounded-full mr-3"></div>
|
| 165 |
+
<div>
|
| 166 |
+
<p class="text-white font-medium">New High-Value Lead</p>
|
| 167 |
+
<p class="text-slate-400 text-sm">ARV $350K - Equity 78%</p>
|
| 168 |
+
</div>
|
| 169 |
+
</div>
|
| 170 |
+
<span class="text-slate-400 text-sm">15 min ago</span>
|
| 171 |
</div>
|
| 172 |
+
|
| 173 |
+
<div class="flex items-center justify-between p-3 bg-slate-700 rounded-lg">
|
| 174 |
+
<div class="flex items-center">
|
| 175 |
+
<div class="w-2 h-2 bg-blue-400 rounded-full mr-3"></div>
|
| 176 |
+
<div>
|
| 177 |
+
<p class="text-white font-medium">ARU Swarm Completed</p>
|
| 178 |
+
<p class="text-slate-400 text-sm">1,247 leads processed - FL</p>
|
| 179 |
+
</div>
|
| 180 |
+
</div>
|
| 181 |
+
<span class="text-slate-400 text-sm">1 hour ago</span>
|
| 182 |
</div>
|
| 183 |
+
|
| 184 |
+
<div class="flex items-center justify-between p-3 bg-slate-700 rounded-lg">
|
| 185 |
+
<div class="flex items-center">
|
| 186 |
+
<div class="w-2 h-2 bg-purple-400 rounded-full mr-3"></div>
|
| 187 |
+
<div>
|
| 188 |
+
<p class="text-white font-medium">AI Call Campaign Sent</p>
|
| 189 |
+
<p class="text-slate-400 text-sm">234 contacts - 67% answer rate</p>
|
| 190 |
+
</div>
|
| 191 |
+
</div>
|
| 192 |
+
<span class="text-slate-400 text-sm">2 hours ago</span>
|
| 193 |
</div>
|
| 194 |
</div>
|
| 195 |
+
</div>
|
| 196 |
+
</div>
|
| 197 |
|
| 198 |
+
<!-- Right Sidebar -->
|
| 199 |
+
<div class="space-y-6">
|
| 200 |
+
<!-- Quick Actions -->
|
| 201 |
+
<div class="bg-slate-800 rounded-lg p-6">
|
| 202 |
+
<h2 class="text-xl font-semibold text-white mb-4">Quick Actions</h2>
|
| 203 |
+
<div class="space-y-3">
|
| 204 |
+
<button class="w-full bg-orange-500 hover:bg-orange-600 text-white font-medium py-2 px-4 rounded-lg flex items-center justify-center">
|
| 205 |
+
<i data-feather="plus" class="h-4 w-4 mr-2"></i>
|
| 206 |
+
Add New Lead
|
| 207 |
+
</button>
|
| 208 |
+
<button class="w-full bg-slate-700 hover:bg-slate-600 text-white font-medium py-2 px-4 rounded-lg flex items-center justify-center">
|
| 209 |
+
<i data-feather="search" class="h-4 w-4 mr-2"></i>
|
| 210 |
+
Skip Trace Lead
|
| 211 |
+
</button>
|
| 212 |
+
<button class="w-full bg-slate-700 hover:bg-slate-600 text-white font-medium py-2 px-4 rounded-lg flex items-center justify-center">
|
| 213 |
+
<i data-feather="phone" class="h-4 w-4 mr-2"></i>
|
| 214 |
+
Start AI Call
|
| 215 |
+
</button>
|
| 216 |
+
<button class="w-full bg-slate-700 hover:bg-slate-600 text-white font-medium py-2 px-4 rounded-lg flex items-center justify-center">
|
| 217 |
+
<i data-feather="file-text" class="h-4 w-4 mr-2"></i>
|
| 218 |
+
Generate Claim
|
| 219 |
+
</button>
|
| 220 |
</div>
|
| 221 |
+
</div>
|
| 222 |
|
| 223 |
+
<!-- Compliance Status -->
|
| 224 |
+
<div class="bg-slate-800 rounded-lg p-6">
|
| 225 |
+
<h2 class="text-xl font-semibold text-white mb-4">Compliance Status</h2>
|
| 226 |
+
<div class="space-y-3">
|
| 227 |
+
<div class="flex items-center justify-between">
|
| 228 |
+
<span class="text-slate-400">TCPA Compliance</span>
|
| 229 |
+
<span class="text-green-400">99.8%</span>
|
| 230 |
</div>
|
| 231 |
+
<div class="flex items-center justify-between">
|
| 232 |
+
<span class="text-slate-400">FDCPA Compliance</span>
|
| 233 |
+
<span class="text-green-400">100%</span>
|
|
|
|
|
|
|
| 234 |
</div>
|
| 235 |
+
<div class="flex items-center justify-between">
|
| 236 |
+
<span class="text-slate-400">DNC Scrub Status</span>
|
| 237 |
+
<span class="text-green-400">Current</span>
|
|
|
|
|
|
|
|
|
|
| 238 |
</div>
|
| 239 |
+
<div class="flex items-center justify-between">
|
| 240 |
+
<span class="text-slate-400">Ethics Shield</span>
|
| 241 |
+
<span class="text-green-400">Active</span>
|
|
|
|
|
|
|
| 242 |
</div>
|
| 243 |
</div>
|
| 244 |
+
</div>
|
| 245 |
|
| 246 |
+
<!-- ARU Map -->
|
| 247 |
+
<div class="bg-slate-800 rounded-lg p-6">
|
| 248 |
+
<h2 class="text-xl font-semibold text-white mb-4">ARU Activity Map</h2>
|
| 249 |
+
<div class="h-48 bg-slate-700 rounded-lg flex items-center justify-center">
|
| 250 |
+
<div class="text-center">
|
| 251 |
+
<i data-feather="map" class="h-12 w-12 text-slate-400 mx-auto mb-2"></i>
|
| 252 |
+
<p class="text-slate-400">47 states active</p>
|
| 253 |
+
<p class="text-green-400 text-sm">1.2M leads processed</p>
|
|
|
|
|
|
|
| 254 |
</div>
|
| 255 |
</div>
|
| 256 |
</div>
|
| 257 |
</div>
|
| 258 |
</div>
|
| 259 |
+
</main>
|
| 260 |
|
| 261 |
+
<!-- Telegram Modal -->
|
| 262 |
+
<div id="telegram-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
|
| 263 |
+
<div class="bg-slate-800 rounded-lg p-6 w-96 max-w-full">
|
| 264 |
+
<div class="flex items-center justify-between mb-4">
|
| 265 |
+
<h3 class="text-xl font-semibold text-white">AI Command Center</h3>
|
| 266 |
+
<button id="close-telegram" class="text-slate-400 hover:text-white">
|
| 267 |
+
<i data-feather="x" class="h-5 w-5"></i>
|
| 268 |
+
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
</div>
|
| 270 |
+
<div class="space-y-4">
|
| 271 |
+
<input type="text" id="telegram-input" placeholder="Enter command (e.g., 'skip-trace John Doe')"
|
| 272 |
+
class="w-full bg-slate-700 text-white rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-orange-500">
|
| 273 |
+
<button id="send-command" class="w-full bg-orange-500 hover:bg-orange-600 text-white font-medium py-2 px-4 rounded-lg">
|
| 274 |
+
Send Command
|
| 275 |
+
</button>
|
| 276 |
+
<div id="telegram-response" class="bg-slate-700 rounded-lg p-4 text-slate-300 text-sm hidden">
|
| 277 |
+
<!-- Response will appear here -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
</div>
|
| 280 |
</div>
|
| 281 |
+
</div>
|
| 282 |
|
| 283 |
+
<script src="script.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
</body>
|
| 285 |
</html>
|
|
@@ -0,0 +1,455 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Leads Management - HBU Asset Recovery</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 10 |
+
<link rel="stylesheet" href="style.css">
|
| 11 |
+
</head>
|
| 12 |
+
<body class="bg-slate-900 text-slate-100">
|
| 13 |
+
<!-- Navigation -->
|
| 14 |
+
<nav class="bg-slate-800 border-b border-orange-500/20 sticky top-0 z-50">
|
| 15 |
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
| 16 |
+
<div class="flex items-center justify-between h-16">
|
| 17 |
+
<div class="flex items-center">
|
| 18 |
+
<div class="flex-shrink-0 flex items-center">
|
| 19 |
+
<i data-feather="shield" class="text-orange-500 mr-2"></i>
|
| 20 |
+
<span class="font-bold text-xl text-orange-500">HBU Asset Recovery</span>
|
| 21 |
+
</div>
|
| 22 |
+
</div>
|
| 23 |
+
<div class="hidden md:block">
|
| 24 |
+
<div class="ml-10 flex items-baseline space-x-4">
|
| 25 |
+
<a href="index.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>
|
| 26 |
+
<a href="leads.html" class="bg-orange-500 text-white px-3 py-2 rounded-md text-sm font-medium">Leads</a>
|
| 27 |
+
<a href="automation.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Automation</a>
|
| 28 |
+
<a href="compliance.html" class="text-slate-300 hover:bg-slate-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Compliance</a>
|
| 29 |
+
</div>
|
| 30 |
+
</div>
|
| 31 |
+
</div>
|
| 32 |
+
</div>
|
| 33 |
+
</nav>
|
| 34 |
+
|
| 35 |
+
<!-- Main Content -->
|
| 36 |
+
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
| 37 |
+
<!-- Header Section -->
|
| 38 |
+
<div class="flex items-center justify-between mb-8">
|
| 39 |
+
<div>
|
| 40 |
+
<h1 class="text-3xl font-bold text-white">Lead Management</h1>
|
| 41 |
+
<p class="text-slate-400 mt-1">Manage and track all asset recovery leads</p>
|
| 42 |
+
</div>
|
| 43 |
+
<button onclick="openAddLeadModal()" class="btn btn-primary">
|
| 44 |
+
<i data-feather="plus" class="h-4 w-4 mr-2"></i>
|
| 45 |
+
Add New Lead
|
| 46 |
+
</button>
|
| 47 |
+
</div>
|
| 48 |
+
|
| 49 |
+
<!-- Filters and Search -->
|
| 50 |
+
<div class="bg-slate-800 rounded-lg p-6 mb-8">
|
| 51 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
| 52 |
+
<div>
|
| 53 |
+
<input type="text" id="search-input" placeholder="Search leads..."
|
| 54 |
+
class="form-input" onkeyup="filterLeads()">
|
| 55 |
+
</div>
|
| 56 |
+
<div>
|
| 57 |
+
<select id="status-filter" class="form-input" onchange="filterLeads()">
|
| 58 |
+
<option value="">All Statuses</option>
|
| 59 |
+
<option value="NEW">New</option>
|
| 60 |
+
<option value="ENRICHED">Enriched</option>
|
| 61 |
+
<option value="CONTACTED">Contacted</option>
|
| 62 |
+
<option value="NEGOTIATING">Negotiating</option>
|
| 63 |
+
<option value="CLAIM_FILED">Claim Filed</option>
|
| 64 |
+
<option value="RECOVERED">Recovered</option>
|
| 65 |
+
</select>
|
| 66 |
+
</div>
|
| 67 |
+
<div>
|
| 68 |
+
<select id="state-filter" class="form-input" onchange="filterLeads()">
|
| 69 |
+
<option value="">All States</option>
|
| 70 |
+
<option value="OK">Oklahoma</option>
|
| 71 |
+
<option value="FL">Florida</option>
|
| 72 |
+
<option value="TX">Texas</option>
|
| 73 |
+
<option value="CA">California</option>
|
| 74 |
+
</select>
|
| 75 |
+
</div>
|
| 76 |
+
<div>
|
| 77 |
+
<select id="value-filter" class="form-input" onchange="filterLeads()">
|
| 78 |
+
<option value="">All Values</option>
|
| 79 |
+
<option value="0-10000">$0 - $10K</option>
|
| 80 |
+
<option value="10000-50000">$10K - $50K</option>
|
| 81 |
+
<option value="50000-100000">$50K - $100K</option>
|
| 82 |
+
<option value="100000+">$100K+</option>
|
| 83 |
+
</select>
|
| 84 |
+
</div>
|
| 85 |
+
</div>
|
| 86 |
+
</div>
|
| 87 |
+
|
| 88 |
+
<!-- Leads Table -->
|
| 89 |
+
<div class="bg-slate-800 rounded-lg overflow-hidden">
|
| 90 |
+
<div class="overflow-x-auto">
|
| 91 |
+
<table class="table">
|
| 92 |
+
<thead>
|
| 93 |
+
<tr>
|
| 94 |
+
<th>Lead</th>
|
| 95 |
+
<th>Contact</th>
|
| 96 |
+
<th>Claim Amount</th>
|
| 97 |
+
<th>ARV</th>
|
| 98 |
+
<th>Equity %</th>
|
| 99 |
+
<th>Status</th>
|
| 100 |
+
<th>Score</th>
|
| 101 |
+
<th>Actions</th>
|
| 102 |
+
</tr>
|
| 103 |
+
</thead>
|
| 104 |
+
<tbody id="leads-table-body">
|
| 105 |
+
<!-- Leads will be loaded here -->
|
| 106 |
+
</tbody>
|
| 107 |
+
</table>
|
| 108 |
+
</div>
|
| 109 |
+
</div>
|
| 110 |
+
|
| 111 |
+
<!-- Pagination -->
|
| 112 |
+
<div class="flex items-center justify-between mt-6">
|
| 113 |
+
<div class="text-slate-400">
|
| 114 |
+
Showing <span id="showing-start">1</span> to <span id="showing-end">10</span> of <span id="total-leads">2,847</span> leads
|
| 115 |
+
</div>
|
| 116 |
+
<div class="flex space-x-2">
|
| 117 |
+
<button onclick="changePage(-1)" class="btn btn-secondary">Previous</button>
|
| 118 |
+
<button onclick="changePage(1)" class="btn btn-secondary">Next</button>
|
| 119 |
+
</div>
|
| 120 |
+
</div>
|
| 121 |
+
</main>
|
| 122 |
+
|
| 123 |
+
<!-- Add Lead Modal -->
|
| 124 |
+
<div id="add-lead-modal" class="modal hidden">
|
| 125 |
+
<div class="modal-content max-w-2xl">
|
| 126 |
+
<div class="flex items-center justify-between mb-6">
|
| 127 |
+
<h2 class="text-2xl font-bold text-white">Add New Lead</h2>
|
| 128 |
+
<button onclick="closeAddLeadModal()" class="text-slate-400 hover:text-white">
|
| 129 |
+
<i data-feather="x" class="h-6 w-6"></i>
|
| 130 |
+
</button>
|
| 131 |
+
</div>
|
| 132 |
+
|
| 133 |
+
<form id="add-lead-form" class="space-y-4">
|
| 134 |
+
<div class="grid grid-cols-2 gap-4">
|
| 135 |
+
<div class="form-group">
|
| 136 |
+
<label class="form-label">First Name *</label>
|
| 137 |
+
<input type="text" name="firstName" class="form-input" required>
|
| 138 |
+
</div>
|
| 139 |
+
<div class="form-group">
|
| 140 |
+
<label class="form-label">Last Name *</label>
|
| 141 |
+
<input type="text" name="lastName" class="form-input" required>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
|
| 145 |
+
<div class="grid grid-cols-2 gap-4">
|
| 146 |
+
<div class="form-group">
|
| 147 |
+
<label class="form-label">Phone</label>
|
| 148 |
+
<input type="tel" name="phone" class="form-input">
|
| 149 |
+
</div>
|
| 150 |
+
<div class="form-group">
|
| 151 |
+
<label class="form-label">Email</label>
|
| 152 |
+
<input type="email" name="email" class="form-input">
|
| 153 |
+
</div>
|
| 154 |
+
</div>
|
| 155 |
+
|
| 156 |
+
<div class="form-group">
|
| 157 |
+
<label class="form-label">Address</label>
|
| 158 |
+
<input type="text" name="address" class="form-input">
|
| 159 |
+
</div>
|
| 160 |
+
|
| 161 |
+
<div class="grid grid-cols-3 gap-4">
|
| 162 |
+
<div class="form-group">
|
| 163 |
+
<label class="form-label">City</label>
|
| 164 |
+
<input type="text" name="city" class="form-input">
|
| 165 |
+
</div>
|
| 166 |
+
<div class="form-group">
|
| 167 |
+
<label class="form-label">State</label>
|
| 168 |
+
<select name="state" class="form-input">
|
| 169 |
+
<option value="OK">Oklahoma</option>
|
| 170 |
+
<option value="FL">Florida</option>
|
| 171 |
+
<option value="TX">Texas</option>
|
| 172 |
+
<option value="CA">California</option>
|
| 173 |
+
</select>
|
| 174 |
+
</div>
|
| 175 |
+
<div class="form-group">
|
| 176 |
+
<label class="form-label">ZIP</label>
|
| 177 |
+
<input type="text" name="zip" class="form-input">
|
| 178 |
+
</div>
|
| 179 |
+
</div>
|
| 180 |
+
|
| 181 |
+
<div class="grid grid-cols-2 gap-4">
|
| 182 |
+
<div class="form-group">
|
| 183 |
+
<label class="form-label">Claim Amount</label>
|
| 184 |
+
<input type="number" name="claimAmount" class="form-input" step="0.01">
|
| 185 |
+
</div>
|
| 186 |
+
<div class="form-group">
|
| 187 |
+
<label class="form-label">Source</label>
|
| 188 |
+
<select name="source" class="form-input">
|
| 189 |
+
<option value="OSCN">OSCN</option>
|
| 190 |
+
<option value="FLTreasure">FL Treasury</option>
|
| 191 |
+
<option value="Manual">Manual</option>
|
| 192 |
+
<option value="Referral">Referral</option>
|
| 193 |
+
</select>
|
| 194 |
+
</div>
|
| 195 |
+
</div>
|
| 196 |
+
|
| 197 |
+
<div class="flex justify-end space-x-4 mt-6">
|
| 198 |
+
<button type="button" onclick="closeAddLeadModal()" class="btn btn-secondary">Cancel</button>
|
| 199 |
+
<button type="submit" class="btn btn-primary">Add Lead</button>
|
| 200 |
+
</div>
|
| 201 |
+
</form>
|
| 202 |
+
</div>
|
| 203 |
+
</div>
|
| 204 |
+
|
| 205 |
+
<script src="script.js"></script>
|
| 206 |
+
<script>
|
| 207 |
+
// Lead management functionality
|
| 208 |
+
class LeadManager {
|
| 209 |
+
constructor() {
|
| 210 |
+
this.leads = [];
|
| 211 |
+
this.filteredLeads = [];
|
| 212 |
+
this.currentPage = 1;
|
| 213 |
+
this.leadsPerPage = 10;
|
| 214 |
+
this.loadLeads();
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
async loadLeads() {
|
| 218 |
+
try {
|
| 219 |
+
// Mock data - in real implementation, fetch from API
|
| 220 |
+
this.leads = [
|
| 221 |
+
{
|
| 222 |
+
id: '1',
|
| 223 |
+
firstName: 'John',
|
| 224 |
+
lastName: 'Doe',
|
| 225 |
+
phone: '(555) 123-4567',
|
| 226 |
+
email: 'john.doe@email.com',
|
| 227 |
+
claimAmount: 45000,
|
| 228 |
+
arv: 250000,
|
| 229 |
+
equity: 78,
|
| 230 |
+
status: 'NEGOTIATING',
|
| 231 |
+
recoveryScore: 92,
|
| 232 |
+
state: 'OK'
|
| 233 |
+
},
|
| 234 |
+
{
|
| 235 |
+
id: '2',
|
| 236 |
+
firstName: 'Jane',
|
| 237 |
+
lastName: 'Smith',
|
| 238 |
+
phone: '(555) 987-6543',
|
| 239 |
+
email: 'jane.smith@email.com',
|
| 240 |
+
claimAmount: 120000,
|
| 241 |
+
arv: 450000,
|
| 242 |
+
equity: 85,
|
| 243 |
+
status: 'CONTACTED',
|
| 244 |
+
recoveryScore: 88,
|
| 245 |
+
state: 'FL'
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
id: '3',
|
| 249 |
+
firstName: 'Robert',
|
| 250 |
+
lastName: 'Johnson',
|
| 251 |
+
phone: '(555) 456-7890',
|
| 252 |
+
email: 'robert.j@email.com',
|
| 253 |
+
claimAmount: 35000,
|
| 254 |
+
arv: 180000,
|
| 255 |
+
equity: 65,
|
| 256 |
+
status: 'ENRICHED',
|
| 257 |
+
recoveryScore: 75,
|
| 258 |
+
state: 'TX'
|
| 259 |
+
}
|
| 260 |
+
];
|
| 261 |
+
|
| 262 |
+
this.filteredLeads = [...this.leads];
|
| 263 |
+
this.renderLeads();
|
| 264 |
+
} catch (error) {
|
| 265 |
+
console.error('Failed to load leads:', error);
|
| 266 |
+
showToast('Failed to load leads', 'error');
|
| 267 |
+
}
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
renderLeads() {
|
| 271 |
+
const tbody = document.getElementById('leads-table-body');
|
| 272 |
+
if (!tbody) return;
|
| 273 |
+
|
| 274 |
+
const start = (this.currentPage - 1) * this.leadsPerPage;
|
| 275 |
+
const end = start + this.leadsPerPage;
|
| 276 |
+
const pageLeads = this.filteredLeads.slice(start, end);
|
| 277 |
+
|
| 278 |
+
tbody.innerHTML = pageLeads.map(lead => `
|
| 279 |
+
<tr class="hover:bg-slate-700/50">
|
| 280 |
+
<td>
|
| 281 |
+
<div class="flex items-center">
|
| 282 |
+
<img class="h-8 w-8 rounded-full mr-3" src="http://static.photos/people/40x40/${lead.id}" alt="${lead.firstName}">
|
| 283 |
+
<div>
|
| 284 |
+
<div class="text-white font-medium">${lead.firstName} ${lead.lastName}</div>
|
| 285 |
+
<div class="text-slate-400 text-sm">${lead.state}</div>
|
| 286 |
+
</div>
|
| 287 |
+
</div>
|
| 288 |
+
</td>
|
| 289 |
+
<td>
|
| 290 |
+
<div class="text-slate-300">${lead.phone}</div>
|
| 291 |
+
<div class="text-slate-400 text-sm">${lead.email}</div>
|
| 292 |
+
</td>
|
| 293 |
+
<td class="text-white font-medium">$${lead.claimAmount.toLocaleString()}</td>
|
| 294 |
+
<td class="text-slate-300">$${lead.arv.toLocaleString()}</td>
|
| 295 |
+
<td>
|
| 296 |
+
<div class="flex items-center">
|
| 297 |
+
<div class="w-16 bg-slate-700 rounded-full h-2 mr-2">
|
| 298 |
+
<div class="bg-orange-500 h-2 rounded-full" style="width: ${lead.equity}%"></div>
|
| 299 |
+
</div>
|
| 300 |
+
<span class="text-slate-300">${lead.equity}%</span>
|
| 301 |
+
</div>
|
| 302 |
+
</td>
|
| 303 |
+
<td>
|
| 304 |
+
<span class="badge badge-${this.getStatusColor(lead.status)}">${lead.status}</span>
|
| 305 |
+
</td>
|
| 306 |
+
<td>
|
| 307 |
+
<div class="text-white font-medium">${lead.recoveryScore}</div>
|
| 308 |
+
<div class="text-slate-400 text-sm">Score</div>
|
| 309 |
+
</td>
|
| 310 |
+
<td>
|
| 311 |
+
<div class="flex space-x-2">
|
| 312 |
+
<button onclick="viewLead('${lead.id}')" class="text-blue-400 hover:text-blue-300">
|
| 313 |
+
<i data-feather="eye" class="h-4 w-4"></i>
|
| 314 |
+
</button>
|
| 315 |
+
<button onclick="skipTraceLead('${lead.id}')" class="text-green-400 hover:text-green-300">
|
| 316 |
+
<i data-feather="search" class="h-4 w-4"></i>
|
| 317 |
+
</button>
|
| 318 |
+
<button onclick="contactLead('${lead.id}')" class="text-orange-400 hover:text-orange-300">
|
| 319 |
+
<i data-feather="phone" class="h-4 w-4"></i>
|
| 320 |
+
</button>
|
| 321 |
+
<button onclick="editLead('${lead.id}')" class="text-slate-400 hover:text-slate-300">
|
| 322 |
+
<i data-feather="edit" class="h-4 w-4"></i>
|
| 323 |
+
</button>
|
| 324 |
+
</div>
|
| 325 |
+
</td>
|
| 326 |
+
</tr>
|
| 327 |
+
`).join('');
|
| 328 |
+
|
| 329 |
+
feather.replace();
|
| 330 |
+
this.updatePagination();
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
getStatusColor(status) {
|
| 334 |
+
const colors = {
|
| 335 |
+
'NEW': 'info',
|
| 336 |
+
'ENRICHED': 'warning',
|
| 337 |
+
'CONTACTED': 'info',
|
| 338 |
+
'NEGOTIATING': 'warning',
|
| 339 |
+
'CLAIM_FILED': 'info',
|
| 340 |
+
'RECOVERED': 'success'
|
| 341 |
+
};
|
| 342 |
+
return colors[status] || 'info';
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
updatePagination() {
|
| 346 |
+
const total = this.filteredLeads.length;
|
| 347 |
+
const start = (this.currentPage - 1) * this.leadsPerPage + 1;
|
| 348 |
+
const end = Math.min(this.currentPage * this.leadsPerPage, total);
|
| 349 |
+
|
| 350 |
+
document.getElementById('showing-start').textContent = start;
|
| 351 |
+
document.getElementById('showing-end').textContent = end;
|
| 352 |
+
document.getElementById('total-leads').textContent = total;
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
filter(search, status, state, valueRange) {
|
| 356 |
+
this.filteredLeads = this.leads.filter(lead => {
|
| 357 |
+
const matchesSearch = !search ||
|
| 358 |
+
`${lead.firstName} ${lead.lastName}`.toLowerCase().includes(search.toLowerCase()) ||
|
| 359 |
+
lead.email?.toLowerCase().includes(search.toLowerCase()) ||
|
| 360 |
+
lead.phone?.includes(search);
|
| 361 |
+
|
| 362 |
+
const matchesStatus = !status || lead.status === status;
|
| 363 |
+
const matchesState = !state || lead.state === state;
|
| 364 |
+
|
| 365 |
+
let matchesValue = true;
|
| 366 |
+
if (valueRange) {
|
| 367 |
+
const [min, max] = valueRange.split('-').map(v => v === '+' ? Infinity : parseInt(v));
|
| 368 |
+
matchesValue = lead.claimAmount >= min && lead.claimAmount <= max;
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
return matchesSearch && matchesStatus && matchesState && matchesValue;
|
| 372 |
+
});
|
| 373 |
+
|
| 374 |
+
this.currentPage = 1;
|
| 375 |
+
this.renderLeads();
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
async addLead(leadData) {
|
| 379 |
+
try {
|
| 380 |
+
// In real implementation, send to API
|
| 381 |
+
const newLead = {
|
| 382 |
+
id: Date.now().toString(),
|
| 383 |
+
...leadData,
|
| 384 |
+
status: 'NEW',
|
| 385 |
+
recoveryScore: Math.floor(Math.random() * 30) + 70
|
| 386 |
+
};
|
| 387 |
+
|
| 388 |
+
this.leads.unshift(newLead);
|
| 389 |
+
this.filteredLeads = [...this.leads];
|
| 390 |
+
this.renderLeads();
|
| 391 |
+
|
| 392 |
+
showToast('Lead added successfully', 'success');
|
| 393 |
+
closeAddLeadModal();
|
| 394 |
+
} catch (error) {
|
| 395 |
+
console.error('Failed to add lead:', error);
|
| 396 |
+
showToast('Failed to add lead', 'error');
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
}
|
| 400 |
+
|
| 401 |
+
// Initialize lead manager
|
| 402 |
+
const leadManager = new LeadManager();
|
| 403 |
+
|
| 404 |
+
// Global functions
|
| 405 |
+
function filterLeads() {
|
| 406 |
+
const search = document.getElementById('search-input').value;
|
| 407 |
+
const status = document.getElementById('status-filter').value;
|
| 408 |
+
const state = document.getElementById('state-filter').value;
|
| 409 |
+
const valueRange = document.getElementById('value-filter').value;
|
| 410 |
+
|
| 411 |
+
leadManager.filter(search, status, state, valueRange);
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
function changePage(direction) {
|
| 415 |
+
const totalPages = Math.ceil(leadManager.filteredLeads.length / leadManager.leadsPerPage);
|
| 416 |
+
leadManager.currentPage = Math.max(1, Math.min(totalPages, leadManager.currentPage + direction));
|
| 417 |
+
leadManager.renderLeads();
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
function openAddLeadModal() {
|
| 421 |
+
document.getElementById('add-lead-modal').classList.remove('hidden');
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
function closeAddLeadModal() {
|
| 425 |
+
document.getElementById('add-lead-modal').classList.add('hidden');
|
| 426 |
+
document.getElementById('add-lead-form').reset();
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
function viewLead(id) {
|
| 430 |
+
showToast(`Viewing lead ${id}`, 'info');
|
| 431 |
+
}
|
| 432 |
+
|
| 433 |
+
function skipTraceLead(id) {
|
| 434 |
+
showToast(`Skip tracing lead ${id}`, 'info');
|
| 435 |
+
}
|
| 436 |
+
|
| 437 |
+
function contactLead(id) {
|
| 438 |
+
showToast(`Contacting lead ${id}`, 'info');
|
| 439 |
+
}
|
| 440 |
+
|
| 441 |
+
function editLead(id) {
|
| 442 |
+
showToast(`Editing lead ${id}`, 'info');
|
| 443 |
+
}
|
| 444 |
+
|
| 445 |
+
// Form submission
|
| 446 |
+
document.getElementById('add-lead-form').addEventListener('submit', async (e) => {
|
| 447 |
+
e.preventDefault();
|
| 448 |
+
const formData = new FormData(e.target);
|
| 449 |
+
const leadData = Object.fromEntries(formData.entries());
|
| 450 |
+
|
| 451 |
+
await leadManager.addLead(leadData);
|
| 452 |
+
});
|
| 453 |
+
</script>
|
| 454 |
+
</body>
|
| 455 |
+
</html>
|
|
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Initialize Feather Icons
|
| 2 |
+
feather.replace();
|
| 3 |
+
|
| 4 |
+
// Dashboard functionality
|
| 5 |
+
class HBUAssetRecovery {
|
| 6 |
+
constructor() {
|
| 7 |
+
this.initializeEventListeners();
|
| 8 |
+
this.initializeCharts();
|
| 9 |
+
this.startRealTimeUpdates();
|
| 10 |
+
this.loadDashboardData();
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
initializeEventListeners() {
|
| 14 |
+
// Telegram modal
|
| 15 |
+
const telegramBtn = document.getElementById('telegram-btn');
|
| 16 |
+
const telegramModal = document.getElementById('telegram-modal');
|
| 17 |
+
const closeTelegram = document.getElementById('close-telegram');
|
| 18 |
+
const sendCommand = document.getElementById('send-command');
|
| 19 |
+
const telegramInput = document.getElementById('telegram-input');
|
| 20 |
+
|
| 21 |
+
if (telegramBtn && telegramModal) {
|
| 22 |
+
telegramBtn.addEventListener('click', () => {
|
| 23 |
+
telegramModal.classList.remove('hidden');
|
| 24 |
+
telegramInput.focus();
|
| 25 |
+
});
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
if (closeTelegram) {
|
| 29 |
+
closeTelegram.addEventListener('click', () => {
|
| 30 |
+
telegramModal.classList.add('hidden');
|
| 31 |
+
});
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
if (sendCommand && telegramInput) {
|
| 35 |
+
sendCommand.addEventListener('click', () => {
|
| 36 |
+
this.handleTelegramCommand(telegramInput.value);
|
| 37 |
+
});
|
| 38 |
+
|
| 39 |
+
telegramInput.addEventListener('keypress', (e) => {
|
| 40 |
+
if (e.key === 'Enter') {
|
| 41 |
+
this.handleTelegramCommand(telegramInput.value);
|
| 42 |
+
}
|
| 43 |
+
});
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
// Close modal on outside click
|
| 47 |
+
telegramModal?.addEventListener('click', (e) => {
|
| 48 |
+
if (e.target === telegramModal) {
|
| 49 |
+
telegramModal.classList.add('hidden');
|
| 50 |
+
}
|
| 51 |
+
});
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
initializeCharts() {
|
| 55 |
+
// Pipeline Chart
|
| 56 |
+
const pipelineCtx = document.getElementById('pipelineChart');
|
| 57 |
+
if (pipelineCtx) {
|
| 58 |
+
new Chart(pipelineCtx.getContext('2d'), {
|
| 59 |
+
type: 'bar',
|
| 60 |
+
data: {
|
| 61 |
+
labels: ['New', 'Enriched', 'Contacted', 'Negotiating', 'Claim Filed', 'Recovered'],
|
| 62 |
+
datasets: [{
|
| 63 |
+
label: 'Leads',
|
| 64 |
+
data: [342, 287, 198, 124, 89, 67],
|
| 65 |
+
backgroundColor: [
|
| 66 |
+
'rgba(249, 115, 22, 0.8)',
|
| 67 |
+
'rgba(59, 130, 246, 0.8)',
|
| 68 |
+
'rgba(251, 191, 36, 0.8)',
|
| 69 |
+
'rgba(168, 85, 247, 0.8)',
|
| 70 |
+
'rgba(34, 197, 94, 0.8)',
|
| 71 |
+
'rgba(16, 185, 129, 0.8)'
|
| 72 |
+
],
|
| 73 |
+
borderColor: [
|
| 74 |
+
'rgba(249, 115, 22, 1)',
|
| 75 |
+
'rgba(59, 130, 246, 1)',
|
| 76 |
+
'rgba(251, 191, 36, 1)',
|
| 77 |
+
'rgba(168, 85, 247, 1)',
|
| 78 |
+
'rgba(34, 197, 94, 1)',
|
| 79 |
+
'rgba(16, 185, 129, 1)'
|
| 80 |
+
],
|
| 81 |
+
borderWidth: 2
|
| 82 |
+
}]
|
| 83 |
+
},
|
| 84 |
+
options: {
|
| 85 |
+
responsive: true,
|
| 86 |
+
maintainAspectRatio: false,
|
| 87 |
+
plugins: {
|
| 88 |
+
legend: {
|
| 89 |
+
display: false
|
| 90 |
+
}
|
| 91 |
+
},
|
| 92 |
+
scales: {
|
| 93 |
+
y: {
|
| 94 |
+
beginAtZero: true,
|
| 95 |
+
grid: {
|
| 96 |
+
color: 'rgba(148, 163, 184, 0.1)'
|
| 97 |
+
},
|
| 98 |
+
ticks: {
|
| 99 |
+
color: '#94a3b8'
|
| 100 |
+
}
|
| 101 |
+
},
|
| 102 |
+
x: {
|
| 103 |
+
grid: {
|
| 104 |
+
display: false
|
| 105 |
+
},
|
| 106 |
+
ticks: {
|
| 107 |
+
color: '#94a3b8'
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
});
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
// Revenue Chart (if exists)
|
| 116 |
+
const revenueCtx = document.getElementById('revenueChart');
|
| 117 |
+
if (revenueCtx) {
|
| 118 |
+
new Chart(revenueCtx.getContext('2d'), {
|
| 119 |
+
type: 'line',
|
| 120 |
+
data: {
|
| 121 |
+
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
|
| 122 |
+
datasets: [{
|
| 123 |
+
label: 'Revenue',
|
| 124 |
+
data: [380000, 410000, 395000, 425000, 440000, 416667],
|
| 125 |
+
borderColor: 'rgba(249, 115, 22, 1)',
|
| 126 |
+
backgroundColor: 'rgba(249, 115, 22, 0.1)',
|
| 127 |
+
tension: 0.4,
|
| 128 |
+
fill: true
|
| 129 |
+
}]
|
| 130 |
+
},
|
| 131 |
+
options: {
|
| 132 |
+
responsive: true,
|
| 133 |
+
maintainAspectRatio: false,
|
| 134 |
+
plugins: {
|
| 135 |
+
legend: {
|
| 136 |
+
display: false
|
| 137 |
+
}
|
| 138 |
+
},
|
| 139 |
+
scales: {
|
| 140 |
+
y: {
|
| 141 |
+
beginAtZero: false,
|
| 142 |
+
grid: {
|
| 143 |
+
color: 'rgba(148, 163, 184, 0.1)'
|
| 144 |
+
},
|
| 145 |
+
ticks: {
|
| 146 |
+
color: '#94a3b8',
|
| 147 |
+
callback: function(value) {
|
| 148 |
+
return '$' + (value / 1000) + 'K';
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
},
|
| 152 |
+
x: {
|
| 153 |
+
grid: {
|
| 154 |
+
display: false
|
| 155 |
+
},
|
| 156 |
+
ticks: {
|
| 157 |
+
color: '#94a3b8'
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
});
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
async handleTelegramCommand(command) {
|
| 167 |
+
const responseDiv = document.getElementById('telegram-response');
|
| 168 |
+
const input = document.getElementById('telegram-input');
|
| 169 |
+
|
| 170 |
+
if (!command.trim()) return;
|
| 171 |
+
|
| 172 |
+
// Show loading state
|
| 173 |
+
responseDiv.innerHTML = '<div class="flex items-center"><div class="loading-spinner mr-3"></div>Processing command...</div>';
|
| 174 |
+
responseDiv.classList.remove('hidden');
|
| 175 |
+
|
| 176 |
+
try {
|
| 177 |
+
// Simulate API call to AI command center
|
| 178 |
+
const response = await fetch('/api/command/ai-route', {
|
| 179 |
+
method: 'POST',
|
| 180 |
+
headers: {
|
| 181 |
+
'Content-Type': 'application/json',
|
| 182 |
+
},
|
| 183 |
+
body: JSON.stringify({ command })
|
| 184 |
+
});
|
| 185 |
+
|
| 186 |
+
const result = await response.json();
|
| 187 |
+
|
| 188 |
+
if (response.ok) {
|
| 189 |
+
responseDiv.innerHTML = `
|
| 190 |
+
<div class="flex items-start">
|
| 191 |
+
<i data-feather="check-circle" class="text-green-400 mr-2 mt-1 h-4 w-4"></i>
|
| 192 |
+
<div>
|
| 193 |
+
<p class="text-green-400 font-medium">Command processed successfully</p>
|
| 194 |
+
<p class="mt-1">${result.response}</p>
|
| 195 |
+
</div>
|
| 196 |
+
</div>
|
| 197 |
+
`;
|
| 198 |
+
input.value = '';
|
| 199 |
+
this.showToast('Command executed successfully', 'success');
|
| 200 |
+
} else {
|
| 201 |
+
throw new Error(result.error || 'Command failed');
|
| 202 |
+
}
|
| 203 |
+
} catch (error) {
|
| 204 |
+
responseDiv.innerHTML = `
|
| 205 |
+
<div class="flex items-start">
|
| 206 |
+
<i data-feather="alert-circle" class="text-red-400 mr-2 mt-1 h-4 w-4"></i>
|
| 207 |
+
<div>
|
| 208 |
+
<p class="text-red-400 font-medium">Error processing command</p>
|
| 209 |
+
<p class="mt-1">${error.message}</p>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
+
`;
|
| 213 |
+
this.showToast('Command failed: ' + error.message, 'error');
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
// Re-initialize feather icons
|
| 217 |
+
feather.replace();
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
async loadDashboardData() {
|
| 221 |
+
try {
|
| 222 |
+
// Simulate loading dashboard data
|
| 223 |
+
const dashboardData = await this.fetchDashboardMetrics();
|
| 224 |
+
this.updateDashboardUI(dashboardData);
|
| 225 |
+
} catch (error) {
|
| 226 |
+
console.error('Failed to load dashboard data:', error);
|
| 227 |
+
}
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
async fetchDashboardMetrics() {
|
| 231 |
+
// Mock data - in real implementation, this would call your API
|
| 232 |
+
return {
|
| 233 |
+
monthlyRevenue: 416667,
|
| 234 |
+
activeLeads: 2847,
|
| 235 |
+
successRate: 98.2,
|
| 236 |
+
aruStatus: 'Active',
|
| 237 |
+
recentActivity: [
|
| 238 |
+
{ type: 'success', message: 'Claim Approved - $45,000', details: 'John Doe - Oklahoma County', time: '2 min ago' },
|
| 239 |
+
{ type: 'warning', message: 'New High-Value Lead', details: 'ARV $350K - Equity 78%', time: '15 min ago' },
|
| 240 |
+
{ type: 'info', message: 'ARU Swarm Completed', details: '1,247 leads processed - FL', time: '1 hour ago' },
|
| 241 |
+
{ type: 'info', message: 'AI Call Campaign Sent', details: '234 contacts - 67% answer rate', time: '2 hours ago' }
|
| 242 |
+
]
|
| 243 |
+
};
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
updateDashboardUI(data) {
|
| 247 |
+
// Update metrics
|
| 248 |
+
const elements = {
|
| 249 |
+
monthlyRevenue: document.querySelector('[data-metric="revenue"]'),
|
| 250 |
+
activeLeads: document.querySelector('[data-metric="leads"]'),
|
| 251 |
+
successRate: document.querySelector('[data-metric="success"]'),
|
| 252 |
+
aruStatus: document.querySelector('[data-metric="aru-status"]')
|
| 253 |
+
};
|
| 254 |
+
|
| 255 |
+
if (elements.monthlyRevenue) {
|
| 256 |
+
elements.monthlyRevenue.textContent = this.formatCurrency(data.monthlyRevenue);
|
| 257 |
+
}
|
| 258 |
+
if (elements.activeLeads) {
|
| 259 |
+
elements.activeLeads.textContent = data.activeLeads.toLocaleString();
|
| 260 |
+
}
|
| 261 |
+
if (elements.successRate) {
|
| 262 |
+
elements.successRate.textContent = data.successRate + '%';
|
| 263 |
+
}
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
formatCurrency(amount) {
|
| 267 |
+
return new Intl.NumberFormat('en-US', {
|
| 268 |
+
style: 'currency',
|
| 269 |
+
currency: 'USD',
|
| 270 |
+
minimumFractionDigits: 0
|
| 271 |
+
}).format(amount);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
startRealTimeUpdates() {
|
| 275 |
+
// Simulate real-time updates
|
| 276 |
+
setInterval(() => {
|
| 277 |
+
this.updateRealTimeMetrics();
|
| 278 |
+
}, 30000); // Update every 30 seconds
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
updateRealTimeMetrics() {
|
| 282 |
+
// Simulate small changes in metrics
|
| 283 |
+
const revenueElement = document.querySelector('[data-metric="revenue"]');
|
| 284 |
+
if (revenueElement) {
|
| 285 |
+
const currentRevenue = parseInt(revenueElement.textContent.replace(/[$,]/g, ''));
|
| 286 |
+
const newRevenue = currentRevenue + Math.floor(Math.random() * 1000);
|
| 287 |
+
revenueElement.textContent = this.formatCurrency(newRevenue);
|
| 288 |
+
}
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
showToast(message, type = 'info') {
|
| 292 |
+
const toast = document.createElement('div');
|
| 293 |
+
toast.className = `toast toast-${type}`;
|
| 294 |
+
toast.innerHTML = `
|
| 295 |
+
<div class="flex items-center">
|
| 296 |
+
<i data-feather="${this.getToastIcon(type)}" class="mr-2 h-5 w-5"></i>
|
| 297 |
+
<span>${message}</span>
|
| 298 |
+
</div>
|
| 299 |
+
`;
|
| 300 |
+
|
| 301 |
+
document.body.appendChild(toast);
|
| 302 |
+
|
| 303 |
+
// Trigger animation
|
| 304 |
+
setTimeout(() => toast.classList.add('show'), 100);
|
| 305 |
+
|
| 306 |
+
// Remove after 3 seconds
|
| 307 |
+
setTimeout(() => {
|
| 308 |
+
toast.classList.remove('show');
|
| 309 |
+
setTimeout(() => toast.remove(), 300);
|
| 310 |
+
}, 3000);
|
| 311 |
+
|
| 312 |
+
feather.replace();
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
getToastIcon(type) {
|
| 316 |
+
switch(type) {
|
| 317 |
+
case 'success': return 'check-circle';
|
| 318 |
+
case 'error': return 'x-circle';
|
| 319 |
+
case 'warning': return 'alert-triangle';
|
| 320 |
+
default: return 'info';
|
| 321 |
+
}
|
| 322 |
+
}
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
// Utility functions
|
| 326 |
+
const hbu = new HBUAssetRecovery();
|
| 327 |
+
|
| 328 |
+
// Export for use in other scripts
|
| 329 |
+
window.HBU = hbu;
|
| 330 |
+
window.showToast = (message, type) => hbu.showToast(message, type);
|
| 331 |
+
|
| 332 |
+
// Keyboard shortcuts
|
| 333 |
+
document.addEventListener('keydown', (e) => {
|
| 334 |
+
// Ctrl/Cmd + K for quick search/commands
|
| 335 |
+
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
|
| 336 |
+
e.preventDefault();
|
| 337 |
+
document.getElementById('telegram-btn')?.click();
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
// Escape to close modals
|
| 341 |
+
if (e.key === 'Escape') {
|
| 342 |
+
document.getElementById('telegram-modal')?.classList.add('hidden');
|
| 343 |
+
}
|
| 344 |
+
});
|
| 345 |
+
|
| 346 |
+
// Page visibility change handling
|
| 347 |
+
document.addEventListener('visibilitychange', () => {
|
| 348 |
+
if (!document.hidden) {
|
| 349 |
+
hbu.loadDashboardData(); // Refresh data when page becomes visible
|
| 350 |
+
}
|
| 351 |
+
});
|
|
@@ -1,28 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
|
|
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
margin-bottom: 10px;
|
| 15 |
-
margin-top: 5px;
|
| 16 |
}
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
.card {
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
|
|
|
| 1 |
+
|
| 2 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
| 3 |
+
|
| 4 |
+
* {
|
| 5 |
+
margin: 0;
|
| 6 |
+
padding: 0;
|
| 7 |
+
box-sizing: border-box;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
body {
|
| 11 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 12 |
+
background-color: #0f172a;
|
| 13 |
+
color: #e2e8f0;
|
| 14 |
+
line-height: 1.6;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
/* Smooth scrolling */
|
| 18 |
+
html {
|
| 19 |
+
scroll-behavior: smooth;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
/* Custom scrollbar */
|
| 23 |
+
::-webkit-scrollbar {
|
| 24 |
+
width: 8px;
|
| 25 |
+
height: 8px;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
::-webkit-scrollbar-track {
|
| 29 |
+
background: #1e293b;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
::-webkit-scrollbar-thumb {
|
| 33 |
+
background: #475569;
|
| 34 |
+
border-radius: 4px;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
::-webkit-scrollbar-thumb:hover {
|
| 38 |
+
background: #64748b;
|
| 39 |
}
|
| 40 |
|
| 41 |
+
/* Animations */
|
| 42 |
+
@keyframes fadeIn {
|
| 43 |
+
from { opacity: 0; transform: translateY(10px); }
|
| 44 |
+
to { opacity: 1; transform: translateY(0); }
|
| 45 |
}
|
| 46 |
|
| 47 |
+
@keyframes pulse {
|
| 48 |
+
0%, 100% { opacity: 1; }
|
| 49 |
+
50% { opacity: 0.5; }
|
|
|
|
|
|
|
| 50 |
}
|
| 51 |
|
| 52 |
+
@keyframes slideIn {
|
| 53 |
+
from { transform: translateX(-100%); }
|
| 54 |
+
to { transform: translateX(0); }
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.fade-in {
|
| 58 |
+
animation: fadeIn 0.3s ease-out;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.pulse {
|
| 62 |
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
/* Card styles */
|
| 66 |
.card {
|
| 67 |
+
background: #1e293b;
|
| 68 |
+
border: 1px solid #334155;
|
| 69 |
+
border-radius: 12px;
|
| 70 |
+
padding: 1.5rem;
|
| 71 |
+
transition: all 0.3s ease;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
.card:hover {
|
| 75 |
+
border-color: #f97316;
|
| 76 |
+
box-shadow: 0 10px 25px -5px rgba(249, 115, 22, 0.1);
|
| 77 |
+
transform: translateY(-2px);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
/* Button styles */
|
| 81 |
+
.btn {
|
| 82 |
+
display: inline-flex;
|
| 83 |
+
align-items: center;
|
| 84 |
+
justify-content: center;
|
| 85 |
+
padding: 0.5rem 1rem;
|
| 86 |
+
border-radius: 8px;
|
| 87 |
+
font-weight: 500;
|
| 88 |
+
transition: all 0.2s ease;
|
| 89 |
+
cursor: pointer;
|
| 90 |
+
text-decoration: none;
|
| 91 |
+
border: none;
|
| 92 |
+
outline: none;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
.btn-primary {
|
| 96 |
+
background-color: #f97316;
|
| 97 |
+
color: white;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.btn-primary:hover {
|
| 101 |
+
background-color: #ea580c;
|
| 102 |
+
transform: translateY(-1px);
|
| 103 |
+
box-shadow: 0 4px 12px rgba(249, 115, 22, 0.25);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.btn-secondary {
|
| 107 |
+
background-color: #374151;
|
| 108 |
+
color: white;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
.btn-secondary:hover {
|
| 112 |
+
background-color: #4b5563;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
.btn-outline {
|
| 116 |
+
background-color: transparent;
|
| 117 |
+
border: 1px solid #f97316;
|
| 118 |
+
color: #f97316;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.btn-outline:hover {
|
| 122 |
+
background-color: #f97316;
|
| 123 |
+
color: white;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
/* Status badges */
|
| 127 |
+
.badge {
|
| 128 |
+
display: inline-flex;
|
| 129 |
+
align-items: center;
|
| 130 |
+
padding: 0.25rem 0.75rem;
|
| 131 |
+
border-radius: 9999px;
|
| 132 |
+
font-size: 0.75rem;
|
| 133 |
+
font-weight: 600;
|
| 134 |
+
text-transform: uppercase;
|
| 135 |
+
letter-spacing: 0.05em;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
.badge-success {
|
| 139 |
+
background-color: rgba(34, 197, 94, 0.1);
|
| 140 |
+
color: #22c55e;
|
| 141 |
+
border: 1px solid rgba(34, 197, 94, 0.2);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
.badge-warning {
|
| 145 |
+
background-color: rgba(251, 191, 36, 0.1);
|
| 146 |
+
color: #fbbf24;
|
| 147 |
+
border: 1px solid rgba(251, 191, 36, 0.2);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.badge-danger {
|
| 151 |
+
background-color: rgba(239, 68, 68, 0.1);
|
| 152 |
+
color: #ef4444;
|
| 153 |
+
border: 1px solid rgba(239, 68, 68, 0.2);
|
| 154 |
}
|
| 155 |
|
| 156 |
+
.badge-info {
|
| 157 |
+
background-color: rgba(59, 130, 246, 0.1);
|
| 158 |
+
color: #3b82f6;
|
| 159 |
+
border: 1px solid rgba(59, 130, 246, 0.2);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
/* Form styles */
|
| 163 |
+
.form-group {
|
| 164 |
+
margin-bottom: 1rem;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
.form-label {
|
| 168 |
+
display: block;
|
| 169 |
+
margin-bottom: 0.5rem;
|
| 170 |
+
font-weight: 500;
|
| 171 |
+
color: #d1d5db;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.form-input {
|
| 175 |
+
width: 100%;
|
| 176 |
+
padding: 0.75rem;
|
| 177 |
+
background-color: #374151;
|
| 178 |
+
border: 1px solid #4b5563;
|
| 179 |
+
border-radius: 8px;
|
| 180 |
+
color: white;
|
| 181 |
+
transition: all 0.2s ease;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
.form-input:focus {
|
| 185 |
+
outline: none;
|
| 186 |
+
border-color: #f97316;
|
| 187 |
+
box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.1);
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.form-input::placeholder {
|
| 191 |
+
color: #9ca3af;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
/* Table styles */
|
| 195 |
+
.table {
|
| 196 |
+
width: 100%;
|
| 197 |
+
border-collapse: collapse;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
.table th,
|
| 201 |
+
.table td {
|
| 202 |
+
padding: 0.75rem;
|
| 203 |
+
text-align: left;
|
| 204 |
+
border-bottom: 1px solid #374151;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.table th {
|
| 208 |
+
background-color: #1e293b;
|
| 209 |
+
font-weight: 600;
|
| 210 |
+
color: #d1d5db;
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
.table tbody tr:hover {
|
| 214 |
+
background-color: rgba(55, 65, 81, 0.5);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
/* Loading spinner */
|
| 218 |
+
.loading-spinner {
|
| 219 |
+
width: 40px;
|
| 220 |
+
height: 40px;
|
| 221 |
+
border: 4px solid #374151;
|
| 222 |
+
border-top: 4px solid #f97316;
|
| 223 |
+
border-radius: 50%;
|
| 224 |
+
animation: spin 1s linear infinite;
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
@keyframes spin {
|
| 228 |
+
0% { transform: rotate(0deg); }
|
| 229 |
+
100% { transform: rotate(360deg); }
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
/* Modal styles */
|
| 233 |
+
.modal {
|
| 234 |
+
position: fixed;
|
| 235 |
+
top: 0;
|
| 236 |
+
left: 0;
|
| 237 |
+
width: 100%;
|
| 238 |
+
height: 100%;
|
| 239 |
+
background-color: rgba(0, 0, 0, 0.5);
|
| 240 |
+
display: flex;
|
| 241 |
+
align-items: center;
|
| 242 |
+
justify-content: center;
|
| 243 |
+
z-index: 1000;
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
.modal-content {
|
| 247 |
+
background-color: #1e293b;
|
| 248 |
+
border-radius: 12px;
|
| 249 |
+
padding: 2rem;
|
| 250 |
+
max-width: 90%;
|
| 251 |
+
max-height: 90%;
|
| 252 |
+
overflow-y: auto;
|
| 253 |
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
/* Toast notification */
|
| 257 |
+
.toast {
|
| 258 |
+
position: fixed;
|
| 259 |
+
bottom: 2rem;
|
| 260 |
+
right: 2rem;
|
| 261 |
+
padding: 1rem 1.5rem;
|
| 262 |
+
background-color: #1e293b;
|
| 263 |
+
border-radius: 8px;
|
| 264 |
+
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.25);
|
| 265 |
+
z-index: 1000;
|
| 266 |
+
transform: translateX(400px);
|
| 267 |
+
transition: transform 0.3s ease;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
.toast.show {
|
| 271 |
+
transform: translateX(0);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
.toast-success {
|
| 275 |
+
border-left: 4px solid #22c55e;
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.toast-error {
|
| 279 |
+
border-left: 4px solid #ef4444;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
.toast-warning {
|
| 283 |
+
border-left: 4px solid #fbbf24;
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
/* Utility classes */
|
| 287 |
+
.text-center { text-align: center; }
|
| 288 |
+
.text-left { text-align: left; }
|
| 289 |
+
.text-right { text-align: right; }
|
| 290 |
+
|
| 291 |
+
.hidden { display: none; }
|
| 292 |
+
.block { display: block; }
|
| 293 |
+
.flex { display: flex; }
|
| 294 |
+
.grid { display: grid; }
|
| 295 |
+
|
| 296 |
+
.items-center { align-items: center; }
|
| 297 |
+
.justify-center { justify-content: center; }
|
| 298 |
+
.justify-between { justify-content: space-between; }
|
| 299 |
+
|
| 300 |
+
.w-full { width: 100%; }
|
| 301 |
+
.h-full { height: 100%; }
|
| 302 |
+
|
| 303 |
+
.rounded { border-radius: 0.25rem; }
|
| 304 |
+
.rounded-lg { border-radius: 0.5rem; }
|
| 305 |
+
.rounded-xl { border-radius: 0.75rem; }
|
| 306 |
+
|
| 307 |
+
.shadow { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); }
|
| 308 |
+
.shadow-lg { box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
|
| 309 |
+
|
| 310 |
+
/* Responsive utilities */
|
| 311 |
+
@media (max-width: 768px) {
|
| 312 |
+
.modal-content {
|
| 313 |
+
padding: 1rem;
|
| 314 |
+
margin: 1rem;
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
.toast {
|
| 318 |
+
bottom: 1rem;
|
| 319 |
+
right: 1rem;
|
| 320 |
+
left: 1rem;
|
| 321 |
+
}
|
| 322 |
}
|