10 30 1
This commit is contained in:
parent
17238c8890
commit
9a4b6fd7bc
@ -10,61 +10,54 @@ if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
|
|||||||
|
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
// -- Analytics & Alerts --
|
|
||||||
$total_residents = $pdo->query("SELECT count(*) FROM residents")->fetchColumn();
|
|
||||||
$active_residents = $pdo->query("SELECT count(*) FROM residents WHERE status = 'Active'")->fetchColumn();
|
|
||||||
$high_risk_residents = $pdo->query("SELECT count(*) FROM residents WHERE risk_level = 'High'")->fetchColumn();
|
|
||||||
|
|
||||||
$high_risk_alert_stmt = $pdo->query("SELECT id, first_name, last_name, program FROM residents WHERE risk_level = 'High' ORDER BY last_name, first_name LIMIT 5");
|
|
||||||
$high_risk_alerts = $high_risk_alert_stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
// -- Fetch Domains --
|
// -- Fetch Domains --
|
||||||
$domain_stmt = $pdo->query("SELECT * FROM domains ORDER BY id");
|
$domains = [
|
||||||
$domains = $domain_stmt->fetchAll(PDO::FETCH_ASSOC);
|
['id' => 'economic', 'name' => 'Economic Stability'],
|
||||||
|
['id' => 'education', 'name' => 'Education Access & Quality'],
|
||||||
|
['id' => 'healthcare', 'name' => 'Health Care Access & Quality'],
|
||||||
|
['id' => 'neighborhood', 'name' => 'Neighborhood & Built Environment'],
|
||||||
|
['id' => 'social', 'name' => 'Social & Community Context'],
|
||||||
|
];
|
||||||
|
|
||||||
// -- Get active domain --
|
// -- Get active domain --
|
||||||
$active_domain_id = $_GET['domain_id'] ?? $domains[0]['id'] ?? 1;
|
$active_domain_id = $_GET['domain'] ?? 'economic';
|
||||||
|
$active_domain_name = '';
|
||||||
// -- Filtering --
|
foreach ($domains as $domain) {
|
||||||
$program_filter = $_GET['program'] ?? '';
|
if ($domain['id'] === $active_domain_id) {
|
||||||
$risk_filter = $_GET['risk_level'] ?? '';
|
$active_domain_name = $domain['name'];
|
||||||
$status_filter = $_GET['status'] ?? '';
|
break;
|
||||||
|
|
||||||
$base_sql = "SELECT r.id, r.first_name, r.last_name, r.status, r.program, r.risk_level, COALESCE(rdp.progress, 0) as progress
|
|
||||||
FROM residents r
|
|
||||||
LEFT JOIN resident_domain_progress rdp ON r.id = rdp.resident_id AND rdp.domain_id = ?";
|
|
||||||
|
|
||||||
$params = [$active_domain_id];
|
|
||||||
$where_clauses = [];
|
|
||||||
|
|
||||||
if ($program_filter) {
|
|
||||||
$where_clauses[] = "r.program = ?";
|
|
||||||
$params[] = $program_filter;
|
|
||||||
}
|
}
|
||||||
if ($risk_filter) {
|
|
||||||
$where_clauses[] = "r.risk_level = ?";
|
|
||||||
$params[] = $risk_filter;
|
|
||||||
}
|
|
||||||
if ($status_filter) {
|
|
||||||
$where_clauses[] = "r.status = ?";
|
|
||||||
$params[] = $status_filter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = $base_sql;
|
// --- DATA FETCHING FOR THE ACTIVE DOMAIN ---
|
||||||
if (!empty($where_clauses)) {
|
|
||||||
$sql .= " WHERE " . implode(' AND ', $where_clauses);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql .= " ORDER BY r.last_name, r.first_name";
|
// KPI: Total Residents in this domain (placeholder)
|
||||||
|
$kpi_total_residents = $pdo->query("SELECT COUNT(DISTINCT resident_id) FROM risk_scores WHERE domain = '{$active_domain_id}'")->fetchColumn();
|
||||||
|
|
||||||
$stmt = $pdo->prepare($sql);
|
// KPI: Average Risk Score
|
||||||
$stmt->execute($params);
|
$kpi_avg_risk = $pdo->prepare("SELECT AVG(score_int) FROM risk_scores WHERE domain = ?");
|
||||||
$residents = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$kpi_avg_risk->execute([$active_domain_id]);
|
||||||
|
$kpi_avg_risk = round($kpi_avg_risk->fetchColumn() ?? 0);
|
||||||
|
|
||||||
// For filter dropdowns
|
// KPI: High-Risk Residents
|
||||||
$programs = $pdo->query("SELECT DISTINCT program FROM residents ORDER BY program")->fetchAll(PDO::FETCH_COLUMN);
|
$kpi_high_risk_count = $pdo->prepare("SELECT COUNT(*) FROM risk_scores WHERE domain = ? AND level = 'high'");
|
||||||
$risk_levels = $pdo->query("SELECT DISTINCT risk_level FROM residents ORDER BY risk_level")->fetchAll(PDO::FETCH_COLUMN);
|
$kpi_high_risk_count->execute([$active_domain_id]);
|
||||||
$statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")->fetchAll(PDO::FETCH_COLUMN);
|
$kpi_high_risk_count = $kpi_high_risk_count->fetchColumn();
|
||||||
|
|
||||||
|
// Risk & Drivers: Top Drivers (Placeholder - requires JSON processing)
|
||||||
|
$top_drivers = [
|
||||||
|
['label' => 'Inconsistent employment', 'weight' => 0.8],
|
||||||
|
['label' => 'High rent burden', 'weight' => 0.7],
|
||||||
|
['label' => 'Lack of emergency funds', 'weight' => 0.6],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Summary Table: Survey Responses
|
||||||
|
$survey_responses_stmt = $pdo->prepare("SELECT r.first_name, r.last_name, sr.question_label, sr.answer_value, sr.answered_at
|
||||||
|
FROM survey_responses sr
|
||||||
|
JOIN residents r ON sr.resident_id = r.id
|
||||||
|
WHERE sr.domain = ? ORDER BY sr.answered_at DESC LIMIT 10");
|
||||||
|
$survey_responses_stmt->execute([$active_domain_id]);
|
||||||
|
$survey_responses = $survey_responses_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -96,49 +89,18 @@ $statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="container mt-4">
|
<div class="container-fluid mt-4">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
<h1 class="h2">Continuum Control Center</h1>
|
<h1 class="h2">Continuum Control Center</h1>
|
||||||
<a href="resident_intake.php" class="btn btn-primary-custom"><i class="bi bi-plus-circle me-2"></i>New Resident</a>
|
<a href="resident_intake.php" class="btn btn-primary-custom"><i class="bi bi-plus-circle me-2"></i>New Resident</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Analytics Overview -->
|
|
||||||
<div class="row mb-4">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Total Residents</h5>
|
|
||||||
<p class="card-text fs-4"><?php echo $total_residents; ?></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card text-center">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">Active Residents</h5>
|
|
||||||
<p class="card-text fs-4"><?php echo $active_residents; ?></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<div class="card text-center text-danger">
|
|
||||||
<div class="card-body">
|
|
||||||
<h5 class="card-title">High Risk</h5>
|
|
||||||
<p class="card-text fs-4"><?php echo $high_risk_residents; ?></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<!-- Main Content: Domain Tabs -->
|
|
||||||
<div class="col-lg-8">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<ul class="nav nav-tabs card-header-tabs" id="domainTabs" role="tablist">
|
<ul class="nav nav-tabs card-header-tabs" id="domainTabs" role="tablist">
|
||||||
<?php foreach ($domains as $domain): ?>
|
<?php foreach ($domains as $domain): ?>
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
<a class="nav-link <?php echo ($domain['id'] == $active_domain_id) ? 'active' : ''; ?>" href="?domain_id=<?php echo $domain['id']; ?>" role="tab"><?php echo htmlspecialchars($domain['name']); ?></a>
|
<a class="nav-link <?php echo ($domain['id'] === $active_domain_id) ? 'active' : ''; ?>" href="?domain=<?php echo $domain['id']; ?>" role="tab"><?php echo htmlspecialchars($domain['name']); ?></a>
|
||||||
</li>
|
</li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</ul>
|
</ul>
|
||||||
@ -146,102 +108,93 @@ $statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="tab-content" id="domainTabsContent">
|
<div class="tab-content" id="domainTabsContent">
|
||||||
<div class="tab-pane fade show active" role="tabpanel">
|
<div class="tab-pane fade show active" role="tabpanel">
|
||||||
<!-- Filter Form -->
|
<h3 class="mb-4">Domain: <?php echo htmlspecialchars($active_domain_name); ?></h3>
|
||||||
<div class="d-flex justify-content-end mb-3">
|
|
||||||
<button class="btn btn-sm btn-outline-secondary me-2" type="button" data-bs-toggle="collapse" data-bs-target="#filterCollapse" aria-expanded="false" aria-controls="filterCollapse">
|
<!-- Overview Cards (KPIs) -->
|
||||||
<i class="bi bi-funnel me-1"></i> Filters
|
<div class="row mb-4">
|
||||||
</button>
|
|
||||||
<a href="#" id="export-csv-btn" class="btn btn-sm btn-outline-success">
|
|
||||||
<i class="bi bi-download me-1"></i> Export CSV
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="collapse" id="filterCollapse">
|
|
||||||
<form method="GET" action="staff_dashboard.php" class="mb-4">
|
|
||||||
<input type="hidden" name="domain_id" value="<?php echo $active_domain_id; ?>">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="program" class="form-label">Program</label>
|
<div class="card text-center">
|
||||||
<select name="program" id="program" class="form-select">
|
<div class="card-body">
|
||||||
<option value="">All</option>
|
<h5 class="card-title">Residents in Domain</h5>
|
||||||
<?php foreach ($programs as $p): ?>
|
<p class="card-text fs-4"><?php echo $kpi_total_residents; ?></p>
|
||||||
<option value="<?php echo htmlspecialchars($p); ?>" <?php echo ($program_filter === $p) ? 'selected' : ''; ?>><?php echo htmlspecialchars($p); ?></option>
|
</div>
|
||||||
<?php endforeach; ?>
|
</div>
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="risk_level" class="form-label">Risk Level</label>
|
<div class="card text-center">
|
||||||
<select name="risk_level" id="risk_level" class="form-select">
|
<div class="card-body">
|
||||||
<option value="">All</option>
|
<h5 class="card-title">Avg. Risk Score</h5>
|
||||||
<?php foreach ($risk_levels as $r): ?>
|
<p class="card-text fs-4"><?php echo $kpi_avg_risk; ?>%</p>
|
||||||
<option value="<?php echo htmlspecialchars($r); ?>" <?php echo ($risk_filter === $r) ? 'selected' : ''; ?>><?php echo htmlspecialchars($r); ?></option>
|
</div>
|
||||||
<?php endforeach; ?>
|
</div>
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="status" class="form-label">Status</label>
|
<div class="card text-center text-danger">
|
||||||
<select name="status" id="status" class="form-select">
|
<div class="card-body">
|
||||||
<option value="">All</option>
|
<h5 class="card-title">High-Risk</h5>
|
||||||
<?php foreach ($statuses as $s): ?>
|
<p class="card-text fs-4"><?php echo $kpi_high_risk_count; ?></p>
|
||||||
<option value="<?php echo htmlspecialchars($s); ?>" <?php echo ($status_filter === $s) ? 'selected' : ''; ?>><?php echo htmlspecialchars($s); ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-end">
|
|
||||||
<a href="staff_dashboard.php?domain_id=<?php echo $active_domain_id; ?>" class="btn btn-secondary">Reset</a>
|
|
||||||
<button type="submit" class="btn btn-primary-custom">Filter</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Left Column: Risk/Drivers & Actions -->
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header">Risk & Drivers</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">Top Risk Drivers</h5>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<?php foreach ($top_drivers as $driver): ?>
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<?php echo htmlspecialchars($driver['label']); ?>
|
||||||
|
<span class="badge bg-danger rounded-pill"><?php echo ($driver['weight'] * 100); ?>%</span>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Actions</div>
|
||||||
|
<div class="list-group list-group-flush">
|
||||||
|
<a href="#" class="list-group-item list-group-item-action"><i class="bi bi-ui-checks me-2"></i>Launch Follow-Up Survey</a>
|
||||||
|
<a href="create_referral.php" class="list-group-item list-group-item-action"><i class="bi bi-send me-2"></i>Create Referral</a>
|
||||||
|
<a href="add_case_note.php" class="list-group-item list-group-item-action"><i class="bi bi-journal-plus me-2"></i>Add Note</a>
|
||||||
|
<a href="#" class="list-group-item list-group-item-action"><i class="bi bi-check2-square me-2"></i>New Task</a>
|
||||||
|
<a href="#" class="list-group-item list-group-item-action text-success"><i class="bi bi-download me-2"></i>Export Domain Data (CSV)</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Column: Timeline & Summary Tables -->
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header">Domain Timeline</div>
|
||||||
|
<div class="card-body" style="height: 200px; overflow-y: auto;">
|
||||||
|
<p class="text-muted">[Placeholder for chronological stream of events: survey responses, notes, referrals, etc.]</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Summary: Survey Responses</div>
|
||||||
|
<div class="card-body">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-hover">
|
<table class="table table-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr><th>Resident</th><th>Question</th><th>Answer</th><th>Date</th></tr>
|
||||||
<th>Name</th>
|
|
||||||
<th>Program</th>
|
|
||||||
<th>Risk Level</th>
|
|
||||||
<th>Progress</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if (!empty($residents)): ?>
|
<?php if (!empty($survey_responses)): ?>
|
||||||
<?php foreach ($residents as $resident): ?>
|
<?php foreach ($survey_responses as $resp): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></td>
|
<td><?php echo htmlspecialchars($resp['first_name'] . ' ' . $resp['last_name']); ?></td>
|
||||||
<td><?php echo htmlspecialchars($resident['program']); ?></td>
|
<td><?php echo htmlspecialchars($resp['question_label']); ?></td>
|
||||||
<td>
|
<td><?php echo htmlspecialchars($resp['answer_value']); ?></td>
|
||||||
<?php
|
<td><?php echo date('M j, Y', strtotime($resp['answered_at'])); ?></td>
|
||||||
$risk_color = 'secondary';
|
|
||||||
if ($resident['risk_level'] === 'High') $risk_color = 'danger';
|
|
||||||
if ($resident['risk_level'] === 'Medium') $risk_color = 'warning';
|
|
||||||
?>
|
|
||||||
<span class="badge bg-<?php echo $risk_color; ?>"><?php echo htmlspecialchars($resident['risk_level']); ?></span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="progress" style="height: 20px;">
|
|
||||||
<div class="progress-bar" role="progressbar" style="width: <?php echo $resident['progress']; ?>%;" aria-valuenow="<?php echo $resident['progress']; ?>" aria-valuemin="0" aria-valuemax="100"><?php echo $resident['progress']; ?>%</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php
|
|
||||||
$status_color = 'primary';
|
|
||||||
if ($resident['status'] === 'Inactive') $status_color = 'secondary';
|
|
||||||
if ($resident['status'] === 'Stabilized') $status_color = 'success';
|
|
||||||
?>
|
|
||||||
<span class="badge bg-<?php echo $status_color; ?>"><?php echo htmlspecialchars($resident['status']); ?></span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="resident_view.php?id=<?php echo $resident['id']; ?>" class="btn btn-sm btn-outline-primary">View</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<tr>
|
<tr><td colspan="4" class="text-center text-muted">No survey responses for this domain yet.</td></tr>
|
||||||
<td colspan="6" class="text-center">No residents found matching your criteria.</td>
|
|
||||||
</tr>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -250,28 +203,7 @@ $statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<!-- Side Panel: AI Alerts -->
|
|
||||||
<div class="col-lg-4">
|
|
||||||
<div class="card border-danger">
|
|
||||||
<div class="card-header bg-danger text-white">
|
|
||||||
<i class="bi bi-exclamation-triangle-fill me-2"></i> High Risk Alerts
|
|
||||||
</div>
|
|
||||||
<div class="list-group list-group-flush">
|
|
||||||
<?php if (!empty($high_risk_alerts)): ?>
|
|
||||||
<?php foreach ($high_risk_alerts as $alert): ?>
|
|
||||||
<a href="resident_view.php?id=<?php echo $alert['id']; ?>" class="list-group-item list-group-item-action">
|
|
||||||
<div class="d-flex w-100 justify-content-between">
|
|
||||||
<h6 class="mb-1"><?php echo htmlspecialchars($alert['first_name'] . ' ' . $alert['last_name']); ?></h6>
|
|
||||||
</div>
|
|
||||||
<small class="text-muted"><?php echo htmlspecialchars($alert['program']); ?></small>
|
|
||||||
</a>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<?php else: ?>
|
|
||||||
<div class="list-group-item">
|
|
||||||
<p class="mb-0 text-center text-muted">No high risk residents found.</p>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -279,23 +211,5 @@ $statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script>
|
|
||||||
document.getElementById('export-csv-btn').addEventListener('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const program = document.getElementById('program').value;
|
|
||||||
const riskLevel = document.getElementById('risk_level').value;
|
|
||||||
const status = document.getElementById('status').value;
|
|
||||||
const domainId = new URLSearchParams(window.location.search).get('domain_id') || '<?php echo $domains[0]['id'] ?? 1; ?>';
|
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
if (program) params.append('program', program);
|
|
||||||
if (riskLevel) params.append('risk_level', riskLevel);
|
|
||||||
if (status) params.append('status', status);
|
|
||||||
params.append('domain_id', domainId);
|
|
||||||
|
|
||||||
const url = 'export_residents.php?' + params.toString();
|
|
||||||
window.location.href = url;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user