« Back to History
interviews_manage.php
|
20260723_000646.php
Initial Domain Snapshot
Copy Code
<?php /* ============================================================================ File: /erp/interviews_manage.php Purpose: Central Interview Management - Feedback, Status Tracking & Editing ============================================================================ */ header('X-Frame-Options: SAMEORIGIN'); error_reporting(E_ALL); ini_set('display_errors', '1'); /* ================= AUTH & CONTEXT ================= */ require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('attendance_dashboard'); $pdo = $ctx['pdo']; $COMPANY_ID = (int)$ctx['company_id']; function j($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } /* ================= HANDLE POST ACTIONS ================= */ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { // 1. Complete Interview if ($_POST['action'] === 'complete_interview') { try { $pdo->beginTransaction(); $interview_id = (int)$_POST['interview_id']; $app_id = (int)$_POST['application_id']; $remarks = trim($_POST['remarks']); $result = $_POST['result']; // Update Interview Status $stmt = $pdo->prepare("UPDATE interviews SET status = 'completed', remarks = ? WHERE id = ? AND company_id = ?"); $stmt->execute([$remarks, $interview_id, $COMPANY_ID]); // Insert Feedback $stmt = $pdo->prepare("INSERT INTO interview_feedback (company_id, interview_id, comments, recommendation) VALUES (?, ?, ?, ?)"); $stmt->execute([$COMPANY_ID, $interview_id, $remarks, $result]); // Update Application Status $status_map = ($result === 'Selected') ? 'Selected' : 'Rejected'; $stmt = $pdo->prepare("UPDATE job_applications SET application_status = ? WHERE id = ? AND company_id = ?"); $stmt->execute([$status_map, $app_id, $COMPANY_ID]); $pdo->commit(); $message = "Interview completed and feedback saved!"; } catch (Exception $e) { $pdo->rollBack(); $error = "Error: " . $e->getMessage(); } } // 2. Edit Interview Feedback / Status if ($_POST['action'] === 'edit_interview') { try { $pdo->beginTransaction(); $interview_id = (int)$_POST['interview_id']; $app_id = (int)$_POST['application_id']; $remarks = trim($_POST['remarks']); $result = $_POST['result']; $status = $_POST['status']; // scheduled or completed // Update Interview Table $stmt = $pdo->prepare("UPDATE interviews SET status = ?, remarks = ? WHERE id = ? AND company_id = ?"); $stmt->execute([$status, $remarks, $interview_id, $COMPANY_ID]); // Sync Application Status accordingly if ($status === 'completed') { $status_map = ($result === 'Selected') ? 'Selected' : 'Rejected'; } else { $status_map = 'Shortlisted'; // Reset back if scheduled } $stmt = $pdo->prepare("UPDATE job_applications SET application_status = ? WHERE id = ? AND company_id = ?"); $stmt->execute([$status_map, $app_id, $COMPANY_ID]); // Delete then Insert pattern for Feedback row $stmt = $pdo->prepare("DELETE FROM interview_feedback WHERE interview_id = ? AND company_id = ?"); $stmt->execute([$interview_id, $COMPANY_ID]); if ($status === 'completed') { $stmt = $pdo->prepare("INSERT INTO interview_feedback (company_id, interview_id, comments, recommendation) VALUES (?, ?, ?, ?)"); $stmt->execute([$COMPANY_ID, $interview_id, $remarks, $result]); } $pdo->commit(); $message = "Interview details updated successfully!"; } catch (Exception $e) { $pdo->rollBack(); $error = "Error: " . $e->getMessage(); } } } /* ================= FETCH DATA WITH FEEDBACK & SALARY ================= */ $query = " SELECT i.*, c.full_name, c.mobile, c.current_salary, c.expected_salary, j.title as position, f.comments, f.recommendation, ja.application_status FROM interviews i JOIN job_applications ja ON i.application_id = ja.id JOIN candidates c ON ja.candidate_id = c.id JOIN jobs j ON ja.job_id = j.id LEFT JOIN interview_feedback f ON i.id = f.interview_id WHERE i.company_id = ? ORDER BY i.interview_date ASC "; $stmt = $pdo->prepare($query); $stmt->execute([$COMPANY_ID]); $interviews = $stmt->fetchAll(PDO::FETCH_ASSOC); require_once __DIR__ . '/partials/header.php'; ?> <div class="container-fluid py-4"> <div class="d-flex justify-content-between align-items-center mb-4"> <h4 class="fw-bold mb-0">INTERVIEW SCHEDULES DASHBOARD</h4> <button type="button" onclick="printIsolatedDashboard()" class="btn btn-sm btn-primary shadow-sm px-3"> Print Report </button> </div> <?php if (!empty($message)): ?><div class="alert alert-success"><?= j($message) ?></div><?php endif; ?> <?php if (!empty($error)): ?><div class="alert alert-danger"><?= j($error) ?></div><?php endif; ?> <div class="card shadow-sm border-0" id="printableArea"> <div class="card-body p-0"> <div class="table-responsive"> <table class="table table-hover align-middle mb-0"> <thead class="table-light"> <tr> <th class="ps-4">Candidate Name</th> <th>Position</th> <th>Current Salary</th> <th>Expected Salary</th> <th>Schedule</th> <th>Remarks / Comments</th> <th>Status</th> <th class="action-column">Action</th> </tr> </thead> <tbody> <?php foreach ($interviews as $i): $badge_class = 'bg-primary'; if ($i['application_status'] === 'Selected') { $badge_class = 'bg-success'; } elseif ($i['application_status'] === 'Rejected') { $badge_class = 'bg-danger'; } ?> <tr> <td class="ps-4"> <div class="fw-bold text-dark"><?= j($i['full_name']) ?></div> <small class="text-muted"><?= j($i['mobile']) ?></small> </td> <td><?= j($i['position']) ?></td> <td class="text-secondary">₹<?= number_format((float)($i['current_salary'] ?? 0), 2) ?></td> <td class="fw-bold text-dark">₹<?= number_format((float)($i['expected_salary'] ?? 0), 2) ?></td> <td><?= j($i['interview_date']) ?> <?= j($i['interview_time']) ?></td> <td> <div><?= j($i['comments'] ?: ($i['remarks'] ?: '-')) ?></div> <?php if (!empty($i['recommendation'])): ?> <small class="badge <?= $i['recommendation'] === 'Selected' ? 'bg-success' : 'bg-danger' ?> mt-1"> <?= j($i['recommendation']) ?> </small> <?php endif; ?> </td> <td> <span class="badge <?= $badge_class ?> text-white"> <?= j($i['application_status'] === 'Shortlisted' ? $i['status'] : $i['application_status']) ?> </span> </td> <td class="action-column"> <div class="btn-group"> <?php if ($i['status'] === 'scheduled'): ?> <button class="btn btn-sm btn-success" data-bs-toggle="modal" data-bs-target="#completeModal<?= $i['id'] ?>">Complete</button> <?php endif; ?> <button class="btn btn-sm btn-outline-dark" data-bs-toggle="modal" data-bs-target="#editModal<?= $i['id'] ?>">Edit</button> </div> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> </div> </div> </div> <?php foreach ($interviews as $i): ?> <div class="modal fade" id="completeModal<?= $i['id'] ?>" tabindex="-1"> <form method="POST" class="modal-dialog"> <input type="hidden" name="action" value="complete_interview"> <input type="hidden" name="interview_id" value="<?= $i['id'] ?>"> <input type="hidden" name="application_id" value="<?= $i['application_id'] ?>"> <div class="modal-content"> <div class="modal-header"><h5>Complete Interview - <?= j($i['full_name']) ?></h5></div> <div class="modal-body"> <label class="form-label fw-bold">Result Decision</label> <select name="result" class="form-select mb-3"> <option value="Selected">Select Candidate</option> <option value="Rejected">Reject</option> </select> <label class="form-label fw-bold">Interview Remarks</label> <textarea name="remarks" class="form-control" placeholder="Write feedback here..." required></textarea> </div> <div class="modal-footer"> <button type="button" class="btn btn-sm btn-secondary" data-bs-close="modal">Close</button> <button type="submit" class="btn btn-sm btn-success">Save Feedback</button> </div> </div> </form> </div> <div class="modal fade" id="editModal<?= $i['id'] ?>" tabindex="-1"> <form method="POST" class="modal-dialog"> <input type="hidden" name="action" value="edit_interview"> <input type="hidden" name="interview_id" value="<?= $i['id'] ?>"> <input type="hidden" name="application_id" value="<?= $i['application_id'] ?>"> <div class="modal-content"> <div class="modal-header"><h5>Edit Interview Status & Feedback</h5></div> <div class="modal-body"> <label class="form-label fw-bold">Interview Workflow Status</label> <select name="status" class="form-select mb-3" onchange="toggleEditResult(this, <?= $i['id'] ?>)"> <option value="scheduled" <?= $i['status'] === 'scheduled' ? 'selected' : '' ?>>Scheduled (Pending Decision)</option> <option value="completed" <?= $i['status'] === 'completed' ? 'selected' : '' ?>>Completed</option> </select> <div id="editResultDiv<?= $i['id'] ?>" style="<?= $i['status'] === 'completed' ? '' : 'display: none;' ?>"> <label class="form-label fw-bold">Decision Outcome</label> <select name="result" class="form-select mb-3"> <option value="Selected" <?= ($i['recommendation'] ?? '') === 'Selected' ? 'selected' : '' ?>>Select Candidate</option> <option value="Rejected" <?= ($i['recommendation'] ?? '') === 'Rejected' ? 'selected' : '' ?>>Reject</option> </select> </div> <label class="form-label fw-bold">Remarks / Comments</label> <textarea name="remarks" class="form-control" required><?= j($i['comments'] ?: $i['remarks']) ?></textarea> </div> <div class="modal-footer"> <button type="button" class="btn btn-sm btn-secondary" data-bs-close="modal">Close</button> <button type="submit" class="btn btn-sm btn-dark">Update Changes</button> </div> </div> </form> </div> <?php endforeach; ?> <script> function toggleEditResult(selectEl, id) { const resDiv = document.getElementById('editResultDiv' + id); if (selectEl.value === 'completed') { resDiv.style.display = 'block'; } else { resDiv.style.display = 'none'; } } function printIsolatedDashboard() { var rawContents = document.getElementById('printableArea').innerHTML; var printWindow = window.open('', '', 'height=850,width=1200'); printWindow.document.write('<html><head><title>INTERVIEW SCHEDULES REPORT</title>'); // Inject dynamic CDN Bootstrap directly into print frame so structure looks clean printWindow.document.write('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">'); printWindow.document.write('<style>'); printWindow.document.write('body { font-family: system-ui, -apple-system, sans-serif; padding: 30px; color: #000; background-color: #fff !important; }'); printWindow.document.write('.action-column, th.action-column { display: none !important; }'); // Remove edit columns printWindow.document.write('table { width: 100% !important; border-collapse: collapse !important; }'); printWindow.document.write('th, td { border: 1px solid #dee2e6 !important; padding: 10px !important; font-size: 13px !important; }'); printWindow.document.write('.badge { color: #000 !important; background: #f0f0f0 !important; border: 1px solid #ccc !important; }'); printWindow.document.write('</style></head><body>'); // Clean Header printWindow.document.write('<div class="text-center mb-4">'); printWindow.document.write('<h2 class="fw-bold m-0 text-uppercase">Ganpati Textile</h2>'); printWindow.document.write('<h4 class="text-muted mt-1">Interview Schedules Report</h4>'); printWindow.document.write('<small class="text-secondary">Report Generated Date: ' + new Date().toLocaleDateString("en-GB") + '</small>'); printWindow.document.write('<hr class="my-3">'); printWindow.document.write('</div>'); printWindow.document.write(rawContents); printWindow.document.write('</body></html>'); printWindow.document.close(); // Let frame load the external bootstrap link before launching system modal setTimeout(function() { printWindow.focus(); printWindow.print(); printWindow.close(); }, 400); } </script> <?php require_once __DIR__ . '/partials/footer.php'; ?>