Files
wevads-platform/public/data-import.php
2026-04-07 03:04:16 +02:00

211 lines
12 KiB
PHP

<?php
require_once('/opt/wevads/config/credentials.php');
error_reporting(E_ALL);
ini_set('display_errors', 0);
set_time_limit(0);
try {
$pdo = get_pdo('adx_system');
} catch (PDOException $e) { die("Database connection failed"); }
$dataDir = '/opt/PLATFOMRDELIVERABILITYWEVAL';
$response = ['success' => false, 'message' => '', 'data' => null];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Content-Type: application/json');
$action = $_POST['action'] ?? '';
if ($action === 'scan_files') {
$files = [];
if (is_dir($dataDir)) {
foreach (new DirectoryIterator($dataDir) as $file) {
if ($file->isDot()) continue;
$ext = strtolower($file->getExtension());
if (!in_array($ext, ['csv', 'txt'])) continue;
$lines = 0;
$handle = fopen($file->getPathname(), 'r');
while (!feof($handle)) { fgets($handle); $lines++; }
fclose($handle);
$fn = strtolower($file->getBasename());
$isp = 'Mixed';
if (strpos($fn,'gmail')!==false) $isp='Gmail';
elseif (strpos($fn,'hotmail')!==false || strpos($fn,'outlook')!==false) $isp='Hotmail';
elseif (strpos($fn,'yahoo')!==false) $isp='Yahoo';
elseif (strpos($fn,'gmx')!==false) $isp='GMX';
$seg = 'cold';
if (strpos($fn,'click')!==false) $seg='hot';
elseif (strpos($fn,'open')!==false || strpos($fn,'active')!==false) $seg='warm';
$country = null;
if (preg_match('/[_-](us|uk|ca|de|fr|au|es|nl|se|no|fi)[\._-]/i', $fn, $m)) $country = strtoupper($m[1]);
$files[] = ['name'=>$file->getBasename(),'size'=>round($file->getSize()/1024,1).'KB','lines'=>$lines-1,'isp'=>$isp,'segment'=>$seg,'country'=>$country];
}
}
usort($files, fn($a,$b) => $b['lines'] - $a['lines']);
echo json_encode(['success'=>true,'data'=>$files]); exit;
}
if ($action === 'import_file') {
$file = basename($_POST['file'] ?? '');
$segment = $_POST['segment'] ?? 'cold';
$country = $_POST['country'] ?? null;
$filepath = $dataDir . '/' . $file;
if (!file_exists($filepath)) { echo json_encode(['success'=>false,'message'=>'File not found']); exit; }
$handle = fopen($filepath, 'r');
$first = fgets($handle); rewind($handle);
$delim = substr_count($first,';') > substr_count($first,',') ? ';' : ',';
fgetcsv($handle, 0, $delim);
$imported = 0; $skipped = 0;
$stmt = $pdo->prepare("INSERT INTO admin.leads (email,country,segment,isp,source_file,created_at) VALUES (?,?,?,?,?,NOW()) ON CONFLICT (email) DO UPDATE SET segment=CASE WHEN EXCLUDED.segment='hot' THEN 'hot' WHEN admin.leads.segment='hot' THEN 'hot' WHEN EXCLUDED.segment='warm' THEN 'warm' ELSE admin.leads.segment END, updated_at=NOW()");
while (($row = fgetcsv($handle, 0, $delim)) !== false) {
$email = null;
foreach ($row as $val) { if (filter_var(trim($val), FILTER_VALIDATE_EMAIL)) { $email = strtolower(trim($val)); break; } }
if (!$email) { $skipped++; continue; }
$domain = substr(strrchr($email, "@"), 1);
$isp = 'Other';
if (strpos($domain,'gmail')!==false) $isp='Gmail';
elseif (strpos($domain,'hotmail')!==false || strpos($domain,'outlook')!==false || strpos($domain,'live')!==false) $isp='Hotmail';
elseif (strpos($domain,'yahoo')!==false) $isp='Yahoo';
try { $stmt->execute([$email,$country,$segment,$isp,$file]); $imported++; } catch(Exception $e) { $skipped++; }
}
fclose($handle);
echo json_encode(['success'=>true,'message'=>"Imported: $imported, Skipped: $skipped",'data'=>['imported'=>$imported,'skipped'=>$skipped]]); exit;
}
}
$totalLeads = $pdo->query("SELECT COUNT(*) FROM admin.leads")->fetchColumn() ?: 0;
$todayImported = $pdo->query("SELECT COUNT(*) FROM admin.leads WHERE created_at::date = CURRENT_DATE")->fetchColumn() ?: 0;
?>
<!DOCTYPE html>
<html><head>
<meta charset="UTF-8">
<title>WEVAL SEND Import</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root{--primary:#2563eb;--primary-dark:#1d4ed8;--secondary:#7c3aed;--success:#10b981;--warning:#f59e0b;--danger:#ef4444;--bg-dark:#0f172a;--bg-card:#1e293b;--bg-hover:#334155;--text-primary:#f1f5f9;--text-secondary:#94a3b8;--border:#334155}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Inter',sans-serif;background:var(--bg-dark);color:var(--text-primary);min-height:100vh}
.header{background:linear-gradient(135deg,#2563eb 0%,#7c3aed 100%);padding:0 30px;height:70px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 4px 20px rgba(37,99,235,0.3)}
.logo{display:flex;align-items:center;gap:12px}
.logo-icon{width:45px;height:45px;background:rgba(255,255,255,0.2);border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:24px}
.logo-text{font-size:22px;font-weight:700;color:white}
.header-nav{display:flex;gap:8px}
.nav-btn{padding:10px 20px;background:rgba(255,255,255,0.15);border:1px solid rgba(255,255,255,0.2);border-radius:10px;color:white;text-decoration:none;font-weight:500;font-size:14px}
.nav-btn:hover{background:rgba(255,255,255,0.25)}
.container{max-width:1400px;margin:0 auto;padding:24px}
.stats-bar{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:24px}
.stat-card{background:var(--bg-card);border-radius:16px;padding:20px;border:1px solid var(--border);position:relative;overflow:hidden}
.stat-card::before{content:'';position:absolute;top:0;left:0;right:0;height:4px;background:linear-gradient(90deg,#2563eb,#7c3aed)}
.stat-value{font-size:32px;font-weight:700;margin-bottom:4px}
.stat-label{font-size:13px;color:var(--text-secondary)}
.log-area{background:var(--bg-dark);border:1px solid var(--border);border-radius:10px;padding:16px;font-family:monospace;font-size:12px;max-height:200px;overflow-y:auto}
.log-success{color:#10b981}
.log-error{color:#ef4444}
.log-info{color:#3b82f6}
.progress-bar{width:100%;height:8px;background:var(--bg-dark);border-radius:4px;overflow:hidden;margin:12px 0}
.progress-fill{height:100%;background:linear-gradient(90deg,#2563eb,#7c3aed);border-radius:4px;transition:width 0.3s}
#loading{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(15,23,42,0.9);display:none;justify-content:center;align-items:center;z-index:1000}
.spinner{width:50px;height:50px;border:4px solid var(--border);border-top-color:var(--primary);border-radius:50%;animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.empty-state{text-align:center;padding:60px}
.empty-icon{font-size:48px;margin-bottom:16px;opacity:0.5}
.empty-text{color:var(--text-secondary)}
</style>
</head>
<body>
<header class="header">
<div class="logo"><div class="logo-icon">📥</div><div class="logo-text">WEVAL SEND Import</div></div>
<nav class="header-nav">
<a href="crm.php" class="nav-btn">👥 CRM</a>
<a href="world-dashboard.php" class="nav-btn">🌍 Dashboard</a>
<a href="index.php" class="nav-btn">🏠 WEVAL</a>
</nav>
</header>
<div class="container">
<div class="stats-bar">
<div class="stat-card"><div class="stat-value" id="totalFiles">-</div><div class="stat-label">📁 Files Found</div></div>
<div class="stat-card"><div class="stat-value" id="totalRecords">-</div><div class="stat-label">📧 Total Records</div></div>
<div class="stat-card"><div class="stat-value"><?php echo number_format($totalLeads); ?></div><div class="stat-label">✅ In Database</div></div>
<div class="stat-card"><div class="stat-value"><?php echo number_format($todayImported); ?></div><div class="stat-label">📊 Today</div></div>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">📂 Data Files - /opt/PLATFOMRDELIVERABILITYWEVAL</span>
<button class="btn btn-secondary" onclick="scanFiles()">🔄 Refresh</button>
</div>
<div class="panel-body">
<div class="toolbar">
<input type="text" class="search-input" id="searchBox" placeholder="🔍 Search files...">
<div class="filter-btns">
<button class="filter-btn active" data-filter="all">All</button>
<button class="filter-btn" data-filter="hot">🔥 Hot</button>
<button class="filter-btn" data-filter="warm">🌡️ Warm</button>
<button class="filter-btn" data-filter="cold">❄️ Cold</button>
</div>
<label style="display:flex;align-items:center;gap:8px;color:var(--text-secondary);font-size:14px"><input type="checkbox" id="selectAll" style="width:18px;height:18px"> Select All</label>
<button class="btn btn-success" onclick="importSelected()">⬆️ Import Selected</button>
</div>
<div class="file-grid" id="fileGrid"><div class="empty-state"><div class="empty-icon">📂</div><p class="empty-text">Loading files...</p></div></div>
</div>
</div>
<div class="panel">
<div class="panel-header">
<span class="panel-title">📋 Import Log</span>
<button class="btn btn-secondary" onclick="clearLog()">Clear</button>
</div>
<div class="panel-body">
<div class="progress-bar" id="progressBar" style="display:none"><div class="progress-fill" id="progressFill" style="width:0%"></div></div>
<div class="log-area" id="logArea">Ready to import data...</div>
</div>
</div>
</div>
<div id="loading"><div class="spinner"></div></div>
function renderFiles(files){
const grid=document.getElementById('fileGrid');
if(files.length===0){grid.innerHTML='<div class="empty-state"><div class="empty-icon">📭</div><p class="empty-text">No files found</p></div>';return}
let html='';
files.forEach(f=>{
const segCls=f.segment==='hot'?'badge-hot':f.segment==='warm'?'badge-warm':'badge-cold';
const segIcon=f.segment==='hot'?'🔥':f.segment==='warm'?'🌡️':'❄️';
html+=`<div class="file-card">
<input type="checkbox" class="file-check" data-name="${f.name}" data-segment="${f.segment}" data-country="${f.country||''}">
<span class="file-name" title="${f.name}">${f.name}</span>
<span class="file-meta">${f.size}</span>
<span class="file-meta">${f.lines.toLocaleString()}</span>
<span class="badge badge-isp">${f.isp}</span>
<span class="badge ${segCls}">${segIcon} ${f.segment}</span>
<span class="file-meta">${f.country||'-'}</span>
</div>`;
});
grid.innerHTML=html;
}
async function importSelected(){
const checked=document.querySelectorAll('.file-check:checked');
if(checked.length===0){alert('Select files first');return}
if(!confirm('Import '+checked.length+' file(s)?'))return;
showLoading();document.getElementById('progressBar').style.display='block';
let done=0,totalImported=0,totalSkipped=0;
for(const cb of checked){
const name=cb.dataset.name,seg=cb.dataset.segment,country=cb.dataset.country;
log('Importing '+name+'...','info');
try{
const r=await fetch('',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'action=import_file&file='+encodeURIComponent(name)+'&segment='+seg+'&country='+country});
const res=await r.json();
if(res.success){log('✅ '+name+': '+res.message,'success');totalImported+=res.data.imported;totalSkipped+=res.data.skipped}
else{log('❌ '+name+': '+res.message,'error')}
}catch(e){log('❌ '+name+': '+e.message,'error')}
done++;document.getElementById('progressFill').style.width=(done/checked.length*100)+'%';
}
log('📊 Total: '+totalImported+' imported, '+totalSkipped+' skipped','info');
hideLoading();setTimeout(()=>location.reload(),2000);
}
function log(msg,type='info'){const a=document.getElementById('logArea');a.innerHTML+=`<div class="log-${type}">[${new Date().toLocaleTimeString()}] ${msg}</div>`;a.scrollTop=a.scrollHeight}
function clearLog(){document.getElementById('logArea').innerHTML='Ready...';document.getElementById('progressBar').style.display='none'}
function showLoading(){document.getElementById('loading').style.display='flex'}
function hideLoading(){document.getElementById('loading').style.display='none'}
</script>
</body></html>