<?php
add_shortcode('case_search_form', 'render_case_search_form');
function render_case_search_form() {
ob_start();
$connection_path = ABSPATH . 'case_management/includes/connection/connection.php';
if (file_exists($connection_path)) {
require_once $connection_path;
} else {
return '<p>Database connection file not found.</p>';
}
if (!isset($conn) || $conn->connect_error) {
return '<p>Database connection failed.</p>';
}
// Case Type options
$case_type_options = '';
$result_case_types = $conn->query("SELECT name, slug FROM case_types_parent ORDER BY name");
while ($row = $result_case_types->fetch_assoc()) {
$name = esc_attr($row['slug']);
$slug = esc_attr($row['slug']);
$case_type_options .= "<option value=\"$slug\">$name</option>";
}
// Year options
$current_year = date('Y');
$year_options = '';
for ($year = 2000; $year <= $current_year; $year++) {
$year_options .= "<option value=\"$year\">$year</option>";
}
// Supreme Court options
$supreme_options = '';
$result1 = $conn->query("SELECT DISTINCT case_no FROM cases WHERE case_no IS NOT NULL AND case_no != ''");
while ($row = $result1->fetch_assoc()) {
$case_no = esc_attr($row['case_no']);
$supreme_options .= "<option value=\"$case_no\">$case_no</option>";
}
// Lower Court options
$lower_options = '';
$result2 = $conn->query("SELECT DISTINCT lc1_case_no FROM cases WHERE lc1_case_no IS NOT NULL AND lc1_case_no != ''");
while ($row = $result2->fetch_assoc()) {
$lc1_case_no = esc_attr($row['lc1_case_no']);
$lower_options .= "<option value=\"$lc1_case_no\">$lc1_case_no</option>";
}
// Handle search
$search_results = '';
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['case_search_submit'])) {
if (!empty($_GET['supremeCaseNo'])) {
$case_no = $conn->real_escape_string($_GET['supremeCaseNo']);
$result = $conn->query("SELECT * FROM cases WHERE case_no = '$case_no'");
$search_results = render_case_cards($result, $conn);
} elseif (!empty($_GET['lowerCaseNo'])) {
$case_no = $conn->real_escape_string($_GET['lowerCaseNo']);
$result = $conn->query("SELECT * FROM cases WHERE lc1_case_no = '$case_no'");
$search_results = render_case_cards($result, $conn);
}
}
?>
<style>
.case-form-wrapper form { background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
.case-form-wrapper label { font-weight: bold; display: block; margin-bottom: 5px; }
.case-form-wrapper select,
.case-form-wrapper input,
.case-form-wrapper button {
margin-top: 10px; width: 100%; padding: 8px;
border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;
}
.case-form-wrapper button { background: #0073aa; color: #fff; border: none; cursor: pointer; }
.case-form-wrapper button:hover { background: #005177; }
.case-results { display: flex; flex-direction: column; gap: 20px; }
.case-card {
background: #ffffff; border: 1px solid #ddd; border-radius: 8px;
padding: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.05); transition: transform 0.2s ease;
}
.case-card:hover { transform: scale(1.01); }
.case-card h5 { margin-top: 0; color: #0073aa; }
.case-card p { margin: 5px 0; }
.case-card hr { margin: 15px 0; border-top: 1px solid #ddd; }
.journal-modal-overlay {
display: none; position: fixed; inset: 0;
background: rgba(0,0,0,0.55); z-index: 9999;
justify-content: center; align-items: center;
}
.journal-modal-overlay.active { display: flex; }
.journal-modal-box {
background: #fff; border-radius: 8px; padding: 30px;
max-width: 650px; width: 90%; max-height: 80vh;
overflow-y: auto; position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
.journal-modal-box h4 { margin-top: 0; color: #0073aa; }
.journal-modal-close {
position: absolute; top: 12px; right: 16px;
font-size: 22px; cursor: pointer; color: #555;
background: none; border: none;
}
.journal-modal-close:hover { color: #000; }
.next-action-badge {
display: inline-block; padding: 3px 10px;
border-radius: 12px; font-size: 0.82em; font-weight: bold; margin-left: 6px;
}
.badge-now { background: #d4edda; color: #155724; }
.badge-pending { background: #fff3cd; color: #856404; }
.badge-keptdown { background: #f8d7da; color: #721c24; }
</style>
<div id="journalModalOverlay" class="journal-modal-overlay">
<div class="journal-modal-box">
<button class="journal-modal-close" id="journalModalCloseBtn">×</button>
<h4 id="journalModalCaseNo"></h4>
<p id="journalModalDate" style="font-size:0.85em;color:#777;margin-bottom:12px;"></p>
<div id="journalModalBody" style="white-space: pre-wrap; line-height:1.6;"></div>
</div>
</div>
<script>
(function() {
function openJournalModal(caseNo, date, text) {
document.getElementById("journalModalCaseNo").textContent = "Journal Entry — " + caseNo;
document.getElementById("journalModalDate").textContent = "Date: " + date;
document.getElementById("journalModalBody").textContent = text;
document.getElementById("journalModalOverlay").classList.add("active");
}
function closeJournalModal() {
document.getElementById("journalModalOverlay").classList.remove("active");
}
document.getElementById("journalModalCloseBtn").addEventListener("click", closeJournalModal);
document.getElementById("journalModalOverlay").addEventListener("click", function(e) {
if (e.target === this) closeJournalModal();
});
document.addEventListener("keydown", function(e) {
if (e.key === "Escape") closeJournalModal();
});
// Event delegation for dynamically inserted buttons
document.addEventListener("click", function(e) {
var btn = e.target.closest(".open-journal-modal");
if (btn) {
openJournalModal(
btn.getAttribute("data-caseno"),
btn.getAttribute("data-date"),
btn.getAttribute("data-journal")
);
}
});
})();
</script>
<div style="display: flex; flex-wrap: wrap; gap: 30px; align-items: stretch; margin-bottom: 40px;">
<div class="case-form-wrapper" style="flex: 1; min-width: 300px;">
<div class="row">
<div class="col-12">
<form method="GET" id="case_type_search_form">
<label for="case_type">Case Type</label>
<select id="case_type" required>
<option value="">Select Case Type</option>
<?php echo $case_type_options; ?>
</select>
<label for="serial_number">Serial Number</label>
<input type="number" id="serial_number" required min="1">
<label for="year">Year</label>
<select id="year" required>
<option value="">Select Year</option>
<?php echo $year_options; ?>
</select>
<input type="hidden" id="supremeCaseNo" name="supremeCaseNo">
<input type="hidden" name="case_search_submit" value="">
<button type="submit" name="case_search_submit">Search</button>
</form>
</div>
</div>
<div class="row" style="display: flex; gap: 15px; align-items: stretch;">
<div class="col-6" style="flex: 1; display: flex;">
<form method="GET" style="width: 100%; display: flex; flex-direction: column;">
<label for="supremeCaseNoText" style="flex-grow: 1;">Search by Court of Appeal Case No</label>
<input type="text" id="supremeCaseNoText" name="supremeCaseNo" list="supremeCaseList">
<datalist id="supremeCaseList"><?php echo $supreme_options; ?></datalist>
<button type="submit" name="case_search_submit">Search</button>
</form>
</div>
<div class="col-6" style="flex: 1; display: flex;">
<form method="GET" style="width: 100%; display: flex; flex-direction: column;">
<label for="lowerCaseNo" style="flex-grow: 1;">Search by Lower Court Case No</label>
<input type="text" id="lowerCaseNo" name="lowerCaseNo" list="lowerCaseList">
<datalist id="lowerCaseList"><?php echo $lower_options; ?></datalist>
<button type="submit" name="case_search_submit">Search</button>
</form>
</div>
</div>
</div>
<div class="search-results-side-wrapper" style="flex: 2; min-width: 300px; display: flex; flex-direction: column;">
<?php if (!empty($search_results)): ?>
<?php echo $search_results; ?>
<?php else: ?>
<div style="background: #f5f5f5; padding: 20px; border-radius: 8px; text-align: center; color: #666; display: flex; align-items: center; justify-content: center; flex-grow: 1;">
<p style="margin: 0;">Enter details on the left to search for a case.</p>
</div>
<?php endif; ?>
</div>
</div> <script>
document.getElementById('case_type_search_form').addEventListener('submit', function(e) {
e.preventDefault();
const caseType = document.getElementById('case_type').value;
const serialNumber = document.getElementById('serial_number').value;
const year = document.getElementById('year').value;
if (caseType && serialNumber && year) {
const supremeCaseNo = `CA/${caseType}/${serialNumber}/${year}`;
document.getElementById('supremeCaseNo').value = supremeCaseNo;
this.submit();
}
});
</script>
<?php
return ob_get_clean();
}
function render_case_cards($result, $conn) {
if (!$result || $result->num_rows === 0) {
return '<p>No cases found.</p>';
}
$output = '<div class="case-results">';
while ($row = $result->fetch_assoc()) {
$case_no_safe = $conn->real_escape_string($row['case_no']);
$case_id = intval($row['id']);
// --- Latest Next Action ---
$na_html = '<p style="color:#999; font-size:0.9em;">No next action found.</p>';
$na_result = $conn->query("
SELECT na.trial_date, na.trial_time, na.remarks, na.status, nat.name AS action_type_name
FROM next_actions_all na
LEFT JOIN next_action_types nat ON na.action_type = nat.id
WHERE (na.case_id = $case_id OR na.case_no = '$case_no_safe')
ORDER BY na.trial_date DESC, na.trial_time DESC, na.id DESC
LIMIT 1
");
if ($na_result && $na_result->num_rows > 0) {
$na = $na_result->fetch_assoc();
$status_map = [
1 => ['Now', 'badge-now'],
2 => ['Pending', 'badge-pending'],
3 => ['Kept Down', 'badge-keptdown']
];
$status_info = isset($status_map[$na['status']]) ? $status_map[$na['status']] : ['Unknown', ''];
$trial_date = !empty($na['trial_date']) ? date('d M Y', strtotime($na['trial_date'])) : '—';
$trial_time = !empty($na['trial_time']) ? $na['trial_time'] : '—';
$na_html = '<p style="margin:3px 0;"><strong>Action Type:</strong> ' . esc_html($na['action_type_name'] ?? 'Unknown') . '
<span class="next-action-badge ' . $status_info[1] . '">' . $status_info[0] . '</span></p>';
$na_html .= '<p style="margin:3px 0;"><strong>Trial Date:</strong> ' . esc_html($trial_date) . ' <strong>Time:</strong> ' . esc_html($trial_time) . '</p>';
}
// --- Latest Journal Entry (journals.case_no = cases.id) ---
$journal_html = '<p style="color:#999; font-size:0.9em;">No journal entry found.</p>';
$j_result = $conn->query("
SELECT id, date, journal
FROM journals
WHERE case_no = $case_id
ORDER BY date DESC, id DESC
LIMIT 1
");
if ($j_result && $j_result->num_rows > 0) {
$j = $j_result->fetch_assoc();
$j_date = !empty($j['date']) ? date('d M Y', strtotime($j['date'])) : '—';
$j_preview = esc_html(mb_substr($j['journal'], 0, 120)) . (mb_strlen($j['journal']) > 120 ? '...' : '');
$data_case_no = htmlspecialchars($row['case_no'], ENT_QUOTES, 'UTF-8');
$data_date = htmlspecialchars($j_date, ENT_QUOTES, 'UTF-8');
$data_journal = htmlspecialchars($j['journal'], ENT_QUOTES, 'UTF-8');
$journal_html = '<p style="margin:3px 0;"><strong>Date:</strong> ' . esc_html($j_date) . '
<button class="open-journal-modal"
data-caseno="' . $data_case_no . '"
data-date="' . $data_date . '"
data-journal="' . $data_journal . '"
style="margin-left:10px; padding:3px 10px; background:#0073aa; color:#fff; border:none; border-radius:4px; cursor:pointer; font-size:0.82em;">
View Full Entry
</button></p>';
$journal_html .= '<p style="margin:3px 0; color:#555; font-size:0.9em;">' . $j_preview . '</p>';
}
// --- Build card ---
$output .= '<div class="case-card" style="display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap;">';
$output .= '<div class="case-info" style="flex:1; min-width: 250px;">';
$output .= '<h5>Case No: ' . esc_html($row['case_no']) . '</h5>';
$output .= '<p><strong>Case Date:</strong> ' . esc_html($row['case_date']) . '</p>';
$output .= '<p><strong>Receipt No:</strong> ' . esc_html($row['receipt_no']) . '</p>';
$output .= '<hr>';
$output .= '<p><strong>Lower Court 1:</strong> ' . esc_html($row['lc1_case_no']) . ' - ' . esc_html($row['lc1_name']) . '</p>';
$output .= '<p><strong>Lower Court 2:</strong> ' . esc_html($row['lc2_case_no']) . ' - ' . esc_html($row['lc2_name']) . '</p>';
// Next Action block
$output .= '<hr>';
$output .= '<p><strong>Latest Next Action:</strong></p>';
$output .= '<div style="background:#f9f9f9; border-left:3px solid #0073aa; padding:8px 12px; border-radius:4px; margin-bottom:8px;">' . $na_html . '</div>';
// Journal Entry block
$output .= '<p><strong>Latest Journal Entry:</strong></p>';
$output .= '<div style="background:#f9f9f9; border-left:3px solid #28a745; padding:8px 12px; border-radius:4px; margin-bottom:8px;">' . $journal_html . '</div>';
// Dates
$output .= '<p style="font-size: 0.85em; color: #777;"><strong>Created At:</strong> ' . esc_html($row['created_at']) . ' | <strong>Updated At:</strong> ' . esc_html($row['updated_at']) . '</p>';
// Buttons
$output .= '<div style="display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; margin-top: 15px;">';
$output .= '<a href="./next-step-status?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">NEXT STEP/STATUS</button></a>';
$output .= '<a href="./journal-entries?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">JOURNAL ENTRIES</button></a>';
$output .= '<a href="./concluded-cases?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">STATUS OF CONCLUDED CASES</button></a>';
// $output .= '<a href="./time-motions?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">TIME MOTION</button></a>';
$output .= '<a href="./normal-motions?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">MOTION</button></a>';
$output .= '<a href="./new-cases-information?case_num=' . $row['case_no'] . '"><button type="button" style="padding: 8px 12px; background: #0073aa; color: #fff; border: none; border-radius: 4px; cursor: pointer;">STATUS OF NEW CASES</button></a>';
$output .= '</div>';
$output .= '</div>'; // end case-info
// Image
$output .= '<div class="case-image" style="text-align: center; min-width: 150px;">';
$output .= '<img src="https://supremecourt.lk/wp-content/uploads/2025/09/law-icon-.png" alt="Digital Case File" style="max-width: 200px; height: auto; border-radius: 8px;">';
$output .= '<p style="margin-top: 10px; font-weight: bold;">Digital Case File (coming Soon)</p>';
$output .= '</div>';
$output .= '</div>'; // end case-card
}
$output .= '</div>'; // end case-results
return $output;
}

