403Webshell
Server IP : 69.72.244.102  /  Your IP : 216.73.216.164
Web Server : LiteSpeed
System : Linux s3434.fra1.stableserver.net 4.18.0-513.24.1.lve.2.el8.x86_64 #1 SMP Fri May 24 12:42:50 UTC 2024 x86_64
User : konzalta ( 1271)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/konzalta/constituency.work/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/konzalta/constituency.work//bursaries.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ConstituencyOS – Bursaries</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  --green:#1a7a4a; --green-light:#e8f5ee; --green-mid:#2d9e63;
  --red:#dc2626; --red-light:#fdecea;
  --amber:#f59e0b; --amber-light:#fffbeb;
  --blue:#2563eb; --blue-light:#eff6ff;
  --purple:#7c3aed; --purple-light:#f5f3ff;
  --text:#111827; --muted:#6b7280; --light:#9ca3af;
  --border:#e5e7eb; --bg:#f3f4f6; --white:#ffffff;
  --sidebar-w:216px; --radius:10px; --radius-sm:6px;
  --shadow:0 1px 3px rgba(0,0,0,.08);
}
html,body{height:100%;margin:0;padding:0;}
body{font-family:'Inter',sans-serif;font-size:13px;color:var(--text);background:var(--bg);}

/* ── SIDEBAR — fixed on the left ── */
.sidebar{
  position:fixed;top:0;left:0;bottom:0;width:var(--sidebar-w);
  background:var(--white);border-right:1px solid var(--border);
  display:flex;flex-direction:column;
  overflow-y:auto;overflow-x:hidden;
  z-index:40;
}
.sidebar-logo{display:flex;align-items:center;gap:9px;padding:14px 14px 12px;border-bottom:1px solid var(--border);flex-shrink:0;}
.logo-icon{width:38px;height:38px;background:linear-gradient(135deg,#b91c1c,#1a7a4a);border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:17px;flex-shrink:0;}
.logo-text strong{display:block;font-size:12.5px;font-weight:700;color:var(--green);}
.logo-text small{font-size:10px;color:var(--muted);line-height:1.3;}
.sidebar-profile{display:flex;align-items:center;gap:9px;padding:11px 14px;border-bottom:1px solid var(--border);flex-shrink:0;}
.avatar{width:36px;height:36px;border-radius:50%;background:#374151;color:white;font-weight:600;font-size:13px;display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;}
.avatar .dot{position:absolute;bottom:1px;right:1px;width:8px;height:8px;border-radius:50%;background:var(--green-mid);border:2px solid white;}
.profile-name{font-size:11.5px;font-weight:600;}.profile-sub{font-size:10.5px;color:var(--muted);}
.sidebar-nav{flex:1;padding:6px 0;}
.nav-item{display:flex;align-items:center;gap:9px;padding:8px 14px;font-size:12px;font-weight:500;color:var(--muted);cursor:pointer;position:relative;transition:background .12s,color .12s;white-space:nowrap;}
.nav-item:hover{background:var(--bg);color:var(--text);}
.nav-item.active{background:var(--green-light);color:var(--green);font-weight:600;}
.nav-item.active::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--green);border-radius:0 2px 2px 0;}
.nav-icon{font-size:14px;width:16px;text-align:center;flex-shrink:0;}
.nav-badge{margin-left:auto;background:var(--red);color:white;font-size:9.5px;font-weight:700;padding:1px 5px;border-radius:10px;}
.nav-new{margin-left:auto;background:var(--green);color:white;font-size:9px;font-weight:700;padding:2px 5px;border-radius:4px;}
.nav-chevron{margin-left:auto;font-size:10px;color:var(--light);}
.sidebar-footer{padding:12px 14px;border-top:1px solid var(--border);flex-shrink:0;}
.help-row{display:flex;align-items:center;gap:9px;cursor:pointer;}
.help-label{font-size:11.5px;font-weight:600;}.help-sub{font-size:10.5px;color:var(--muted);}

/* ── RIGHT PANEL — offset by sidebar width ── */
.right-panel{margin-left:var(--sidebar-w);display:flex;flex-direction:column;min-height:100vh;}

/* ── TOPBAR — sticky at top of right panel ── */
.topbar{
  position:sticky;top:0;z-index:30;
  height:52px;background:var(--white);border-bottom:1px solid var(--border);
  display:flex;align-items:center;gap:10px;padding:0 18px;
}
.menu-btn{font-size:17px;cursor:pointer;color:var(--muted);}
.const-selector{display:flex;align-items:center;gap:6px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:5px 10px;cursor:pointer;font-size:12px;font-weight:500;}
.search-top{flex:1;max-width:360px;display:flex;align-items:center;gap:7px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 11px;color:var(--muted);font-size:12px;}
.search-top input{border:none;background:transparent;outline:none;width:100%;font-size:12px;font-family:inherit;}
.search-top kbd{margin-left:auto;font-size:9.5px;background:var(--border);padding:1px 5px;border-radius:3px;font-family:inherit;}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:8px;}
.icon-btn{position:relative;width:32px;height:32px;border-radius:50%;background:var(--bg);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;}
.icon-btn .bdg{position:absolute;top:-3px;right:-3px;background:var(--red);color:white;font-size:9px;font-weight:700;width:15px;height:15px;border-radius:50%;display:flex;align-items:center;justify-content:center;border:1.5px solid white;}
.icon-btn .bdg.grn{background:var(--green-mid);}
.user-pill{display:flex;align-items:center;gap:7px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:3px 8px;cursor:pointer;font-size:12px;font-weight:500;}

/* ── CONTENT — just a normal flow div, page scroll handles the rest ── */
.content{padding:18px 18px 40px;display:flex;flex-direction:column;gap:14px;}
.btn{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:var(--radius-sm);font-size:12px;font-weight:600;cursor:pointer;border:none;transition:background .15s;}
.btn-primary{background:var(--green);color:white;}.btn-primary:hover{background:var(--green-mid);}
.btn-ghost{background:var(--white);color:var(--text);border:1px solid var(--border);}.btn-ghost:hover{background:var(--bg);}
.btn-sm{padding:5px 10px;font-size:11px;}
.page-header{display:flex;align-items:flex-start;justify-content:space-between;}
.page-title{font-size:19px;font-weight:700;}
.page-sub{font-size:12px;color:var(--muted);margin-top:2px;}

/* ── TOP METRICS ── */
.metrics-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;}
.metric-card{background:var(--white);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;}
.metric-icon{font-size:22px;margin-bottom:6px;}
.metric-val{font-size:26px;font-weight:700;line-height:1;}
.metric-lbl{font-size:11px;color:var(--muted);margin-top:3px;}
.metric-sub{font-size:10.5px;margin-top:4px;display:flex;align-items:center;gap:4px;}
.metric-sub.up{color:#16a34a;} .metric-sub.warn{color:var(--red);}

/* ── BUDGET BAR ── */
.budget-card{background:var(--white);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;}
.budget-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;}
.budget-title{font-size:13px;font-weight:600;}
.budget-amounts{display:flex;gap:24px;margin-bottom:10px;}
.ba-item{font-size:12px;}
.ba-val{font-size:18px;font-weight:700;}
.ba-lbl{font-size:10.5px;color:var(--muted);}
.budget-bar-wrap{height:12px;background:var(--border);border-radius:12px;overflow:hidden;margin-bottom:8px;}
.budget-bar-fill{height:100%;border-radius:12px;}
.budget-legend{display:flex;gap:16px;font-size:10.5px;color:var(--muted);}
.bl-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:4px;}
.ward-breakdown{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-top:14px;}
.ward-bar-item{text-align:center;}
.ward-bar-track{height:60px;background:var(--bg);border-radius:4px;position:relative;overflow:hidden;}
.ward-bar-fill{width:100%;position:absolute;bottom:0;left:0;right:0;border-radius:4px 4px 0 0;}
.ward-bar-used{background:var(--green);}
.ward-lbl{font-size:9.5px;color:var(--muted);margin-top:4px;line-height:1.3;}
.ward-pct{font-size:10px;font-weight:700;color:var(--green);}

/* ── TOOLBAR ── */
.toolbar{display:flex;align-items:center;gap:10px;background:var(--white);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px;}
.search-bar{flex:1;display:flex;align-items:center;gap:7px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 10px;}
.search-bar input{border:none;background:transparent;outline:none;width:100%;font-size:12px;font-family:inherit;color:var(--text);}
.fsel{display:flex;align-items:center;gap:5px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 10px;font-size:12px;}
.fsel select{border:none;background:transparent;outline:none;font-size:12px;font-family:inherit;color:var(--text);cursor:pointer;}

/* ── STATUS TABS ── */
.status-tabs{display:flex;gap:0;background:var(--white);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;}
.stab{flex:1;padding:10px 14px;text-align:center;cursor:pointer;font-size:12px;font-weight:500;color:var(--muted);border-right:1px solid var(--border);transition:background .15s;}
.stab:last-child{border-right:none;}
.stab:hover{background:var(--bg);}
.stab.active{background:var(--green-light);color:var(--green);font-weight:700;}
.stab-count{font-size:18px;font-weight:700;display:block;line-height:1.1;}
.stab-lbl{font-size:10.5px;margin-top:2px;}

/* ── TABLE ── */
.table-card{background:var(--white);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;}
.table-wrap{overflow-x:auto;}
table{width:100%;border-collapse:collapse;}
thead tr{background:var(--bg);border-bottom:1px solid var(--border);}
th{padding:9px 14px;font-size:11px;font-weight:600;color:var(--muted);text-align:left;white-space:nowrap;cursor:pointer;user-select:none;}
th:hover{color:var(--text);}
tbody tr{border-bottom:1px solid var(--border);transition:background .1s;cursor:pointer;}
tbody tr:last-child{border-bottom:none;}
tbody tr:hover{background:#f9fafb;}
td{padding:10px 14px;font-size:12px;vertical-align:middle;}
.stag{display:inline-flex;align-items:center;gap:4px;font-size:10px;font-weight:600;padding:3px 8px;border-radius:20px;white-space:nowrap;}
.stag.approved{background:#ecfdf5;color:#065f46;}
.stag.review{background:#fffbeb;color:#b45309;}
.stag.rejected{background:#fdecea;color:#b91c1c;}
.stag.disbursed{background:#eff6ff;color:#1d4ed8;}
.cb{display:flex;gap:4px;opacity:0;transition:opacity .15s;}
tbody tr:hover .cb{opacity:1;}
.cab{padding:4px 8px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--white);font-size:10.5px;font-weight:600;cursor:pointer;white-space:nowrap;}
.cab.approve{color:var(--green);border-color:#bbf7d0;background:#f0fdf4;}
.cab.approve:hover{background:#dcfce7;}
.cab.reject{color:var(--red);border-color:#fecaca;background:#fef2f2;}
.cab.reject:hover{background:#fdecea;}

/* ── PAGINATION ── */
.pagination{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-top:1px solid var(--border);}
.pg-info{font-size:11.5px;color:var(--muted);}
.pg-btns{display:flex;gap:4px;}
.pg-btn{width:28px;height:28px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--white);display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;font-weight:500;}
.pg-btn.active{background:var(--green);color:white;border-color:var(--green);}
.pg-btn:hover:not(.active){background:var(--bg);}

/* ── DETAIL PANEL ── */
.detail-overlay{position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:100;display:none;align-items:flex-start;justify-content:flex-end;}
.detail-overlay.open{display:flex;}
.detail-panel{width:440px;height:100%;background:var(--white);box-shadow:-4px 0 24px rgba(0,0,0,.12);display:flex;flex-direction:column;overflow:hidden;}
.dp-header{padding:16px 18px;border-bottom:1px solid var(--border);flex-shrink:0;}
.dp-hdr-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.dp-close{width:28px;height:28px;border-radius:50%;background:var(--bg);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;}
.dp-title{font-size:15px;font-weight:700;}
.dp-body{flex:1;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:16px;}
.dp-sect-title{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;}
.dp-row{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px solid var(--border);font-size:12px;}
.dp-row:last-child{border-bottom:none;}
.dp-key{color:var(--muted);}.dp-val{font-weight:500;text-align:right;}
.score-bar{height:8px;background:var(--border);border-radius:8px;overflow:hidden;margin:6px 0;}
.score-fill{height:100%;border-radius:8px;}
.dp-footer{padding:14px 18px;border-top:1px solid var(--border);display:flex;gap:8px;flex-shrink:0;}
.dp-footer .btn{flex:1;justify-content:center;}
.note-box{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 10px;font-size:12px;font-family:inherit;resize:none;height:60px;outline:none;color:var(--text);}
.note-box:focus{border-color:var(--green);}
.info-box{background:var(--bg);border-radius:var(--radius-sm);padding:10px 12px;font-size:12px;line-height:1.6;}
</style>
</head>
<body>

<!-- SIDEBAR -->
<aside class="sidebar">
  <div class="sidebar-logo">
    <div class="logo-icon">🏛️</div>
    <div class="logo-text"><strong>ConstituencyOS</strong><small>Everything in your constituency,<br>in one place.</small></div>
  </div>
  <div class="sidebar-profile">
    <div class="avatar">DM<div class="dot"></div></div>
    <div><div class="profile-name">Hon. David Mwangi, MP</div><div class="profile-sub">Embakasi South</div></div>
  </div>
  <nav class="sidebar-nav">
    <div class="nav-item" onclick="location.href='index.html'"><span class="nav-icon">🏠</span>Dashboard</div>
    <div class="nav-item" onclick="location.href='constituents.html'"><span class="nav-icon">👥</span>Constituents</div>
    <div class="nav-item" onclick="location.href='complaints.html'"><span class="nav-icon">📋</span>Complaints<span class="nav-badge">9</span></div>
    <div class="nav-item" onclick="location.href='projects.html'"><span class="nav-icon">📁</span>Projects</div>
    <div class="nav-item" onclick="location.href='bursaries.html'"><span class="nav-icon">🎓</span>Bursaries</div>
    <div class="nav-item" onclick="location.href='events.html'"><span class="nav-icon">📅</span>Events</div>
    <div class="nav-item" onclick="location.href='social_protection.html'"><span class="nav-icon">🛡️</span>Social Protection</div>
    <div class="nav-item" onclick="location.href='ward_management.html'"><span class="nav-icon">🏘️</span>Ward Management</div>
    <div class="nav-item" onclick="location.href='finance.html'"><span class="nav-icon">💰</span>Finance</div>
    <div class="nav-item" onclick="location.href='documents.html'"><span class="nav-icon">📄</span>Documents</div>
    <div class="nav-item" onclick="location.href='staff_management.html'"><span class="nav-icon">👤</span>Staff Management</div>
    <div class="nav-item" onclick="location.href='reports_analytics.html'"><span class="nav-icon">📊</span>Reports & Analytics</div>
    <div class="nav-item active"><span class="nav-icon">🤖</span>AI Assistant<span class="nav-new">New</span></div>
    <div class="nav-item" onclick="location.href='settings.html'"><span class="nav-icon">⚙️</span>Settings</div>
    <div class="nav-item" onclick="location.href='public_portal.html'"><span class="nav-icon">🌐</span>Public Portal</div>
  </nav>
  <div class="sidebar-footer">
    <div class="help-row"><span>❓</span><div><div class="help-label">Need Help?</div><div class="help-sub">Contact Support</div></div></div>
  </div>
</aside>

<!-- RIGHT PANEL -->
<div class="right-panel">
  <header class="topbar">
    <span class="menu-btn">☰</span>
    <div class="const-selector"><span style="font-size:13px">🏛️</span>Embakasi South Constituency<span style="font-size:10px;color:var(--muted)">▼</span></div>
    <div class="search-top"><span>🔍</span><input type="text" placeholder="Search for anything…"><kbd>⌘K</kbd></div>
    <div class="topbar-right">
      <div class="icon-btn">🔔<div class="bdg">8</div></div>
      <div class="icon-btn">✉️<div class="bdg grn">3</div></div>
      <div class="user-pill"><div class="avatar" style="width:26px;height:26px;font-size:10px">DM</div>Hon. David Mwangi<span style="font-size:10px;color:var(--muted)">▼</span></div>
    </div>
  </header>

  <main class="content">

    <!-- Page Header -->
    <div class="page-header">
      <div>
        <div class="page-title">Bursaries</div>
        <div class="page-sub">Manage bursary applications, approvals and disbursements — FY 2023/2024</div>
      </div>
      <div style="display:flex;gap:8px;">
        <button class="btn btn-ghost">⬇ Export</button>
        <button class="btn btn-ghost">📋 Batch Review</button>
        <button class="btn btn-primary">+ New Application</button>
      </div>
    </div>

    <!-- Metrics Row -->
    <div class="metrics-row">
      <div class="metric-card">
        <div class="metric-icon">📨</div>
        <div class="metric-val" id="m-total">3,248</div>
        <div class="metric-lbl">Total Applications</div>
        <div class="metric-sub up">▲ 14% vs last year</div>
      </div>
      <div class="metric-card">
        <div class="metric-icon">✅</div>
        <div class="metric-val" style="color:var(--green)" id="m-approved">1,892</div>
        <div class="metric-lbl">Approved</div>
        <div class="metric-sub up">58% approval rate</div>
      </div>
      <div class="metric-card">
        <div class="metric-icon">⏳</div>
        <div class="metric-val" style="color:var(--amber)" id="m-review">1,156</div>
        <div class="metric-lbl">Under Review</div>
        <div class="metric-sub warn">Needs attention</div>
      </div>
      <div class="metric-card">
        <div class="metric-icon">💰</div>
        <div class="metric-val" style="color:var(--blue)">KSh 42M</div>
        <div class="metric-lbl">Total Disbursed</div>
        <div class="metric-sub" style="color:var(--muted)">of KSh 55M budget</div>
      </div>
    </div>

    <!-- Budget Card -->
    <div class="budget-card">
      <div class="budget-hdr">
        <div class="budget-title">Budget Utilisation by Ward</div>
        <div style="font-size:11.5px;color:var(--muted)">FY 2023/2024 · Total: KSh 55,000,000</div>
      </div>
      <div class="budget-amounts">
        <div class="ba-item"><div class="ba-val" style="color:var(--green)">KSh 42.0M</div><div class="ba-lbl">Disbursed (76%)</div></div>
        <div class="ba-item"><div class="ba-val" style="color:var(--amber)">KSh 8.5M</div><div class="ba-lbl">Approved, Pending</div></div>
        <div class="ba-item"><div class="ba-val" style="color:var(--light)">KSh 4.5M</div><div class="ba-lbl">Remaining</div></div>
      </div>
      <div class="budget-bar-wrap">
        <div class="budget-bar-fill" style="width:76%;background:var(--green)"></div>
      </div>
      <div class="budget-legend">
        <span><span class="bl-dot" style="background:var(--green)"></span>Disbursed</span>
        <span><span class="bl-dot" style="background:var(--amber)"></span>Approved, pending</span>
        <span><span class="bl-dot" style="background:var(--border)"></span>Remaining</span>
      </div>
      <div class="ward-breakdown">
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:88%"></div></div>
          <div class="ward-lbl">Pipeline</div><div class="ward-pct">88%</div>
        </div>
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:72%"></div></div>
          <div class="ward-lbl">Imara Daima</div><div class="ward-pct">72%</div>
        </div>
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:81%"></div></div>
          <div class="ward-lbl">Mabatini</div><div class="ward-pct">81%</div>
        </div>
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:65%"></div></div>
          <div class="ward-lbl">Umoja</div><div class="ward-pct">65%</div>
        </div>
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:79%"></div></div>
          <div class="ward-lbl">Kwa Njenga</div><div class="ward-pct">79%</div>
        </div>
        <div class="ward-bar-item">
          <div class="ward-bar-track"><div class="ward-bar-fill ward-bar-used" style="height:70%"></div></div>
          <div class="ward-lbl">Mihango</div><div class="ward-pct">70%</div>
        </div>
      </div>
    </div>

    <!-- Status Tabs -->
    <div class="status-tabs">
      <div class="stab active" onclick="filterStatus('all',this)">
        <span class="stab-count" id="t-all">20</span>
        <div class="stab-lbl">All</div>
      </div>
      <div class="stab" onclick="filterStatus('Under Review',this)">
        <span class="stab-count" style="color:var(--amber)" id="t-review">0</span>
        <div class="stab-lbl">Under Review</div>
      </div>
      <div class="stab" onclick="filterStatus('Approved',this)">
        <span class="stab-count" style="color:var(--green)" id="t-approved">0</span>
        <div class="stab-lbl">Approved</div>
      </div>
      <div class="stab" onclick="filterStatus('Disbursed',this)">
        <span class="stab-count" style="color:var(--blue)" id="t-disbursed">0</span>
        <div class="stab-lbl">Disbursed</div>
      </div>
      <div class="stab" onclick="filterStatus('Rejected',this)">
        <span class="stab-count" style="color:var(--red)" id="t-rejected">0</span>
        <div class="stab-lbl">Rejected</div>
      </div>
    </div>

    <!-- Toolbar -->
    <div class="toolbar">
      <div class="search-bar"><span>🔍</span><input type="text" id="searchInput" placeholder="Search by name, ID, institution…" oninput="applyFilters()"></div>
      <div class="fsel">🏘️ <select id="wardFilter" onchange="applyFilters()">
        <option value="">All Wards</option>
        <option>Pipeline Ward</option><option>Imara Daima</option><option>Mabatini Ward</option>
        <option>Umoja Ward</option><option>Kwa Njenga Ward</option><option>Mihango Ward</option>
      </select></div>
      <div class="fsel">🎓 <select id="levelFilter" onchange="applyFilters()">
        <option value="">All Levels</option>
        <option>University</option><option>College</option><option>Secondary</option><option>Vocational</option>
      </select></div>
      <div class="fsel">📅 <select id="yearFilter" onchange="applyFilters()">
        <option value="">All Years</option><option>2024</option><option>2023</option>
      </select></div>
      <button class="btn btn-ghost btn-sm" onclick="batchApprove()">✓ Batch Approve</button>
    </div>

    <!-- Table -->
    <div class="table-card">
      <div class="table-wrap">
        <table id="bursaryTable">
          <thead><tr>
            <th><input type="checkbox" id="selectAll" onchange="toggleAll(this)"></th>
            <th onclick="sortBy('id')">App ID ↕</th>
            <th onclick="sortBy('name')">Applicant ↕</th>
            <th onclick="sortBy('ward')">Ward ↕</th>
            <th onclick="sortBy('institution')">Institution ↕</th>
            <th onclick="sortBy('level')">Level ↕</th>
            <th onclick="sortBy('amount')">Amount (KSh) ↕</th>
            <th onclick="sortBy('score')">Need Score ↕</th>
            <th onclick="sortBy('status')">Status ↕</th>
            <th onclick="sortBy('date')">Applied ↕</th>
            <th></th>
          </tr></thead>
          <tbody id="tableBody"></tbody>
        </table>
      </div>
      <div class="pagination">
        <div class="pg-info" id="pgInfo"></div>
        <div class="pg-btns" id="pgBtns"></div>
      </div>
    </div>

  </main>
</div>

<!-- DETAIL PANEL -->
<div class="detail-overlay" id="detailOverlay" onclick="closeDetail(event)">
  <div class="detail-panel">
    <div class="dp-header">
      <div class="dp-hdr-top">
        <div style="font-size:10.5px;color:var(--muted)" id="dp-id"></div>
        <div class="dp-close" onclick="closeDetailDirect()">✕</div>
      </div>
      <div class="dp-title" id="dp-name"></div>
      <div style="margin-top:6px" id="dp-status-tag"></div>
    </div>
    <div class="dp-body">

      <div>
        <div class="dp-sect-title">Applicant Details</div>
        <div class="dp-row"><span class="dp-key">ID Number</span><span class="dp-val" id="dp-idno"></span></div>
        <div class="dp-row"><span class="dp-key">Ward</span><span class="dp-val" id="dp-ward"></span></div>
        <div class="dp-row"><span class="dp-key">Phone</span><span class="dp-val" id="dp-phone"></span></div>
        <div class="dp-row"><span class="dp-key">Guardian</span><span class="dp-val" id="dp-guardian"></span></div>
        <div class="dp-row"><span class="dp-key">Date Applied</span><span class="dp-val" id="dp-date"></span></div>
      </div>

      <div>
        <div class="dp-sect-title">Academic Details</div>
        <div class="dp-row"><span class="dp-key">Institution</span><span class="dp-val" id="dp-inst"></span></div>
        <div class="dp-row"><span class="dp-key">Level</span><span class="dp-val" id="dp-level"></span></div>
        <div class="dp-row"><span class="dp-key">Course / Programme</span><span class="dp-val" id="dp-course"></span></div>
        <div class="dp-row"><span class="dp-key">Year of Study</span><span class="dp-val" id="dp-year"></span></div>
        <div class="dp-row"><span class="dp-key">Admission No.</span><span class="dp-val" id="dp-admno"></span></div>
      </div>

      <div>
        <div class="dp-sect-title">Financial Need Assessment</div>
        <div style="display:flex;justify-content:space-between;align-items:center;font-size:12px;margin-bottom:4px;">
          <span>Need Score</span><span id="dp-score-val" style="font-weight:700;font-size:16px;"></span>
        </div>
        <div class="score-bar"><div class="score-fill" id="dp-score-fill"></div></div>
        <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--muted);margin-bottom:10px;"><span>Low need</span><span>High need</span></div>
        <div class="dp-row"><span class="dp-key">Household Income</span><span class="dp-val" id="dp-income"></span></div>
        <div class="dp-row"><span class="dp-key">Dependants</span><span class="dp-val" id="dp-deps"></span></div>
        <div class="dp-row"><span class="dp-key">Amount Requested</span><span class="dp-val" id="dp-amount"></span></div>
        <div class="dp-row"><span class="dp-key">Recommended Award</span><span class="dp-val" id="dp-award" style="color:var(--green);font-weight:700;"></span></div>
      </div>

      <div>
        <div class="dp-sect-title">Review Note</div>
        <textarea class="note-box" id="dp-note" placeholder="Add a review note…"></textarea>
      </div>

    </div>
    <div class="dp-footer" id="dp-footer"></div>
  </div>
</div>

<script>
const APPLICATIONS = [
  {id:'BUR-2024-001',name:'John Kamau Njoroge',idno:'30421567',ward:'Pipeline Ward',phone:'0712 345 678',guardian:'Mary Njoroge (Mother)',institution:'Kenyatta University',level:'University',course:'Bachelor of Education',year:'Year 2',admno:'KU/2022/034521',amount:35000,score:82,status:'Under Review',date:'15 May 2024',income:'KSh 12,000/mo',deps:5},
  {id:'BUR-2024-002',name:'Amina Hassan Wario',idno:'32187654',ward:'Imara Daima',phone:'0723 456 789',guardian:'Hassan Wario (Father)',institution:'University of Nairobi',level:'University',course:'Bachelor of Medicine',year:'Year 3',admno:'UON/2021/18734',amount:50000,score:91,status:'Approved',date:'14 May 2024',income:'KSh 8,000/mo',deps:7},
  {id:'BUR-2024-003',name:'Peter Ochieng Otieno',idno:'28934512',ward:'Kwa Njenga Ward',phone:'0734 567 890',guardian:'Grace Otieno (Mother)',institution:'Technical University of Kenya',level:'University',course:'Civil Engineering',year:'Year 1',admno:'TUK/2023/09821',amount:30000,score:74,status:'Disbursed',date:'10 May 2024',income:'KSh 15,000/mo',deps:4},
  {id:'BUR-2024-004',name:'Grace Wanjiku Kamau',idno:'35621098',ward:'Mabatini Ward',phone:'0745 678 901',guardian:'James Kamau (Father)',institution:'Mombasa Technical Training Institute',level:'Vocational',course:'Electrical Installation',year:'Year 2',admno:'MTTI/2023/0441',amount:20000,score:88,status:'Approved',date:'9 May 2024',income:'KSh 7,500/mo',deps:6},
  {id:'BUR-2024-005',name:'Samuel Muthoni Kariuki',idno:'29876543',ward:'Umoja Ward',phone:'0756 789 012',guardian:'Ann Kariuki (Mother)',institution:'Alliance High School',level:'Secondary',course:'Kenya Certificate of Secondary Education',year:'Form 3',admno:'AHS/2022/1187',amount:15000,score:79,status:'Disbursed',date:'8 May 2024',income:'KSh 18,000/mo',deps:3},
  {id:'BUR-2024-006',name:'Faith Achieng Omondi',idno:'33654321',ward:'Mihango Ward',phone:'0767 890 123',guardian:'David Omondi (Father)',institution:'Strathmore University',level:'University',course:'Bachelor of Business Information Technology',year:'Year 2',admno:'STR/2023/4421',amount:45000,score:68,status:'Under Review',date:'7 May 2024',income:'KSh 22,000/mo',deps:3},
  {id:'BUR-2024-007',name:'Daniel Kipchoge Rono',idno:'31245678',ward:'Pipeline Ward',phone:'0778 901 234',guardian:'Elijah Rono (Father)',institution:'Kenya Medical Training College',level:'College',course:'Clinical Medicine',year:'Year 1',admno:'KMTC/2024/0087',amount:28000,score:85,status:'Approved',date:'6 May 2024',income:'KSh 9,000/mo',deps:5},
  {id:'BUR-2024-008',name:'Mercy Nduta Waweru',idno:'34123456',ward:'Kwa Njenga Ward',phone:'0789 012 345',guardian:'John Waweru (Father)',institution:'Jomo Kenyatta University',level:'University',course:'Bachelor of Nursing',year:'Year 3',admno:'JKUAT/2022/23411',amount:38000,score:77,status:'Rejected',date:'5 May 2024',income:'KSh 25,000/mo',deps:2},
  {id:'BUR-2024-009',name:'Kevin Otieno Adhiambo',idno:'27654321',ward:'Imara Daima',phone:'0790 123 456',guardian:'Rose Adhiambo (Mother)',institution:'Nairobi Technical Training Institute',level:'Vocational',course:'Plumbing & Pipe Fitting',year:'Year 1',admno:'NTTI/2024/0312',amount:18000,score:93,status:'Under Review',date:'4 May 2024',income:'KSh 5,000/mo',deps:8},
  {id:'BUR-2024-010',name:'Beatrice Wambua Mutua',idno:'36543210',ward:'Mabatini Ward',phone:'0701 234 567',guardian:'Joseph Mutua (Father)',institution:'Daystar University',level:'University',course:'Bachelor of Communications',year:'Year 4',admno:'DAY/2021/8821',amount:42000,score:71,status:'Disbursed',date:'3 May 2024',income:'KSh 16,000/mo',deps:4},
  {id:'BUR-2024-011',name:'James Mwangi Njeru',idno:'30987654',ward:'Umoja Ward',phone:'0712 567 890',guardian:'Alice Njeru (Mother)',institution:'University of Nairobi',level:'University',course:'Bachelor of Laws',year:'Year 2',admno:'UON/2023/31122',amount:48000,score:80,status:'Approved',date:'2 May 2024',income:'KSh 11,000/mo',deps:5},
  {id:'BUR-2024-012',name:'Lucy Chebet Kiprotich',idno:'32109876',ward:'Mihango Ward',phone:'0723 678 901',guardian:'Paul Kiprotich (Father)',institution:'Rift Valley Institute of Science & Technology',level:'College',course:'Food Technology',year:'Year 2',admno:'RVIST/2023/1654',amount:22000,score:86,status:'Under Review',date:'1 May 2024',income:'KSh 8,500/mo',deps:6},
  {id:'BUR-2024-013',name:'Paul Ndungu Mwangi',idno:'28765432',ward:'Pipeline Ward',phone:'0734 789 012',guardian:'Jane Mwangi (Mother)',institution:'Kenya Institute of Management',level:'College',course:'Diploma in Human Resource Management',year:'Year 1',admno:'KIM/2024/2211',amount:25000,score:73,status:'Rejected',date:'30 Apr 2024',income:'KSh 28,000/mo',deps:2},
  {id:'BUR-2024-014',name:'Rose Akinyi Owino',idno:'35432109',ward:'Kwa Njenga Ward',phone:'0745 890 123',guardian:'Michael Owino (Father)',institution:'Maseno University',level:'University',course:'Bachelor of Science in Agriculture',year:'Year 1',admno:'MAS/2024/4411',amount:32000,score:89,status:'Approved',date:'29 Apr 2024',income:'KSh 7,000/mo',deps:7},
  {id:'BUR-2024-015',name:'Brian Kamau Wanjiku',idno:'29543210',ward:'Imara Daima',phone:'0756 901 234',guardian:'Susan Wanjiku (Mother)',institution:'Embu University College',level:'University',course:'Bachelor of Commerce',year:'Year 3',admno:'EMB/2022/1834',amount:36000,score:76,status:'Disbursed',date:'28 Apr 2024',income:'KSh 13,000/mo',deps:4},
  {id:'BUR-2024-016',name:'Ann Chebet Kosgei',idno:'31876543',ward:'Mabatini Ward',phone:'0767 012 345',guardian:'David Kosgei (Father)',institution:'Eldoret National Polytechnic',level:'Vocational',course:'Garment Making',year:'Year 2',admno:'ENP/2023/0887',amount:16000,score:84,status:'Under Review',date:'27 Apr 2024',income:'KSh 9,500/mo',deps:5},
  {id:'BUR-2024-017',name:'Michael Oduya Ongeri',idno:'33210987',ward:'Umoja Ward',phone:'0778 123 456',guardian:'Hannah Ongeri (Mother)',institution:'Kabarak University',level:'University',course:'Bachelor of Science in ICT',year:'Year 2',admno:'KAB/2023/2211',amount:40000,score:78,status:'Approved',date:'26 Apr 2024',income:'KSh 10,000/mo',deps:5},
  {id:'BUR-2024-018',name:'Esther Wanjiru Gitau',idno:'34321098',ward:'Mihango Ward',phone:'0789 234 567',guardian:'Peter Gitau (Father)',institution:'Nyeri National Polytechnic',level:'Vocational',course:'Hairdressing & Beauty Therapy',year:'Year 1',admno:'NNP/2024/0543',amount:14000,score:90,status:'Under Review',date:'25 Apr 2024',income:'KSh 6,000/mo',deps:7},
  {id:'BUR-2024-019',name:'Vincent Mwenda Kirimi',idno:'27432109',ward:'Pipeline Ward',phone:'0790 345 678',guardian:'Mary Kirimi (Mother)',institution:'Chuka University',level:'University',course:'Bachelor of Education (Science)',year:'Year 4',admno:'CHU/2021/1122',amount:34000,score:83,status:'Disbursed',date:'24 Apr 2024',income:'KSh 10,500/mo',deps:5},
  {id:'BUR-2024-020',name:'Fatuma Omar Abdi',idno:'36210987',ward:'Kwa Njenga Ward',phone:'0701 456 789',guardian:'Omar Abdi (Father)',institution:'Kenya Coast National Polytechnic',level:'College',course:'Diploma in Catering & Hotel Management',year:'Year 2',admno:'KCNP/2023/0671',amount:24000,score:87,status:'Under Review',date:'23 Apr 2024',income:'KSh 8,000/mo',deps:6},
];

let filtered = [...APPLICATIONS];
let activeStatus = 'all';
let currentPage = 1;
const PAGE_SIZE = 10;
let sortKey = 'date';
let sortDir = -1;
let selectedIds = new Set();
let currentApp = null;

function statusTag(s){
  const cls = s==='Approved'?'approved':s==='Under Review'?'review':s==='Rejected'?'rejected':'disbursed';
  const icon = s==='Approved'?'✓':s==='Under Review'?'⏳':s==='Rejected'?'✕':'💸';
  return `<span class="stag ${cls}">${icon} ${s}</span>`;
}

function scoreColor(n){ return n>=85?'#16a34a':n>=70?'#f59e0b':'#dc2626'; }

function updateCounts(){
  const all=APPLICATIONS, total=all.length;
  document.getElementById('t-all').textContent=total;
  document.getElementById('t-review').textContent=all.filter(a=>a.status==='Under Review').length;
  document.getElementById('t-approved').textContent=all.filter(a=>a.status==='Approved').length;
  document.getElementById('t-disbursed').textContent=all.filter(a=>a.status==='Disbursed').length;
  document.getElementById('t-rejected').textContent=all.filter(a=>a.status==='Rejected').length;
  document.getElementById('m-total').textContent=total.toLocaleString();
  document.getElementById('m-approved').textContent=all.filter(a=>a.status==='Approved'||a.status==='Disbursed').length.toLocaleString();
  document.getElementById('m-review').textContent=all.filter(a=>a.status==='Under Review').length.toLocaleString();
}

function applyFilters(){
  const q=document.getElementById('searchInput').value.toLowerCase();
  const ward=document.getElementById('wardFilter').value;
  const level=document.getElementById('levelFilter').value;
  filtered=APPLICATIONS.filter(a=>{
    if(activeStatus!=='all'&&a.status!==activeStatus) return false;
    if(ward&&a.ward!==ward) return false;
    if(level&&a.level!==level) return false;
    if(q&&!`${a.id} ${a.name} ${a.institution} ${a.course}`.toLowerCase().includes(q)) return false;
    return true;
  });
  currentPage=1; render();
}

function filterStatus(status,el){
  activeStatus=status;
  document.querySelectorAll('.stab').forEach(s=>s.classList.remove('active'));
  el.classList.add('active'); applyFilters();
}

function sortBy(key){
  if(sortKey===key) sortDir*=-1; else{sortKey=key;sortDir=1;}
  filtered.sort((a,b)=>{ let av=a[key],bv=b[key]; return av>bv?sortDir:av<bv?-sortDir:0; });
  render();
}

function render(){
  const start=(currentPage-1)*PAGE_SIZE, end=start+PAGE_SIZE;
  const page=filtered.slice(start,end);
  document.getElementById('tableBody').innerHTML=page.map(a=>`
    <tr onclick="openDetail('${a.id}')">
      <td onclick="event.stopPropagation()"><input type="checkbox" class="row-cb" data-id="${a.id}" onchange="toggleRow(this,'${a.id}')"></td>
      <td style="font-size:11px;color:var(--muted);font-weight:600">${a.id}</td>
      <td><div style="font-weight:600">${a.name}</div><div style="font-size:10.5px;color:var(--muted)">${a.ward}</div></td>
      <td style="font-size:11.5px">${a.ward}</td>
      <td><div style="font-size:11.5px;font-weight:500">${a.institution}</div><div style="font-size:10px;color:var(--muted)">${a.course}</div></td>
      <td style="font-size:11.5px">${a.level}</td>
      <td style="font-weight:600">${(a.amount).toLocaleString()}</td>
      <td>
        <div style="display:flex;align-items:center;gap:6px">
          <div style="flex:1;height:5px;background:var(--border);border-radius:5px;min-width:40px">
            <div style="height:100%;border-radius:5px;background:${scoreColor(a.score)};width:${a.score}%"></div>
          </div>
          <span style="font-size:11px;font-weight:700;color:${scoreColor(a.score)}">${a.score}</span>
        </div>
      </td>
      <td>${statusTag(a.status)}</td>
      <td style="font-size:11px;color:var(--muted)">${a.date}</td>
      <td><div class="cb">
        ${a.status==='Under Review'?`
          <span class="cab approve" onclick="event.stopPropagation();quickApprove('${a.id}')">✓ Approve</span>
          <span class="cab reject" onclick="event.stopPropagation();quickReject('${a.id}')">✕</span>
        `:''}
      </div></td>
    </tr>
  `).join('');

  const total=filtered.length,pages=Math.ceil(total/PAGE_SIZE);
  document.getElementById('pgInfo').textContent=`Showing ${Math.min(start+1,total)}–${Math.min(end,total)} of ${total}`;
  const pb=document.getElementById('pgBtns'); pb.innerHTML='';
  const addBtn=(l,p,a)=>{const d=document.createElement('div');d.className='pg-btn'+(a?' active':'');d.textContent=l;d.onclick=()=>{currentPage=p;render();};pb.appendChild(d);};
  if(currentPage>1) addBtn('‹',currentPage-1,false);
  for(let i=1;i<=Math.min(pages,7);i++) addBtn(i,i,i===currentPage);
  if(currentPage<pages) addBtn('›',currentPage+1,false);
}

function openDetail(id){
  currentApp=APPLICATIONS.find(a=>a.id===id);
  const a=currentApp;
  document.getElementById('dp-id').textContent=a.id;
  document.getElementById('dp-name').textContent=a.name;
  document.getElementById('dp-status-tag').innerHTML=statusTag(a.status);
  document.getElementById('dp-idno').textContent=a.idno;
  document.getElementById('dp-ward').textContent=a.ward;
  document.getElementById('dp-phone').textContent=a.phone;
  document.getElementById('dp-guardian').textContent=a.guardian;
  document.getElementById('dp-date').textContent=a.date;
  document.getElementById('dp-inst').textContent=a.institution;
  document.getElementById('dp-level').textContent=a.level;
  document.getElementById('dp-course').textContent=a.course;
  document.getElementById('dp-year').textContent=a.year;
  document.getElementById('dp-admno').textContent=a.admno;
  document.getElementById('dp-score-val').textContent=a.score+'/100';
  document.getElementById('dp-score-val').style.color=scoreColor(a.score);
  document.getElementById('dp-score-fill').style.cssText=`width:${a.score}%;background:${scoreColor(a.score)}`;
  document.getElementById('dp-income').textContent=a.income;
  document.getElementById('dp-deps').textContent=a.deps+' dependants';
  document.getElementById('dp-amount').textContent='KSh '+a.amount.toLocaleString();
  const award=Math.round(a.amount*(a.score/100));
  document.getElementById('dp-award').textContent='KSh '+award.toLocaleString();

  const footer=document.getElementById('dp-footer');
  if(a.status==='Under Review'){
    footer.innerHTML=`
      <button class="btn btn-ghost" style="flex:1;justify-content:center;color:var(--red);border-color:#fecaca;" onclick="quickReject('${a.id}');closeDetailDirect()">✕ Reject</button>
      <button class="btn btn-primary" style="flex:1;justify-content:center;" onclick="quickApprove('${a.id}');closeDetailDirect()">✓ Approve</button>`;
  } else {
    footer.innerHTML=`<button class="btn btn-ghost" style="flex:1;justify-content:center;" onclick="closeDetailDirect()">Close</button>`;
  }
  document.getElementById('detailOverlay').classList.add('open');
}

function closeDetail(e){if(e.target===document.getElementById('detailOverlay'))closeDetailDirect();}
function closeDetailDirect(){document.getElementById('detailOverlay').classList.remove('open');}

function quickApprove(id){
  const a=APPLICATIONS.find(x=>x.id===id);
  if(a){a.status='Approved';updateCounts();applyFilters();}
}
function quickReject(id){
  const a=APPLICATIONS.find(x=>x.id===id);
  if(a){a.status='Rejected';updateCounts();applyFilters();}
}
function batchApprove(){
  let count=0;
  selectedIds.forEach(id=>{
    const a=APPLICATIONS.find(x=>x.id===id);
    if(a&&a.status==='Under Review'){a.status='Approved';count++;}
  });
  selectedIds.clear();
  document.getElementById('selectAll').checked=false;
  updateCounts();applyFilters();
  if(count>0) alert(`${count} application(s) approved.`);
  else alert('Select "Under Review" applications to batch approve.');
}
function toggleAll(cb){
  const boxes=document.querySelectorAll('.row-cb');
  boxes.forEach(b=>{b.checked=cb.checked;const id=b.dataset.id;if(cb.checked)selectedIds.add(id);else selectedIds.delete(id);});
}
function toggleRow(cb,id){if(cb.checked)selectedIds.add(id);else selectedIds.delete(id);}

updateCounts();
applyFilters();
</script>
</body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit