Auto commit: 2025-10-30T00:12:08.183Z

This commit is contained in:
Flatlogic Bot 2025-10-30 00:12:08 +00:00
parent c5ae495f9e
commit 0f55e9d0b9
18 changed files with 1528 additions and 119 deletions

40
add_case_note.php Normal file
View File

@ -0,0 +1,40 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: staff_dashboard.php');
exit;
}
// Check if user is logged in and has the 'staff' role
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
// You can redirect to a generic error page or the login page
header('HTTP/1.1 403 Forbidden');
exit("Access denied.");
}
$resident_id = isset($_POST['resident_id']) ? (int)$_POST['resident_id'] : 0;
$note = isset($_POST['note']) ? trim($_POST['note']) : '';
if ($resident_id === 0 || empty($note)) {
// Basic validation failed
// Redirect back with an error message (optional)
header("Location: resident_view.php?id={$resident_id}&error=empty_note");
exit;
}
try {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO case_notes (resident_id, note) VALUES (?, ?)");
$stmt->execute([$resident_id, $note]);
// Redirect back to the resident's view page after successful insertion
header("Location: resident_view.php?id={$resident_id}&success=note_added");
exit;
} catch (PDOException $e) {
// In a real app, log this error.
// For simplicity, redirect with a generic error.
header("Location: resident_view.php?id={$resident_id}&error=db_error");
exit;
}

68
compose_message.php Normal file
View File

@ -0,0 +1,68 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || !in_array($_SESSION['user_role'], ['partner', 'staff'])) {
header("Location: index.php");
exit;
}
$pdo = db();
// Fetch staff users to populate the 'To' dropdown
$stmt = $pdo->query("SELECT id, email FROM users WHERE role = 'staff' ORDER BY email");
$staff_users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Compose Message - Continuum of Healing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Continuum of Healing</a>
<a href="logout.php" class="btn btn-outline-light">Logout</a>
</div>
</nav>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Compose New Message</h1>
<a href="partner_dashboard.php" class="btn btn-secondary"> Back to Dashboard</a>
</div>
<div class="card">
<div class="card-body">
<form action="send_message.php" method="POST">
<div class="mb-3">
<label for="recipient" class="form-label">To</label>
<select name="recipient_user_id" id="recipient" class="form-select" required>
<option value="">Select a staff member...</option>
<?php foreach ($staff_users as $staff): ?>
<option value="<?php echo $staff['id']; ?>"><?php echo htmlspecialchars($staff['email']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="subject" class="form-label">Subject</label>
<input type="text" name="subject" id="subject" class="form-control" required>
</div>
<div class="mb-3">
<label for="body" class="form-label">Message</label>
<textarea name="body" id="body" class="form-control" rows="8" required></textarea>
</div>
<button type="submit" class="btn btn-primary-custom">Send Message</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

82
create_referral.php Normal file
View File

@ -0,0 +1,82 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
header("Location: index.php");
exit;
}
$resident_id = isset($_GET['resident_id']) ? (int)$_GET['resident_id'] : 0;
if ($resident_id === 0) {
header("Location: staff_dashboard.php");
exit;
}
$pdo = db();
// Fetch resident details
$stmt = $pdo->prepare("SELECT * FROM residents WHERE id = ?");
$stmt->execute([$resident_id]);
$resident = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$resident) {
header("Location: staff_dashboard.php");
exit;
}
// Fetch partners for the dropdown
$stmt = $pdo->query("SELECT id, name FROM partners ORDER BY name");
$partners = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Referral - Continuum of Healing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="staff_dashboard.php">Continuum of Healing</a>
<a href="logout.php" class="btn btn-outline-light">Logout</a>
</div>
</nav>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">New Referral for <?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></h1>
<a href="resident_view.php?id=<?php echo $resident_id; ?>" class="btn btn-secondary"> Back to Resident</a>
</div>
<div class="card">
<div class="card-body">
<form action="submit_referral.php" method="POST">
<input type="hidden" name="resident_id" value="<?php echo $resident_id; ?>">
<input type="hidden" name="staff_id" value="<?php echo $_SESSION['user_id']; ?>">
<div class="mb-3">
<label for="partner_id" class="form-label">Refer to Partner</label>
<select name="partner_id" id="partner_id" class="form-select" required>
<option value="">Select a partner...</option>
<?php foreach ($partners as $partner): ?>
<option value="<?php echo $partner['id']; ?>"><?php echo htmlspecialchars($partner['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="notes" class="form-label">Referral Notes</label>
<textarea name="notes" id="notes" class="form-control" rows="5" required></textarea>
</div>
<button type="submit" class="btn btn-primary-custom">Submit Referral</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/../config.php';
try {
$db = db();
// 1. Add columns to residents table
$db->exec("ALTER TABLE residents ADD COLUMN risk_level VARCHAR(255) DEFAULT 'Low'");
$db->exec("ALTER TABLE residents ADD COLUMN program VARCHAR(255) DEFAULT 'General'");
$db->exec("ALTER TABLE residents ADD COLUMN status VARCHAR(255) DEFAULT 'Active'");
// 2. Create case_notes table
$db->exec("
CREATE TABLE IF NOT EXISTS case_notes (
id INT AUTO_INCREMENT PRIMARY KEY,
resident_id INT NOT NULL,
note TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (resident_id) REFERENCES residents(id) ON DELETE CASCADE
)
");
// 3. Populate with some data
$stmt = $db->query("SELECT id FROM residents");
$resident_ids = $stmt->fetchAll(PDO::FETCH_COLUMN);
if ($resident_ids) {
$programs = ['Housing', 'Health', 'Employment'];
$risks = ['Low', 'Medium', 'High'];
$statuses = ['Active', 'Inactive', 'Stabilized'];
foreach ($resident_ids as $id) {
$program = $programs[array_rand($programs)];
$risk = $risks[array_rand($risks)];
$status = $statuses[array_rand($statuses)];
$db->prepare("UPDATE residents SET program = ?, risk_level = ?, status = ? WHERE id = ?")->execute([$program, $risk, $status, $id]);
// Add a case note
$db->prepare("INSERT INTO case_notes (resident_id, note) VALUES (?, ?)")->execute([$id, 'Initial intake assessment completed.']);
}
}
echo "Database schema updated successfully.";
} catch (PDOException $e) {
die("Database migration failed: " . $e->getMessage());
}

View File

@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/../config.php';
try {
$db = db();
// 1. Create partners table
$db->exec("
CREATE TABLE IF NOT EXISTS partners (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
user_id INT UNIQUE
)
");
// 2. Add partner_id to residents table
$db->exec("ALTER TABLE residents ADD COLUMN partner_id INT NULL");
// 3. Create a user for a partner (if not exists)
$partner_email = 'partner@goodwill.example';
$stmt = $db->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$partner_email]);
$partner_user_id = $stmt->fetchColumn();
if (!$partner_user_id) {
$db->prepare("INSERT INTO users (email, password, role) VALUES (?, ?, ?)")->execute([$partner_email, password_hash('password123', PASSWORD_DEFAULT), 'partner']);
$partner_user_id = $db->lastInsertId();
}
// 4. Create a partner profile
$stmt = $db->prepare("SELECT id FROM partners WHERE user_id = ?");
$stmt->execute([$partner_user_id]);
$partner_id = $stmt->fetchColumn();
if (!$partner_id) {
$db->prepare("INSERT INTO partners (name, user_id) VALUES (?, ?)")->execute(['Goodwill Housing', $partner_user_id]);
$partner_id = $db->lastInsertId();
}
// 5. Assign some residents to the partner
$db->exec("UPDATE residents SET partner_id = {$partner_id} WHERE program = 'Housing'");
echo "Database schema updated successfully for partner feature.";
} catch (PDOException $e) {
die("Database migration failed: " . $e->getMessage());
}

65
download_document.php Normal file
View File

@ -0,0 +1,65 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header("HTTP/1.1 403 Forbidden");
exit("Access denied.");
}
$document_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($document_id === 0) {
header("HTTP/1.1 404 Not Found");
exit;
}
$pdo = db();
// Fetch document details
$stmt = $pdo->prepare("SELECT * FROM documents WHERE id = ?");
$stmt->execute([$document_id]);
$document = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$document) {
header("HTTP/1.1 404 Not Found");
exit;
}
// Permission check
$user_role = $_SESSION['user_role'];
$user_id = $_SESSION['user_id'];
$has_permission = false;
if ($user_role === 'staff') {
$has_permission = true;
} elseif ($user_role === 'partner') {
$stmt = $pdo->prepare("SELECT id FROM partners WHERE user_id = ?");
$stmt->execute([$user_id]);
$partner_id = $stmt->fetchColumn();
if ($partner_id && $document['partner_id'] == $partner_id) {
$has_permission = true;
}
}
if (!$has_permission) {
header("HTTP/1.1 403 Forbidden");
exit("You do not have permission to access this file.");
}
// Serve the file for download
$file_path = $document['file_path'];
if (file_exists($file_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($document['file_name']) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
} else {
header("HTTP/1.1 404 Not Found");
exit("File not found on server.");
}

77
export_residents.php Normal file
View File

@ -0,0 +1,77 @@
<?php
session_start();
require_once 'db/config.php';
// Check if user is logged in and has the 'staff' role
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
header("HTTP/1.1 403 Forbidden");
exit("Access denied.");
}
$pdo = db();
// -- Filtering (reuse logic from dashboard) --
$program_filter = $_GET['program'] ?? '';
$risk_filter = $_GET['risk_level'] ?? '';
$status_filter = $_GET['status'] ?? '';
$where_clauses = [];
$params = [];
if ($program_filter) {
$where_clauses[] = "program = ?";
$params[] = $program_filter;
}
if ($risk_filter) {
$where_clauses[] = "risk_level = ?";
$params[] = $risk_filter;
}
if ($status_filter) {
$where_clauses[] = "status = ?";
$params[] = $status_filter;
}
$sql = "SELECT * FROM residents"; // Select all columns for export
if (!empty($where_clauses)) {
$sql .= " WHERE " . implode(' AND ', $where_clauses);
}
$sql .= " ORDER BY last_name, first_name";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
// -- CSV Generation --
$filename = "continuum_residents_" . date('Y-m-d') . ".csv";
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=' . $filename);
$output = fopen('php://output', 'w');
// Add header row
fputcsv($output, [
'ID', 'First Name', 'Last Name', 'Email', 'Phone Number', 'Date of Birth',
'Program', 'Status', 'Risk Level', 'Health Progress', 'Housing Progress', 'Employment Progress', 'Created At'
]);
// Add data rows
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
fputcsv($output, [
$row['id'],
$row['first_name'],
$row['last_name'],
$row['email'],
$row['phone_number'],
$row['date_of_birth'],
$row['program'],
$row['status'],
$row['risk_level'],
$row['health_progress'],
$row['housing_progress'],
$row['employment_progress'],
$row['created_at']
]);
}
fclose($output);
exit;

118
manage_documents.php Normal file
View File

@ -0,0 +1,118 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'partner') {
header("Location: index.php");
exit;
}
$resident_id = isset($_GET['resident_id']) ? (int)$_GET['resident_id'] : 0;
if ($resident_id === 0) {
header("Location: partner_dashboard.php");
exit;
}
$pdo = db();
// Fetch resident details
$stmt = $pdo->prepare("SELECT * FROM residents WHERE id = ?");
$stmt->execute([$resident_id]);
$resident = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$resident) {
header("Location: partner_dashboard.php");
exit;
}
// Fetch documents for this resident
$stmt = $pdo->prepare("SELECT * FROM documents WHERE resident_id = ? ORDER BY uploaded_at DESC");
$stmt->execute([$resident_id]);
$documents = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Documents - <?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="partner_dashboard.php">Continuum of Healing</a>
<a href="logout.php" class="btn btn-outline-light">Logout</a>
</div>
</nav>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Manage Documents for <?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></h1>
<a href="partner_dashboard.php" class="btn btn-secondary"> Back to Dashboard</a>
</div>
<div class="row">
<div class="col-md-7">
<div class="card">
<div class="card-header">Uploaded Documents</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>File Name</th>
<th>Description</th>
<th>Uploaded On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($documents)): ?>
<tr>
<td colspan="4" class="text-center">No documents uploaded yet.</td>
</tr>
<?php else: ?>
<?php foreach ($documents as $doc): ?>
<tr>
<td><?php echo htmlspecialchars($doc['file_name']); ?></td>
<td><?php echo htmlspecialchars($doc['description']); ?></td>
<td><?php echo date("M j, Y", strtotime($doc['uploaded_at'])); ?></td>
<td>
<a href="download_document.php?id=<?php echo $doc['id']; ?>" class="btn btn-sm btn-outline-primary">Download</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-5">
<div class="card">
<div class="card-header">Upload New Document</div>
<div class="card-body">
<form action="upload_document.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="resident_id" value="<?php echo $resident_id; ?>">
<div class="mb-3">
<label for="document" class="form-label">Select File</label>
<input type="file" name="document" id="document" class="form-control" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea name="description" id="description" class="form-control" rows="3" required></textarea>
</div>
<button type="submit" class="btn btn-primary-custom">Upload File</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -8,19 +8,74 @@ if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'partner') {
}
$pdo = db();
$current_user_id = $_SESSION['user_id'];
// Get partner details
// Get partner details from user_id
$stmt = $pdo->prepare("SELECT * FROM partners WHERE user_id = ?");
$stmt->execute([$_SESSION['user_id']]);
$stmt->execute([$current_user_id]);
$partner = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$partner) {
$error_message = "Could not find a partner profile linked to your user account.";
} else {
// Get residents assigned to this partner
$stmt = $pdo->prepare("SELECT * FROM residents WHERE partner_id = ? ORDER BY last_name, first_name");
$stmt->execute([$partner['id']]);
$residents = $stmt->fetchAll(PDO::FETCH_ASSOC);
$partner_id = $partner['id'];
// -- Performance Summary --
$stmt = $pdo->prepare("SELECT COUNT(*) FROM residents WHERE partner_id = ?");
$stmt->execute([$partner_id]);
$total_assigned = $stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT COUNT(*) FROM residents WHERE partner_id = ? AND status = 'Active'");
$stmt->execute([$partner_id]);
$active_assigned = $stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT COUNT(*) FROM referrals WHERE partner_id = ?");
$stmt->execute([$partner_id]);
$total_referrals = $stmt->fetchColumn();
// -- Resident Data --
$resident_sql = "
SELECT
r.id, r.first_name, r.last_name, r.program, r.risk_level, r.status,
(SELECT COUNT(*) FROM action_plans ap WHERE ap.resident_id = r.id AND ap.status != 'Completed') as open_plans_count,
(SELECT note FROM case_notes WHERE resident_id = r.id ORDER BY created_at DESC LIMIT 1) as last_note,
(SELECT created_at FROM case_notes WHERE resident_id = r.id ORDER BY created_at DESC LIMIT 1) as last_note_date
FROM residents r
WHERE r.partner_id = ?
ORDER BY r.last_name, r.first_name
";
$resident_stmt = $pdo->prepare($resident_sql);
$resident_stmt->execute([$partner_id]);
$residents = $resident_stmt->fetchAll(PDO::FETCH_ASSOC);
// -- Referral Data --
$referral_sql = "
SELECT
ref.id, ref.referral_date, ref.status, ref.notes,
res.first_name, res.last_name,
u.email as staff_email
FROM referrals ref
JOIN residents res ON ref.resident_id = res.id
JOIN users u ON ref.staff_user_id = u.id
WHERE ref.partner_id = ?
ORDER BY ref.referral_date DESC
";
$referral_stmt = $pdo->prepare($referral_sql);
$referral_stmt->execute([$partner_id]);
$referrals = $referral_stmt->fetchAll(PDO::FETCH_ASSOC);
// -- Fetch Messages --
$message_sql = "
SELECT m.id, m.subject, m.created_at, m.read_at, u.email as sender_email
FROM messages m
JOIN users u ON m.sender_user_id = u.id
WHERE m.recipient_user_id = ?
ORDER BY m.created_at DESC
";
$message_stmt = $pdo->prepare($message_sql);
$message_stmt->execute([$current_user_id]);
$messages = $message_stmt->fetchAll(PDO::FETCH_ASSOC);
}
?>
@ -31,6 +86,7 @@ if (!$partner) {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Partner Dashboard - Continuum of Healing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
@ -54,43 +110,256 @@ if (!$partner) {
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php elseif (isset($partner)): ?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Partner Dashboard: <?php echo htmlspecialchars($partner['name']); ?></h1>
<h1 class="h2">Partner: <?php echo htmlspecialchars($partner['name']); ?></h1>
</div>
<div class="card">
<div class="card-header">Assigned Residents</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Program</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php if (empty($residents)): ?>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="residents-tab" data-bs-toggle="tab" data-bs-target="#residents" type="button" role="tab" aria-controls="residents" aria-selected="true">Assigned Residents</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="referrals-tab" data-bs-toggle="tab" data-bs-target="#referrals" type="button" role="tab" aria-controls="referrals" aria-selected="false">Referrals</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="messages-tab" data-bs-toggle="tab" data-bs-target="#messages" type="button" role="tab" aria-controls="messages" aria-selected="false">Messages</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="documents-tab" data-bs-toggle="tab" data-bs-target="#documents" type="button" role="tab" aria-controls="documents" aria-selected="false">Documents</button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<!-- Residents Tab -->
<div class="tab-pane fade show active" id="residents" role="tabpanel" aria-labelledby="residents-tab">
<div class="pt-4">
<!-- Performance Summary -->
<div class="row mb-4">
<div class="col-md-4">
<div class="card text-center h-100">
<div class="card-body">
<h5 class="card-title">Total Assigned</h5>
<p class="card-text fs-4"><?php echo $total_assigned; ?></p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center h-100">
<div class="card-body">
<h5 class="card-title">Active Residents</h5>
<p class="card-text fs-4"><?php echo $active_assigned; ?></p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center h-100">
<div class="card-body">
<h5 class="card-title">Total Referrals</h5>
<p class="card-text fs-4"><?php echo $total_referrals; ?></p>
</div>
</div>
</div>
</div>
<!-- Resident Health Cards -->
<h3 class="h4 mb-3">Assigned Resident Health Cards</h3>
<div class="row gy-4">
<?php if (empty($residents)): ?>
<div class="col-12">
<div class="alert alert-info">No residents are currently assigned to you.</div>
</div>
<?php else: ?>
<?php foreach ($residents as $resident): ?>
<div class="col-md-6 col-lg-4">
<div class="card h-100 shadow-sm">
<div class="card-header d-flex justify-content-between align-items-center bg-light">
<h5 class="mb-0 fs-6"><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></h5>
<?php
$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>
</div>
<div class="card-body">
<p class="card-text mb-2">
<strong><i class="bi bi-clipboard-check me-2"></i>Program:</strong> <?php echo htmlspecialchars($resident['program']); ?>
</p>
<p class="card-text mb-3">
<strong><i class="bi bi-activity me-2"></i>Status:</strong>
<?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>
</p>
<div class="d-flex justify-content-between align-items-center border-top pt-2">
<small class="text-muted"><i class="bi bi-card-checklist me-1"></i> Open Action Plans</small>
<span class="badge rounded-pill bg-primary-custom"><?php echo $resident['open_plans_count']; ?></span>
</div>
<h6 class="card-subtitle mb-2 mt-3 text-muted border-top pt-2"><i class="bi bi-chat-left-text me-2"></i>Last Note</h6>
<p class="card-text fst-italic small">
<?php if ($resident['last_note']): ?>
"<?php echo htmlspecialchars(substr($resident['last_note'], 0, 80)); ?>..."
<br><small class="text-muted"> on <?php echo date("M j, Y", strtotime($resident['last_note_date'])); ?></small>
<?php else: ?>
<span class="text-muted">No notes recorded yet.</span>
<?php endif; ?>
</p>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<!-- Referrals Tab -->
<div class="tab-pane fade" id="referrals" role="tabpanel" aria-labelledby="referrals-tab">
<div class="pt-4">
<h3 class="h4 mb-3">Referral Tracker</h3>
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<td colspan="3" class="text-center">No residents are currently assigned to you.</td>
<th>Date</th>
<th>Resident</th>
<th>Referred By</th>
<th>Status</th>
<th>Actions</th>
</tr>
<?php else: ?>
<?php foreach ($residents as $resident): ?>
</thead>
<tbody>
<?php if (empty($referrals)): ?>
<tr>
<td><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></td>
<td><?php echo htmlspecialchars($resident['program']); ?></td>
<td><span class="badge bg-primary"><?php echo htmlspecialchars($resident['status']); ?></span></td>
<td colspan="5" class="text-center text-muted">No referrals found.</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php else: ?>
<?php foreach ($referrals as $referral): ?>
<tr>
<td><?php echo date("M j, Y", strtotime($referral['referral_date'])); ?></td>
<td><?php echo htmlspecialchars($referral['first_name'] . ' ' . $referral['last_name']); ?></td>
<td><?php echo htmlspecialchars($referral['staff_email']); ?></td>
<td>
<?php
$ref_status_color = 'secondary';
if ($referral['status'] === 'Accepted') $ref_status_color = 'success';
if ($referral['status'] === 'Rejected') $ref_status_color = 'danger';
?>
<span class="badge bg-<?php echo $ref_status_color; ?>"><?php echo htmlspecialchars($referral['status']); ?></span>
</td>
<td>
<?php if ($referral['status'] === 'Pending'): ?>
<button class="btn btn-success btn-sm btn-action" data-action="Accepted" data-referral-id="<?php echo $referral['id']; ?>">Accept</button>
<button class="btn btn-danger btn-sm btn-action" data-action="Rejected" data-referral-id="<?php echo $referral['id']; ?>">Reject</button>
<?php else: ?>
<button class="btn btn-secondary btn-sm" disabled>Handled</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Messages Tab -->
<div class="tab-pane fade" id="messages" role="tabpanel" aria-labelledby="messages-tab">
<div class="pt-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h3 class="h4">Inbox</h3>
<a href="compose_message.php" class="btn btn-primary-custom"><i class="bi bi-pencil-square me-2"></i>Compose Message</a>
</div>
<div class="list-group">
<?php if (empty($messages)): ?>
<div class="list-group-item text-center text-muted">You have no messages.</div>
<?php else: ?>
<?php foreach ($messages as $message): ?>
<a href="view_message.php?id=<?php echo $message['id']; ?>" class="list-group-item list-group-item-action <?php echo !$message['read_at'] ? 'fw-bold' : ''; ?>">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1"><?php echo htmlspecialchars($message['subject']); ?></h6>
<small><?php echo date("M j, Y", strtotime($message['created_at'])); ?></small>
</div>
<p class="mb-1">From: <?php echo htmlspecialchars($message['sender_email']); ?></p>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<!-- Documents Tab -->
<div class="tab-pane fade" id="documents" role="tabpanel" aria-labelledby="documents-tab">
<div class="pt-4">
<h3 class="h4 mb-3">Document Management</h3>
<div class="list-group">
<?php if (empty($residents)): ?>
<div class="list-group-item text-center text-muted">No residents assigned to you.</div>
<?php else: ?>
<?php foreach ($residents as $resident): ?>
<div class="list-group-item d-flex justify-content-between align-items-center">
<span><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></span>
<a href="manage_documents.php?resident_id=<?php echo $resident['id']; ?>" class="btn btn-outline-primary btn-sm">Manage Documents</a>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const actionButtons = document.querySelectorAll('.btn-action');
actionButtons.forEach(button => {
button.addEventListener('click', function () {
const referralId = this.dataset.referralId;
const newStatus = this.dataset.action;
const row = this.closest('tr');
if (!confirm(`Are you sure you want to ${newStatus.toLowerCase()} this referral?`)) {
return;
}
fetch('update_referral_status.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
referral_id: referralId,
status: newStatus
}),
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Update the UI
const statusCell = row.querySelector('td:nth-child(4) span');
statusCell.textContent = newStatus;
statusCell.className = `badge bg-${newStatus === 'Accepted' ? 'success' : 'danger'}`;
const actionCell = row.querySelector('td:nth-child(5)');
actionCell.innerHTML = '<button class="btn btn-secondary btn-sm" disabled>Handled</button>';
// Optional: show a success message
// alert(data.message);
} else {
alert('Error: ' + data.message);
}
})
.catch(error => {
console.error('Fetch Error:', error);
alert('An unexpected error occurred. Please try again.');
});
});
});
});
</script>
</body>
</html>

View File

@ -19,7 +19,7 @@ $pdo = db();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$sql = "UPDATE residents SET first_name = ?, last_name = ?, email = ?, phone_number = ?, date_of_birth = ?, program = ?, status = ? WHERE id = ?";
$sql = "UPDATE residents SET first_name = ?, last_name = ?, email = ?, phone_number = ?, date_of_birth = ?, program = ?, status = ?, health_progress = ?, housing_progress = ?, employment_progress = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$_POST['first_name'],
@ -29,6 +29,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_POST['date_of_birth'],
$_POST['program'],
$_POST['status'],
$_POST['health_progress'],
$_POST['housing_progress'],
$_POST['employment_progress'],
$resident_id
]);
header("Location: resident_view.php?id=" . $resident_id . "&success=2"); // Success code for update
@ -117,6 +120,25 @@ if (!$resident) {
</select>
</div>
</div>
<hr class="my-4">
<h5 class="mb-3">Continuum Progress</h5>
<div class="row">
<div class="col-md-4 mb-3">
<label for="health_progress" class="form-label">Health Progress</label>
<input type="range" class="form-range" id="health_progress" name="health_progress" min="0" max="100" step="10" value="<?php echo htmlspecialchars($resident['health_progress']); ?>">
</div>
<div class="col-md-4 mb-3">
<label for="housing_progress" class="form-label">Housing Progress</label>
<input type="range" class="form-range" id="housing_progress" name="housing_progress" min="0" max="100" step="10" value="<?php echo htmlspecialchars($resident['housing_progress']); ?>">
</div>
<div class="col-md-4 mb-3">
<label for="employment_progress" class="form-label">Employment Progress</label>
<input type="range" class="form-range" id="employment_progress" name="employment_progress" min="0" max="100" step="10" value="<?php echo htmlspecialchars($resident['employment_progress']); ?>">
</div>
</div>
<button type="submit" class="btn btn-primary-custom">Save Changes</button>
</form>
</div>

View File

@ -27,9 +27,14 @@ if (!$resident) {
}
// Fetch action plans for the resident
$stmt = $pdo->prepare("SELECT * FROM action_plans WHERE resident_id = ? ORDER BY created_at DESC");
$stmt->execute([$resident_id]);
$action_plans = $stmt->fetchAll(PDO::FETCH_ASSOC);
$action_plan_stmt = $pdo->prepare("SELECT * FROM action_plans WHERE resident_id = ? ORDER BY created_at DESC");
$action_plan_stmt->execute([$resident_id]);
$action_plans = $action_plan_stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch case notes for the resident
$case_notes_stmt = $pdo->prepare("SELECT * FROM case_notes WHERE resident_id = ? ORDER BY created_at DESC");
$case_notes_stmt->execute([$resident_id]);
$case_notes = $case_notes_stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
@ -39,6 +44,7 @@ $action_plans = $stmt->fetchAll(PDO::FETCH_ASSOC);
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View Resident - <?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
@ -66,8 +72,17 @@ $action_plans = $stmt->fetchAll(PDO::FETCH_ASSOC);
<!-- Resident Details Card -->
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
Resident Information
<a href="resident_edit.php?id=<?php echo $resident_id; ?>" class="btn btn-secondary btn-sm">Edit</a>
<span>Resident Information</span>
<div>
<a href="resident_edit.php?id=<?php echo $resident_id; ?>" class="btn btn-secondary btn-sm">Edit</a>
<?php if ($resident['status'] !== 'Stabilized'): ?>
<form action="update_resident_status.php" method="POST" class="d-inline">
<input type="hidden" name="resident_id" value="<?php echo $resident_id; ?>">
<input type="hidden" name="status" value="Stabilized">
<button type="submit" class="btn btn-success btn-sm">Mark as Stabilized</button>
</form>
<?php endif; ?>
</div>
</div>
<div class="card-body">
<div class="row">
@ -85,44 +100,75 @@ $action_plans = $stmt->fetchAll(PDO::FETCH_ASSOC);
</div>
</div>
<!-- Action Plans Card -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
Action Plans
<a href="create_action_plan.php?resident_id=<?php echo $resident_id; ?>" class="btn btn-primary-custom btn-sm">+ New Action Plan</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Status</th>
<th>Due Date</th>
<th>Created On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($action_plans)): ?>
<tr>
<td colspan="5" class="text-center">No action plans found for this resident.</td>
</tr>
<?php else: ?>
<?php foreach ($action_plans as $plan): ?>
<div class="row">
<div class="col-md-8">
<!-- Action Plans Card -->
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
Action Plans
<a href="create_action_plan.php?resident_id=<?php echo $resident_id; ?>" class="btn btn-primary-custom btn-sm">+ New Action Plan</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<td><?php echo htmlspecialchars($plan['title']); ?></td>
<td><span class="badge bg-info"><?php echo htmlspecialchars($plan['status']); ?></span></td>
<td><?php echo htmlspecialchars($plan['due_date'] ? date("M j, Y", strtotime($plan['due_date'])) : 'N/A'); ?></td>
<td><?php echo htmlspecialchars(date("M j, Y", strtotime($plan['created_at']))); ?></td>
<td>
<a href="view_action_plan.php?id=<?php echo $plan['id']; ?>" class="btn btn-outline-secondary btn-sm">View/Edit</a>
</td>
<th>Title</th>
<th>Status</th>
<th>Due Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (empty($action_plans)): ?>
<tr>
<td colspan="4" class="text-center">No action plans found.</td>
</tr>
<?php else: ?>
<?php foreach ($action_plans as $plan): ?>
<tr>
<td><?php echo htmlspecialchars($plan['title']); ?></td>
<td><span class="badge bg-info"><?php echo htmlspecialchars($plan['status']); ?></span></td>
<td><?php echo htmlspecialchars($plan['due_date'] ? date("M j, Y", strtotime($plan['due_date'])) : 'N/A'); ?></td>
<td>
<a href="view_action_plan.php?id=<?php echo $plan['id']; ?>" class="btn btn-outline-secondary btn-sm">View/Edit</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<!-- Case Notes Card -->
<div class="card">
<div class="card-header">Case Notes</div>
<div class="card-body">
<!-- Add Note Form -->
<form action="add_case_note.php" method="POST" class="mb-3">
<input type="hidden" name="resident_id" value="<?php echo $resident_id; ?>">
<div class="mb-2">
<textarea name="note" class="form-control" rows="3" placeholder="Add a new note..." required></textarea>
</div>
<button type="submit" class="btn btn-primary-custom btn-sm w-100">Add Note</button>
</form>
<!-- Notes List -->
<div class="list-group list-group-flush">
<?php if (empty($case_notes)): ?>
<div class="list-group-item text-muted text-center">No notes yet.</div>
<?php else: ?>
<?php foreach ($case_notes as $note): ?>
<div class="list-group-item">
<p class="mb-1"><?php echo nl2br(htmlspecialchars($note['note'])); ?></p>
<small class="text-muted">On <?php echo date("M j, Y, g:i a", strtotime($note['created_at'])); ?></small>
</div>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

40
send_message.php Normal file
View File

@ -0,0 +1,40 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: index.php');
exit;
}
if (!isset($_SESSION['user_id'])) {
header('HTTP/1.1 403 Forbidden');
exit("Access denied.");
}
$sender_user_id = $_SESSION['user_id'];
$recipient_user_id = isset($_POST['recipient_user_id']) ? (int)$_POST['recipient_user_id'] : 0;
$subject = isset($_POST['subject']) ? trim($_POST['subject']) : '';
$body = isset($_POST['body']) ? trim($_POST['body']) : '';
if ($recipient_user_id === 0 || empty($subject) || empty($body)) {
// Basic validation failed
$redirect_url = ($_SESSION['user_role'] === 'staff') ? 'staff_dashboard.php' : 'partner_dashboard.php';
header("Location: " . $redirect_url . "?error=empty_message");
exit;
}
try {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO messages (sender_user_id, recipient_user_id, subject, body) VALUES (?, ?, ?, ?)");
$stmt->execute([$sender_user_id, $recipient_user_id, $subject, $body]);
$redirect_url = ($_SESSION['user_role'] === 'staff') ? 'staff_dashboard.php' : 'partner_dashboard.php';
header("Location: " . $redirect_url . "?success=message_sent");
exit;
} catch (PDOException $e) {
// In a real app, log this error.
$redirect_url = ($_SESSION['user_role'] === 'staff') ? 'staff_dashboard.php' : 'partner_dashboard.php';
header("Location: " . $redirect_url . "?error=db_error");
exit;
}

View File

@ -8,16 +8,53 @@ if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
exit;
}
// Fetch residents from the database
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, first_name, last_name, status, program FROM residents ORDER BY last_name, first_name");
$residents = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// Handle DB error - for now, just show a simple message
$error_message = "Error fetching resident data.";
// In a real app, you'd log this error.
$pdo = db();
// -- Analytics & Alerts --
// Fetch summary metrics
$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();
// Fetch high-risk residents for the alert panel
$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);
// -- Filtering --
$program_filter = $_GET['program'] ?? '';
$risk_filter = $_GET['risk_level'] ?? '';
$status_filter = $_GET['status'] ?? '';
$where_clauses = [];
$params = [];
if ($program_filter) {
$where_clauses[] = "program = ?";
$params[] = $program_filter;
}
if ($risk_filter) {
$where_clauses[] = "risk_level = ?";
$params[] = $risk_filter;
}
if ($status_filter) {
$where_clauses[] = "status = ?";
$params[] = $status_filter;
}
$sql = "SELECT id, first_name, last_name, status, program, risk_level, health_progress, housing_progress, employment_progress FROM residents";
if (!empty($where_clauses)) {
$sql .= " WHERE " . implode(' AND ', $where_clauses);
}
$sql .= " ORDER BY last_name, first_name";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$residents = $stmt->fetchAll(PDO::FETCH_ASSOC);
// For filter dropdowns
$programs = $pdo->query("SELECT DISTINCT program FROM residents ORDER BY program")->fetchAll(PDO::FETCH_COLUMN);
$risk_levels = $pdo->query("SELECT DISTINCT risk_level FROM residents ORDER BY risk_level")->fetchAll(PDO::FETCH_COLUMN);
$statuses = $pdo->query("SELECT DISTINCT status FROM residents ORDER BY status")->fetchAll(PDO::FETCH_COLUMN);
?>
<!DOCTYPE html>
@ -27,6 +64,7 @@ try {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Staff Dashboard | Continuum of Healing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
@ -51,52 +89,200 @@ try {
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Continuum Control Center</h1>
<a href="resident_intake.php" class="btn btn-primary-custom">+ 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>
<?php if (isset($error_message)): ?>
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php endif; ?>
<div class="card">
<div class="card-header">
All Residents
<!-- 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="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Program</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (isset($residents) && !empty($residents)): ?>
<?php foreach ($residents as $resident): ?>
<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: Resident List -->
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<span>All Residents</span>
<div>
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#filterCollapse" aria-expanded="false" aria-controls="filterCollapse">
<i class="bi bi-funnel me-1"></i> Filters
</button>
<a href="export_residents.php" id="export-csv-btn" class="btn btn-sm btn-outline-success">
<i class="bi bi-download me-1"></i> Export CSV
</a>
</div>
</div>
</div>
<div class="card-body">
<!-- Filter Form -->
<div class="collapse" id="filterCollapse">
<form method="GET" action="staff_dashboard.php" class="mb-4">
<div class="row">
<div class="col-md-4">
<label for="program" class="form-label">Program</label>
<select name="program" id="program" class="form-select">
<option value="">All</option>
<?php foreach ($programs as $p): ?>
<option value="<?php echo htmlspecialchars($p); ?>" <?php echo ($program_filter === $p) ? 'selected' : ''; ?>><?php echo htmlspecialchars($p); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4">
<label for="risk_level" class="form-label">Risk Level</label>
<select name="risk_level" id="risk_level" class="form-select">
<option value="">All</option>
<?php foreach ($risk_levels as $r): ?>
<option value="<?php echo htmlspecialchars($r); ?>" <?php echo ($risk_filter === $r) ? 'selected' : ''; ?>><?php echo htmlspecialchars($r); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4">
<label for="status" class="form-label">Status</label>
<select name="status" id="status" class="form-select">
<option value="">All</option>
<?php foreach ($statuses as $s): ?>
<option value="<?php echo htmlspecialchars($s); ?>" <?php echo ($status_filter === $s) ? 'selected' : ''; ?>><?php echo htmlspecialchars($s); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="mt-2 text-end">
<a href="staff_dashboard.php" class="btn btn-secondary">Reset</a>
<button type="submit" class="btn btn-primary-custom">Filter</button>
</div>
</form>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<td><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></td>
<td><?php echo htmlspecialchars($resident['program']); ?></td>
<td><span class="badge bg-primary"><?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>
<th>Name</th>
<th>Program</th>
<th>Risk Level</th>
<th>Continuum</th>
<th>Status</th>
<th>Action</th>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="4" class="text-center">No residents found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</thead>
<tbody>
<?php if (!empty($residents)): ?>
<?php foreach ($residents as $resident): ?>
<tr>
<td><?php echo htmlspecialchars($resident['first_name'] . ' ' . $resident['last_name']); ?></td>
<td><?php echo htmlspecialchars($resident['program']); ?></td>
<td>
<?php
$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="d-flex flex-column">
<div class="progress" style="height: 5px; margin-bottom: 2px;" title="Health: <?php echo $resident['health_progress']; ?>%">
<div class="progress-bar bg-success" role="progressbar" style="width: <?php echo $resident['health_progress']; ?>%;" aria-valuenow="<?php echo $resident['health_progress']; ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress" style="height: 5px; margin-bottom: 2px;" title="Housing: <?php echo $resident['housing_progress']; ?>%">
<div class="progress-bar bg-primary" role="progressbar" style="width: <?php echo $resident['housing_progress']; ?>%;" aria-valuenow="<?php echo $resident['housing_progress']; ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="progress" style="height: 5px;" title="Employment: <?php echo $resident['employment_progress']; ?>%">
<div class="progress-bar bg-warning" role="progressbar" style="width: <?php echo $resident['employment_progress']; ?>%;" aria-valuenow="<?php echo $resident['employment_progress']; ?>" aria-valuemin="0" aria-valuemax="100"></div>
</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>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="6" class="text-center">No residents found matching your criteria.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</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>
<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 params = new URLSearchParams();
if (program) params.append('program', program);
if (riskLevel) params.append('risk_level', riskLevel);
if (status) params.append('status', status);
const url = 'export_residents.php?' + params.toString();
window.location.href = url;
});
</script>
</body>
</html>

37
submit_referral.php Normal file
View File

@ -0,0 +1,37 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: index.php');
exit;
}
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
header('HTTP/1.1 403 Forbidden');
exit("Access denied.");
}
$resident_id = isset($_POST['resident_id']) ? (int)$_POST['resident_id'] : 0;
$partner_id = isset($_POST['partner_id']) ? (int)$_POST['partner_id'] : 0;
$staff_id = isset($_POST['staff_id']) ? (int)$_POST['staff_id'] : 0;
$notes = isset($_POST['notes']) ? trim($_POST['notes']) : '';
if ($resident_id === 0 || $partner_id === 0 || $staff_id === 0 || empty($notes)) {
header("Location: create_referral.php?resident_id={$resident_id}&error=invalid_data");
exit;
}
try {
$pdo = db();
$sql = "INSERT INTO referrals (resident_id, partner_id, staff_id, notes) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$resident_id, $partner_id, $staff_id, $notes]);
header("Location: resident_view.php?id={$resident_id}&success=referral_sent");
exit;
} catch (PDOException $e) {
// Log error in a real app
header("Location: create_referral.php?resident_id={$resident_id}&error=db_error");
exit;
}

View File

@ -0,0 +1,61 @@
<?php
session_start();
require_once 'db/config.php';
header('Content-Type: application/json');
// Check if user is a logged-in partner
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'partner') {
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
// Check for POST request
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
exit;
}
// Get and validate input
$input = json_decode(file_get_contents('php://input'), true);
$referral_id = $input['referral_id'] ?? null;
$new_status = $input['status'] ?? null;
if (!$referral_id || !$new_status) {
echo json_encode(['success' => false, 'message' => 'Missing required parameters.']);
exit;
}
if (!in_array($new_status, ['Accepted', 'Rejected'])) {
echo json_encode(['success' => false, 'message' => 'Invalid status.']);
exit;
}
$pdo = db();
// Verify the partner owns this referral
$stmt = $pdo->prepare("SELECT r.id FROM referrals r JOIN partners p ON r.partner_id = p.id WHERE r.id = ? AND p.user_id = ?");
$stmt->execute([$referral_id, $_SESSION['user_id']]);
$referral = $stmt->fetch();
if (!$referral) {
echo json_encode(['success' => false, 'message' => 'Referral not found or you do not have permission to modify it.']);
exit;
}
// Update the referral status
try {
$update_stmt = $pdo->prepare("UPDATE referrals SET status = ? WHERE id = ?");
$update_stmt->execute([$new_status, $referral_id]);
if ($update_stmt->rowCount() > 0) {
echo json_encode(['success' => true, 'message' => 'Referral status updated successfully.']);
} else {
echo json_encode(['success' => false, 'message' => 'Failed to update status or status was already set.']);
}
} catch (PDOException $e) {
// Log error properly in a real application
echo json_encode(['success' => false, 'message' => 'Database error: ' . $e->getMessage()]);
}
?>

View File

@ -0,0 +1,44 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: staff_dashboard.php');
exit;
}
// Check if user is logged in and has the 'staff' role
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'staff') {
header('HTTP/1.1 403 Forbidden');
exit("Access denied.");
}
$resident_id = isset($_POST['resident_id']) ? (int)$_POST['resident_id'] : 0;
$status = isset($_POST['status']) ? trim($_POST['status']) : '';
// Basic validation
if ($resident_id === 0 || empty($status)) {
header("Location: staff_dashboard.php?error=invalid_data");
exit;
}
// You might want to validate the status against a list of allowed statuses
$allowed_statuses = ['Active', 'Inactive', 'Stabilized'];
if (!in_array($status, $allowed_statuses)) {
header("Location: resident_view.php?id={$resident_id}&error=invalid_status");
exit;
}
try {
$pdo = db();
$stmt = $pdo->prepare("UPDATE residents SET status = ? WHERE id = ?");
$stmt->execute([$status, $resident_id]);
// Redirect back to the resident's view page
header("Location: resident_view.php?id={$resident_id}&success=status_updated");
exit;
} catch (PDOException $e) {
// Log the error in a real app
header("Location: resident_view.php?id={$resident_id}&error=db_error");
exit;
}

65
upload_document.php Normal file
View File

@ -0,0 +1,65 @@
<?php
session_start();
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: index.php');
exit;
}
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'partner') {
header('HTTP/1.1 403 Forbidden');
exit("Access denied.");
}
$resident_id = isset($_POST['resident_id']) ? (int)$_POST['resident_id'] : 0;
$description = isset($_POST['description']) ? trim($_POST['description']) : '';
if ($resident_id === 0 || empty($description) || !isset($_FILES['document']) || $_FILES['document']['error'] !== UPLOAD_ERR_OK) {
header("Location: manage_documents.php?resident_id={$resident_id}&error=invalid_upload");
exit;
}
$file = $_FILES['document'];
$upload_dir = __DIR__ . '/uploads/documents/';
$original_name = basename($file['name']);
$file_extension = pathinfo($original_name, PATHINFO_EXTENSION);
$unique_name = uniqid('', true) . '.' . $file_extension;
$target_path = $upload_dir . $unique_name;
// Basic security checks
$allowed_extensions = ['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png'];
if (!in_array(strtolower($file_extension), $allowed_extensions)) {
header("Location: manage_documents.php?resident_id={$resident_id}&error=invalid_file_type");
exit;
}
if ($file['size'] > 5 * 1024 * 1024) { // 5MB limit
header("Location: manage_documents.php?resident_id={$resident_id}&error=file_too_large");
exit;
}
if (move_uploaded_file($file['tmp_name'], $target_path)) {
try {
$pdo = db();
$partner_id = null;
$stmt = $pdo->prepare("SELECT id FROM partners WHERE user_id = ?");
$stmt->execute([$_SESSION['user_id']]);
$partner_id = $stmt->fetchColumn();
$sql = "INSERT INTO documents (resident_id, partner_id, file_name, file_path, description) VALUES (?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$resident_id, $partner_id, $original_name, $target_path, $description]);
header("Location: manage_documents.php?resident_id={$resident_id}&success=uploaded");
exit;
} catch (PDOException $e) {
// Clean up the uploaded file if DB insert fails
unlink($target_path);
header("Location: manage_documents.php?resident_id={$resident_id}&error=db_error");
exit;
}
} else {
header("Location: manage_documents.php?resident_id={$resident_id}&error=upload_failed");
exit;
}

95
view_message.php Normal file
View File

@ -0,0 +1,95 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header("Location: index.php");
exit;
}
$message_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($message_id === 0) {
$redirect_url = ($_SESSION['user_role'] === 'staff') ? 'staff_dashboard.php' : 'partner_dashboard.php';
header("Location: " . $redirect_url);
exit;
}
$pdo = db();
// Fetch message details
$stmt = $pdo->prepare("
SELECT m.*, u.email as sender_email
FROM messages m
JOIN users u ON m.sender_user_id = u.id
WHERE m.id = ?
");
$stmt->execute([$message_id]);
$message = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$message || ($message['recipient_user_id'] != $_SESSION['user_id'] && $message['sender_user_id'] != $_SESSION['user_id'])) {
// Message not found or user is not part of the conversation
$redirect_url = ($_SESSION['user_role'] === 'staff') ? 'staff_dashboard.php' : 'partner_dashboard.php';
header("Location: " . $redirect_url . "?error=not_found");
exit;
}
// Mark as read if the current user is the recipient
if ($message['recipient_user_id'] == $_SESSION['user_id'] && !$message['read_at']) {
$pdo->prepare("UPDATE messages SET read_at = NOW() WHERE id = ?")->execute([$message_id]);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View Message - Continuum of Healing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Continuum of Healing</a>
<a href="logout.php" class="btn btn-outline-light">Logout</a>
</div>
</nav>
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">View Message</h1>
<a href="partner_dashboard.php" class="btn btn-secondary"> Back to Dashboard</a>
</div>
<div class="card">
<div class="card-header">
<h5><?php echo htmlspecialchars($message['subject']); ?></h5>
<small class="text-muted">From: <?php echo htmlspecialchars($message['sender_email']); ?> on <?php echo date("M j, Y, g:i a", strtotime($message['created_at'])); ?></small>
</div>
<div class="card-body">
<p><?php echo nl2br(htmlspecialchars($message['body'])); ?></p>
</div>
</div>
<hr class="my-4">
<div class="card">
<div class="card-header">Reply</div>
<div class="card-body">
<form action="send_message.php" method="POST">
<input type="hidden" name="recipient_user_id" value="<?php echo $message['sender_user_id']; ?>">
<input type="hidden" name="subject" value="Re: <?php echo htmlspecialchars($message['subject']); ?>">
<div class="mb-3">
<label for="body" class="form-label">Message</label>
<textarea name="body" id="body" class="form-control" rows="5" required></textarea>
</div>
<button type="submit" class="btn btn-primary-custom">Send Reply</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>