exec("SET time_zone = '+05:30'"); } catch (Exception $e) { error_log("Projects page DB error: ".$e->getMessage()); } // ===== Snapshot KPIs ===== $kpi = [ 'total' => 0, 'live' => 0, 'closed' => 0, 'on_hold' => 0, 'created' => 0, 'targeted' => 0, 'sample_target' => 0, 'completes_total' => 0, 'completes_valid' => 0, 'avg_eloi' => 0, 'avg_actual_loi_min' => 0, 'revenue_inr' => 0, 'active_clients' => 0, 'urls_sent_total' => 0, 'urls_screenout_total' => 0, ]; $forexRates = ['INR' => 1.0, 'USD' => 86.50, 'EUR' => 93.00]; if ($pdo) { // Live forex (best-effort) try { $ctx = stream_context_create(['http' => ['timeout' => 3]]); $rateJson = @file_get_contents('https://api.exchangerate-api.com/v4/latest/USD', false, $ctx); if ($rateJson) { $rateData = json_decode($rateJson, true); if (!empty($rateData['rates']['INR'])) { $usdToInr = (float)$rateData['rates']['INR']; $forexRates['USD'] = $usdToInr; if (!empty($rateData['rates']['EUR'])) { $forexRates['EUR'] = $usdToInr / (float)$rateData['rates']['EUR']; } } } } catch (Exception $e) { /* fallback rates */ } try { $stmt = $pdo->query("SELECT COUNT(*) as total, SUM(CASE WHEN status='Live' THEN 1 ELSE 0 END) as live_cnt, SUM(CASE WHEN status='Closed' THEN 1 ELSE 0 END) as closed_cnt, SUM(CASE WHEN status='On hold' THEN 1 ELSE 0 END) as hold_cnt, SUM(CASE WHEN status='Created' THEN 1 ELSE 0 END) as created_cnt, SUM(CASE WHEN status='Targeted' THEN 1 ELSE 0 END) as targeted_cnt, COALESCE(SUM(sample_size),0) as sample_target, AVG(eloi) as avg_eloi, COUNT(DISTINCT client_id) as active_clients FROM projects"); $row = $stmt->fetch(); if ($row) { $kpi['total'] = (int)$row['total']; $kpi['live'] = (int)$row['live_cnt']; $kpi['closed'] = (int)$row['closed_cnt']; $kpi['on_hold'] = (int)$row['hold_cnt']; $kpi['created'] = (int)$row['created_cnt']; $kpi['targeted'] = (int)$row['targeted_cnt']; $kpi['sample_target'] = (int)$row['sample_target']; $kpi['avg_eloi'] = round((float)($row['avg_eloi'] ?? 0), 1); $kpi['active_clients'] = (int)$row['active_clients']; } } catch (Exception $e) { error_log("Projects KPI agg error: ".$e->getMessage()); } try { $stmt = $pdo->query("SELECT SUM(CASE WHEN status='complete' THEN 1 ELSE 0 END) as completes_total, SUM(CASE WHEN status='complete' AND quality_flag='valid' THEN 1 ELSE 0 END) as completes_valid, SUM(CASE WHEN status='sent' THEN 1 ELSE 0 END) as sent_cnt, SUM(CASE WHEN status IN ('earlyscreenout','latescreenout') THEN 1 ELSE 0 END) as so_cnt, AVG(CASE WHEN status='complete' AND quality_flag='valid' AND actual_loi_seconds IS NOT NULL THEN actual_loi_seconds END) as avg_loi_sec FROM survey_urls"); $row = $stmt->fetch(); if ($row) { $kpi['completes_total'] = (int)$row['completes_total']; $kpi['completes_valid'] = (int)$row['completes_valid']; $kpi['urls_sent_total'] = (int)$row['sent_cnt']; $kpi['urls_screenout_total'] = (int)$row['so_cnt']; $kpi['avg_actual_loi_min'] = round((float)($row['avg_loi_sec'] ?? 0) / 60, 1); } } catch (Exception $e) { /* */ } try { $stmt = $pdo->query("SELECT currency, SUM(total_amount) as amt FROM invoices GROUP BY currency"); foreach ($stmt->fetchAll() as $r) { $rate = $forexRates[$r['currency'] ?? 'INR'] ?? 1.0; $kpi['revenue_inr'] += (float)$r['amt'] * $rate; } } catch (Exception $e) { /* */ } } // ===== Build WHERE for filtered list ===== $where = ['1=1']; $params = []; if ($f_status !== '') { $where[] = "p.status = ?"; $params[] = $f_status; } if ($f_client > 0) { $where[] = "p.client_id = ?"; $params[] = $f_client; } if ($f_search !== '') { $where[] = "(p.project_id LIKE ? OR p.project_name LIKE ? OR p.client_reference LIKE ?)"; $params[] = '%'.$f_search.'%'; $params[] = '%'.$f_search.'%'; $params[] = '%'.$f_search.'%'; } switch ($f_sort) { case 'newest': $orderBy = 'p.created_at DESC'; break; case 'oldest': $orderBy = 'p.created_at ASC'; break; case 'sample': $orderBy = 'p.sample_size DESC'; break; case 'completes': $orderBy = 'urls_valid DESC'; break; case 'name': $orderBy = 'p.project_name ASC'; break; case 'client': $orderBy = 'c.company_name ASC, p.created_at DESC'; break; default: $orderBy = 'p.updated_at DESC'; // 'recent' } // ===== Fetch project list ===== $projects = []; if ($pdo) { try { $sql = " SELECT p.*, c.company_name as client_name, c.country as client_country, c.currency as client_currency, (SELECT COUNT(*) FROM project_selections WHERE project_id = p.id) as selections_count, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id) as urls_total, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status='available') as urls_available, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status='sent') as urls_sent, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status='complete') as urls_complete, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status='complete' AND quality_flag='valid') as urls_valid, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status IN ('earlyscreenout','latescreenout')) as urls_screenout, (SELECT COUNT(*) FROM survey_urls WHERE project_id = p.project_id AND status='quotafull') as urls_quotafull, (SELECT AVG(actual_loi_seconds) FROM survey_urls WHERE project_id = p.project_id AND status='complete' AND quality_flag='valid' AND actual_loi_seconds IS NOT NULL) as avg_loi_seconds, (SELECT SUM(total_amount) FROM invoices WHERE project_id = p.id) as invoice_total, (SELECT currency FROM invoices WHERE project_id = p.id LIMIT 1) as invoice_currency, (SELECT status FROM invoices WHERE project_id = p.id LIMIT 1) as invoice_status FROM projects p LEFT JOIN clients c ON p.client_id = c.id WHERE ".implode(' AND ', $where)." ORDER BY $orderBy "; $stmt = $pdo->prepare($sql); $stmt->execute($params); $projects = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("Projects fetch error: ".$e->getMessage()); } } // Client dropdown $clients_dd = []; if ($pdo) { try { $stmt = $pdo->query("SELECT id, company_name FROM clients ORDER BY company_name ASC"); $clients_dd = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { /* */ } } // Helpers if (!function_exists('fmtIST')) { function fmtIST($dt, $fmt = 'd M Y, h:i A') { if (!$dt || $dt === '0000-00-00 00:00:00') return '—'; try { $date = new DateTime($dt, new DateTimeZone('Asia/Kolkata')); return $date->format($fmt); } catch (Exception $e) { return date($fmt, strtotime($dt)); } } } if (!function_exists('fmtINR')) { function fmtINR($v) { return '₹' . number_format((float)$v, 2); } } if (!function_exists('fmtNum')) { function fmtNum($v) { return number_format((int)$v); } } include 'includes/header.php'; ?>
All projects across all clients · live + closed + draft
| Project | Client | Industry | Country | Status | ELOI | Actual LOI | Sample Progress | Sels | URLs Funnel | Invoice | Created | Made Live | Updated | Action |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Ref:
|
min | min — |
/
%
|
Sent: ·
Cmp:
( valid)
SO: · QF: · Total: |
No invoice
|
—'; ?>
Closed: |
View →
Client |