MERGE_UAT_BUG_FIXES
This commit is contained in:
commit
1c5a14475f
@ -73,6 +73,12 @@ class Acl
|
||||
'teams' => []
|
||||
],
|
||||
|
||||
// ===================== LOGIN DIAGNOSTIC =====================
|
||||
'#^/security/login-diagnostic#' => [
|
||||
'roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID],
|
||||
'teams' => []
|
||||
],
|
||||
|
||||
// ===================== INTERNAL TEST =====================
|
||||
'#^/test#' => [
|
||||
'roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID],
|
||||
|
||||
@ -594,6 +594,11 @@ $routes->group('security/rate-limits', ['filter' => 'authMVC'], function ($route
|
||||
$routes->post('unblock-user', 'RateLimitAdminController::unblockUser');
|
||||
});
|
||||
|
||||
$routes->group('security/login-diagnostic', ['filter' => 'authMVC'], function ($routes) {
|
||||
$routes->get('/', 'LoginDiagnosticController::index');
|
||||
$routes->post('diagnose', 'LoginDiagnosticController::diagnose');
|
||||
});
|
||||
|
||||
//saml - routes
|
||||
// $routes->group("employeeRest", ['filter' => ['appSignature','AuthApiRateLimitFilter'] ], function ($routes) {
|
||||
|
||||
|
||||
@ -1253,7 +1253,8 @@ class ClientController extends AdminController
|
||||
$data['is_member_modify_allowed'] = $this->request->getPost('is_member_modify_allowed') ? 1 : 0;
|
||||
$data['enrolment_visibility'] = $this->request->getPost('enrolment_visibility') ? 1 : 0;
|
||||
$data['is_lgbtq'] = $this->request->getPost('is_lgbtq') ? 1 : 0;
|
||||
$data['is_premium_summery'] = $this->request->getPost('is_premium_summery') ? 1 : 0;
|
||||
$premiumSummary = (int) $this->request->getPost('is_premium_summery');
|
||||
$data['is_premium_summery'] = in_array($premiumSummary, [0, 1, 2], true) ? $premiumSummary : 0;
|
||||
|
||||
|
||||
if ($policy_type_id == 1 || $policy_type_id == 2 || $policy_type_id == 6 || $policy_type_id == 7) {
|
||||
@ -1386,7 +1387,8 @@ class ClientController extends AdminController
|
||||
$data['policy_end_date'] = change_date_format($this->request->getPost('policy_end_date'), 'd-m-Y', 'Y-m-d');
|
||||
// $data['is_member_modify_allowed'] = $this->request->getPost('is_member_modify_allowed') ? 1 : 0;
|
||||
$data['is_lgbtq'] = $this->request->getPost('is_lgbtq') ? 1 : 0;
|
||||
$data['is_premium_summery'] = $this->request->getPost('is_premium_summery') ? 1 : 0;
|
||||
$premiumSummary = (int) $this->request->getPost('is_premium_summery');
|
||||
$data['is_premium_summery'] = in_array($premiumSummary, [0, 1, 2], true) ? $premiumSummary : 0;
|
||||
|
||||
if ($data['inception_type'] == 2) {
|
||||
$data['open_date'] = change_date_format($this->request->getPost('open_date'), 'd-m-Y', 'Y-m-d');
|
||||
|
||||
68
app/Controllers/LoginDiagnosticController.php
Normal file
68
app/Controllers/LoginDiagnosticController.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Helpers\LoginDiagnosticHelper;
|
||||
|
||||
/**
|
||||
* Admin-only employee login diagnostic (PRE + POST).
|
||||
* Does not modify existing auth controllers/models/views.
|
||||
*/
|
||||
class LoginDiagnosticController extends BaseController
|
||||
{
|
||||
public function index(): void
|
||||
{
|
||||
$email = trim((string) $this->request->getGet('email'));
|
||||
$mobile = trim((string) $this->request->getGet('mobile'));
|
||||
|
||||
$data = [
|
||||
'title' => 'Employee Login Diagnostic',
|
||||
'email' => $email,
|
||||
'mobile' => $mobile,
|
||||
'result' => null,
|
||||
'has_search' => false,
|
||||
];
|
||||
|
||||
if ($email !== '' || $mobile !== '') {
|
||||
$data['has_search'] = true;
|
||||
$data['result'] = LoginDiagnosticHelper::diagnose(
|
||||
$email !== '' ? $email : null,
|
||||
$mobile !== '' ? $mobile : null
|
||||
);
|
||||
}
|
||||
|
||||
echo view('admin/login_diagnostic', $data);
|
||||
}
|
||||
|
||||
public function diagnose()
|
||||
{
|
||||
$email = trim((string) $this->request->getPost('email'));
|
||||
$mobile = trim((string) $this->request->getPost('mobile'));
|
||||
|
||||
if ($email === '' && $mobile === '') {
|
||||
$json = $this->request->getJSON(true);
|
||||
if (is_array($json)) {
|
||||
$email = trim((string) ($json['email'] ?? ''));
|
||||
$mobile = trim((string) ($json['mobile'] ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->request->isAJAX() || str_contains((string) $this->request->getHeaderLine('Accept'), 'application/json')) {
|
||||
$result = LoginDiagnosticHelper::diagnose(
|
||||
$email !== '' ? $email : null,
|
||||
$mobile !== '' ? $mobile : null
|
||||
);
|
||||
return $this->response->setJSON($result);
|
||||
}
|
||||
|
||||
$query = [];
|
||||
if ($email !== '') {
|
||||
$query['email'] = $email;
|
||||
}
|
||||
if ($mobile !== '') {
|
||||
$query['mobile'] = $mobile;
|
||||
}
|
||||
|
||||
return redirect()->to(base_url('security/login-diagnostic?' . http_build_query($query)));
|
||||
}
|
||||
}
|
||||
1211
app/Helpers/LoginDiagnosticHelper.php
Normal file
1211
app/Helpers/LoginDiagnosticHelper.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -317,8 +317,7 @@ if(!function_exists('check_si'))
|
||||
$return_array['error'] = !empty($return_array['error']) ? ($return_array['error'].', '.'Sum insured not configured for this age slab') : 'Sum insured not configured for this age slab';
|
||||
}
|
||||
|
||||
if(empty($received_si))
|
||||
{
|
||||
if (isset($received_si) && trim((string) $received_si) === '') {
|
||||
$return_array['status'] = false;
|
||||
$return_array['error'] = "Sum insured value mandantory";
|
||||
}
|
||||
|
||||
632
app/Views/admin/login_diagnostic.php
Normal file
632
app/Views/admin/login_diagnostic.php
Normal file
@ -0,0 +1,632 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= esc($title ?? 'Employee Login Diagnostic') ?></title>
|
||||
<style>
|
||||
:root{
|
||||
--bg: #F6F8F9;
|
||||
--surface: #FFFFFF;
|
||||
--border: #E3E7EA;
|
||||
--border-strong: #CBD2D8;
|
||||
--text-primary: #16212B;
|
||||
--text-secondary: #5B6770;
|
||||
--text-muted: #8B959C;
|
||||
--teal: #0E8F9C;
|
||||
--teal-dark: #0A6B75;
|
||||
--teal-tint: #E7F5F6;
|
||||
--success-bg: #E4F5EC;
|
||||
--success-border: #B9E3CC;
|
||||
--success-text: #1B7A4C;
|
||||
--warn-bg: #FFF6E0;
|
||||
--warn-border: #F0D9A0;
|
||||
--warn-text: #8A5B00;
|
||||
--danger-bg: #FDECEE;
|
||||
--danger-border: #F0C4CB;
|
||||
--danger-text: #9B1C3A;
|
||||
--danger-code: #C43D6E;
|
||||
--low-badge-bg: #EDEFF1;
|
||||
--low-badge-text: #4A545C;
|
||||
--med-badge-bg: #FFF3CD;
|
||||
--med-badge-text: #664D03;
|
||||
--high-badge-bg: #F8D7DA;
|
||||
--high-badge-text: #842029;
|
||||
--mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
|
||||
--sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 10px;
|
||||
}
|
||||
*{box-sizing:border-box;}
|
||||
body{
|
||||
margin:0;
|
||||
background:var(--bg);
|
||||
font-family:var(--sans);
|
||||
color:var(--text-primary);
|
||||
padding:32px 40px 64px;
|
||||
}
|
||||
.wrap{max-width:1320px;margin:0 auto;}
|
||||
|
||||
.page-head{margin-bottom:24px;}
|
||||
.page-head h1{font-size:22px;font-weight:600;margin:0 0 4px;letter-spacing:-0.01em;}
|
||||
.page-head p{margin:0;font-size:13.5px;color:var(--text-secondary);}
|
||||
.page-head p b{color:var(--text-primary);font-weight:600;}
|
||||
|
||||
.card{
|
||||
background:var(--surface);
|
||||
border:1px solid var(--border);
|
||||
border-radius:var(--radius-md);
|
||||
}
|
||||
|
||||
.search-card{padding:20px 24px;margin-bottom:16px;}
|
||||
.search-grid{display:grid;grid-template-columns:1fr 1fr auto auto;gap:16px;align-items:end;}
|
||||
.field label{display:block;font-size:12.5px;font-weight:600;color:var(--text-primary);margin-bottom:6px;}
|
||||
.field label span{font-weight:400;color:var(--text-muted);font-family:var(--mono);font-size:11.5px;margin-left:2px;}
|
||||
.field input{
|
||||
width:100%;height:38px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);
|
||||
padding:0 12px;font-size:13.5px;font-family:var(--sans);color:var(--text-primary);
|
||||
background:#FCFDFD;
|
||||
}
|
||||
.field input::placeholder{color:var(--text-muted);}
|
||||
.field input:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px rgba(14,143,156,0.12);}
|
||||
.btn{
|
||||
height:38px;padding:0 20px;border-radius:var(--radius-sm);font-size:13.5px;font-weight:600;
|
||||
border:1px solid transparent;cursor:pointer;white-space:nowrap;text-decoration:none;
|
||||
display:inline-flex;align-items:center;justify-content:center;
|
||||
}
|
||||
.btn-primary{background:var(--teal);color:#fff;}
|
||||
.btn-primary:hover{background:var(--teal-dark);}
|
||||
.btn-ghost{background:#fff;border-color:var(--border-strong);color:var(--text-primary);}
|
||||
.btn-ghost:hover{background:#F5F6F7;}
|
||||
.search-hint{grid-column:1/-1;font-size:12px;color:var(--text-muted);margin:2px 0 0;}
|
||||
.search-hint b{color:var(--text-secondary);font-weight:600;}
|
||||
|
||||
.status-banner{
|
||||
display:flex;align-items:center;justify-content:space-between;
|
||||
border-radius:var(--radius-md);padding:16px 22px;margin-bottom:16px;
|
||||
}
|
||||
.status-ok{background:var(--success-bg);border:1px solid var(--success-border);}
|
||||
.status-ok .txt strong{color:var(--success-text);}
|
||||
.status-ok .txt span{color:#2C5F45;}
|
||||
.status-ok .copy-btn{border-color:var(--success-border);color:var(--success-text);}
|
||||
.status-ok .copy-btn:hover{background:#F1FBF6;}
|
||||
.status-warn,.status-partial{background:var(--warn-bg);border:1px solid var(--warn-border);}
|
||||
.status-warn .txt strong,.status-partial .txt strong{color:var(--warn-text);}
|
||||
.status-warn .txt span,.status-partial .txt span{color:#6B4A10;}
|
||||
.status-warn .copy-btn,.status-partial .copy-btn{border-color:var(--warn-border);color:var(--warn-text);}
|
||||
.status-fail{background:var(--danger-bg);border:1px solid var(--danger-border);}
|
||||
.status-fail .txt strong{color:var(--danger-text);}
|
||||
.status-fail .txt span{color:#7A2A3A;}
|
||||
.status-fail .copy-btn{border-color:var(--danger-border);color:var(--danger-text);}
|
||||
.status-banner .txt strong{display:block;font-size:14.5px;font-weight:700;margin-bottom:2px;}
|
||||
.status-banner .txt span{font-size:13px;}
|
||||
.status-banner .copy-btn{
|
||||
background:#fff;font-size:12.5px;font-weight:600;padding:8px 14px;border-radius:var(--radius-sm);
|
||||
cursor:pointer;border:1px solid;
|
||||
}
|
||||
|
||||
.section-title{
|
||||
font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;
|
||||
color:var(--text-secondary);padding:14px 20px;background:#F8F9FA;
|
||||
border:1px solid var(--border);border-bottom:none;border-radius:var(--radius-md) var(--radius-md) 0 0;
|
||||
}
|
||||
.section-title span{text-transform:none;font-weight:400;letter-spacing:0;color:var(--text-muted);}
|
||||
table{width:100%;border-collapse:collapse;}
|
||||
.problems-table{border:1px solid var(--border);border-radius:0 0 var(--radius-md) var(--radius-md);overflow:hidden;margin-bottom:20px;background:#fff;}
|
||||
.problems-table th{
|
||||
text-align:left;font-size:12px;font-weight:700;color:var(--text-secondary);
|
||||
padding:10px 20px;border-bottom:1px solid var(--border);background:#fff;
|
||||
}
|
||||
.problems-table td{
|
||||
padding:12px 20px;font-size:13.5px;border-bottom:1px solid var(--border);
|
||||
border-left:3px solid var(--teal);vertical-align:middle;
|
||||
}
|
||||
.problems-table tr:last-child td{border-bottom:none;}
|
||||
.problems-table tr:nth-child(even) td{background:#FAFBFC;}
|
||||
.problems-table .empty{border-left-color:transparent;color:var(--text-muted);text-align:center;}
|
||||
.badge{
|
||||
display:inline-block;font-size:11px;font-weight:700;padding:3px 9px;border-radius:4px;letter-spacing:0.03em;
|
||||
}
|
||||
.badge-low{background:var(--low-badge-bg);color:var(--low-badge-text);}
|
||||
.badge-medium{background:var(--med-badge-bg);color:var(--med-badge-text);}
|
||||
.badge-high{background:var(--high-badge-bg);color:var(--high-badge-text);}
|
||||
.code{font-family:var(--mono);font-size:12.5px;color:var(--danger-code);font-weight:600;}
|
||||
.fix-text{color:var(--text-secondary);}
|
||||
|
||||
.compare-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px;}
|
||||
.compare-card{border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;background:#fff;}
|
||||
.compare-head{
|
||||
padding:14px 20px;background:#F8F9FA;border-bottom:1px solid var(--border);
|
||||
font-size:13px;font-weight:700;color:var(--text-primary);
|
||||
}
|
||||
.compare-head span{font-weight:400;color:var(--text-muted);}
|
||||
.kv-table td{padding:10px 20px;font-size:13px;border-bottom:1px solid var(--border);}
|
||||
.kv-table tr:last-child td{border-bottom:none;}
|
||||
.kv-table tr:nth-child(even) td{background:#FAFBFC;}
|
||||
.kv-key{color:var(--text-secondary);font-weight:600;width:44%;}
|
||||
.kv-val{color:var(--text-primary);font-family:var(--mono);font-size:12.5px;}
|
||||
.check{color:#1B9C56;font-weight:700;}
|
||||
.cross{color:var(--danger-code);font-weight:700;}
|
||||
.val-flag{color:var(--danger-code);font-weight:700;}
|
||||
.alert-inline{margin:12px 20px;padding:10px 12px;border-radius:var(--radius-sm);background:var(--warn-bg);border:1px solid var(--warn-border);color:var(--warn-text);font-size:12.5px;}
|
||||
|
||||
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--border);margin-bottom:0;padding:0 4px;}
|
||||
.tab{
|
||||
padding:11px 18px;font-size:13px;font-weight:600;color:var(--text-secondary);
|
||||
cursor:pointer;border-bottom:2px solid transparent;background:none;border-top:none;border-left:none;border-right:none;
|
||||
font-family:var(--sans);
|
||||
}
|
||||
.tab.active{color:var(--teal-dark);border-bottom-color:var(--teal);}
|
||||
.tab:hover:not(.active){color:var(--text-primary);}
|
||||
.tab-panel{border:1px solid var(--border);border-top:none;border-radius:0 0 var(--radius-md) var(--radius-md);overflow:hidden;background:#fff;display:none;}
|
||||
.tab-panel.active{display:block;}
|
||||
.cred-table th{
|
||||
text-align:left;font-size:12px;font-weight:700;color:var(--text-secondary);
|
||||
padding:12px 20px;background:#F8F9FA;border-bottom:1px solid var(--border);
|
||||
}
|
||||
.cred-table th.center, .cred-table td.center{text-align:left;width:22%;}
|
||||
.cred-table td{padding:11px 20px;font-size:13.5px;border-bottom:1px solid var(--border);}
|
||||
.cred-table tr:last-child td{border-bottom:none;}
|
||||
.cred-table tr:nth-child(even) td{background:#FAFBFC;}
|
||||
.cred-key{font-weight:600;color:var(--text-primary);}
|
||||
.val-yes{color:#1B9C56;font-weight:600;}
|
||||
.val-no{color:var(--text-muted);}
|
||||
.val-raw{font-family:var(--mono);color:var(--danger-code);font-weight:600;}
|
||||
.muted{color:var(--text-muted);font-size:13px;padding:16px 20px;}
|
||||
.dup-wrap{padding:16px 20px;}
|
||||
.dup-wrap h6{margin:0 0 10px;font-size:13px;font-weight:700;}
|
||||
.dup-wrap h6 + .dup-table, .dup-wrap .dup-block{margin-bottom:18px;}
|
||||
.dup-subhead{font-size:12px;font-weight:700;color:var(--text-secondary);margin:14px 0 8px;text-transform:uppercase;letter-spacing:0.03em;}
|
||||
.dup-subhead .count{font-weight:600;color:var(--text-muted);text-transform:none;letter-spacing:0;}
|
||||
.dup-table{border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden;}
|
||||
.dup-table th,.dup-table td{padding:8px 12px;font-size:12px;border-bottom:1px solid var(--border);text-align:left;}
|
||||
.dup-table th{background:#F8F9FA;font-weight:700;color:var(--text-secondary);}
|
||||
.dup-table tr:last-child td{border-bottom:none;}
|
||||
.winner{display:inline-block;background:var(--success-bg);color:var(--success-text);font-size:10px;font-weight:700;padding:2px 6px;border-radius:4px;margin-right:4px;}
|
||||
.dup-badge{display:inline-block;font-size:10px;font-weight:700;padding:2px 6px;border-radius:4px;}
|
||||
.dup-self{background:var(--danger-bg);color:var(--danger-text);}
|
||||
.dup-family{background:var(--warn-bg);color:var(--warn-text);}
|
||||
.row-self-dup td{background:#FDECEE !important;}
|
||||
.row-family-dup td{background:#FFF8E8 !important;}
|
||||
.problems-table tr.sev-high td{border-left-color:var(--danger-text);background:#FDF2F4;}
|
||||
.problems-table tr.sev-medium td{border-left-color:#C9A227;}
|
||||
.problems-table tr.sev-low td{border-left-color:var(--text-muted);}
|
||||
.window-open{color:#1B9C56;font-weight:700;}
|
||||
.window-closed{color:var(--danger-text);font-weight:700;}
|
||||
.window-pending{color:var(--warn-text);font-weight:700;}
|
||||
.window-missing{color:var(--text-muted);font-weight:600;}
|
||||
.policy-wrap{padding:16px 20px;}
|
||||
.policy-wrap h6{margin:0 0 10px;font-size:13px;font-weight:700;}
|
||||
.policy-note{font-size:12px;color:var(--text-muted);margin:0 0 12px;}
|
||||
|
||||
@media (max-width:900px){
|
||||
body{padding:20px 16px 40px;}
|
||||
.search-grid{grid-template-columns:1fr;}
|
||||
.compare-grid{grid-template-columns:1fr;}
|
||||
.status-banner{flex-direction:column;align-items:flex-start;gap:12px;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
|
||||
<div class="page-head">
|
||||
<h1>Employee login diagnostic</h1>
|
||||
<p><b>PRE</b> (enrollment) + <b>POST</b> (live) · read-only · does not send OTP</p>
|
||||
</div>
|
||||
|
||||
<form method="get" action="<?= base_url('security/login-diagnostic') ?>" class="card search-card">
|
||||
<div class="search-grid">
|
||||
<div class="field">
|
||||
<label>Email <span>email_corporate</span></label>
|
||||
<input type="text" name="email" value="<?= esc($email ?? '') ?>" placeholder="user@company.com">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Mobile</label>
|
||||
<input type="text" name="mobile" value="<?= esc($mobile ?? '') ?>" placeholder="10-digit mobile">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Diagnose</button>
|
||||
<a class="btn btn-ghost" href="<?= base_url('security/login-diagnostic') ?>">Clear</a>
|
||||
<p class="search-hint">If both are filled, login logic uses <b>mobile first</b> (same as auth APIs).</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if (! empty($has_search) && is_array($result ?? null)): ?>
|
||||
<?php
|
||||
$v = $result['verdict'] ?? 'WILL_FAIL';
|
||||
$bannerClass = match ($v) {
|
||||
'OK' => 'status-ok',
|
||||
'OK_WITH_WARNINGS' => 'status-warn',
|
||||
'PARTIAL' => 'status-partial',
|
||||
default => 'status-fail',
|
||||
};
|
||||
$pre = $result['pre'] ?? [];
|
||||
$post = $result['post'] ?? [];
|
||||
$merge = $result['merge'] ?? [];
|
||||
$problems = $result['problems'] ?? [];
|
||||
$connectivity = $result['connectivity'] ?? [];
|
||||
$pc = $pre['credentials'] ?? [];
|
||||
$oc = $post['credentials'] ?? [];
|
||||
$pt = $pre['token'] ?? [];
|
||||
$ot = $post['token'] ?? [];
|
||||
$yn = static fn ($ok) => $ok ? '<span class="val-yes">Yes</span>' : '<span class="val-no">No</span>';
|
||||
$rawFlag = static function ($val): string {
|
||||
if ($val === null || $val === '') {
|
||||
return 'null';
|
||||
}
|
||||
return (string) $val;
|
||||
};
|
||||
$mark = static fn (bool $ok) => $ok ? '<span class="check">✓</span>' : '<span class="cross">✗</span>';
|
||||
?>
|
||||
|
||||
<div class="status-banner <?= esc($bannerClass) ?>">
|
||||
<div class="txt">
|
||||
<strong><?= esc($v) ?></strong>
|
||||
<span><?= esc($result['verdict_message'] ?? '') ?></span>
|
||||
</div>
|
||||
<button type="button" class="copy-btn" id="copyDiagSummary">Copy summary</button>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Problems <span>(failed checks only)</span></div>
|
||||
<table class="problems-table">
|
||||
<tr>
|
||||
<th style="width:80px;">Severity</th>
|
||||
<th style="width:190px;">Code</th>
|
||||
<th>Message</th>
|
||||
<th style="width:340px;">Fix</th>
|
||||
</tr>
|
||||
<?php if (empty($problems)): ?>
|
||||
<tr><td class="empty" colspan="4">No problems detected.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($problems as $p): ?>
|
||||
<?php $sev = strtolower((string) ($p['severity'] ?? 'low')); ?>
|
||||
<tr class="sev-<?= esc($sev) ?>">
|
||||
<td><span class="badge badge-<?= esc($sev) ?>"><?= esc(strtoupper($sev)) ?></span></td>
|
||||
<td><span class="code"><?= esc($p['code'] ?? '') ?></span></td>
|
||||
<td><?= esc($p['message'] ?? '') ?></td>
|
||||
<td class="fix-text"><?= esc($p['fix'] ?? '') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
|
||||
<div class="compare-grid">
|
||||
<div class="compare-card">
|
||||
<div class="compare-head">PRE <span>(enrollment)</span></div>
|
||||
<?= view('admin/login_diagnostic_side', ['side' => $pre, 'mark' => $mark]) ?>
|
||||
</div>
|
||||
<div class="compare-card">
|
||||
<div class="compare-head">POST <span>(live)</span></div>
|
||||
<?= view('admin/login_diagnostic_side', ['side' => $post, 'mark' => $mark]) ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs" role="tablist">
|
||||
<button type="button" class="tab active" data-tab="merge">Merge</button>
|
||||
<button type="button" class="tab" data-tab="dup">Duplicates</button>
|
||||
<button type="button" class="tab" data-tab="policies">Policies</button>
|
||||
<button type="button" class="tab" data-tab="wellness">Wellness</button>
|
||||
<button type="button" class="tab" data-tab="cred">Credentials</button>
|
||||
<button type="button" class="tab" data-tab="token">Token</button>
|
||||
<button type="button" class="tab" data-tab="conn">Connectivity</button>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel active" id="panel-merge">
|
||||
<table class="cred-table">
|
||||
<tr><td class="cred-key">PRE eligible</td><td><?= ! empty($merge['pre_eligible']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<tr><td class="cred-key">POST eligible</td><td><?= ! empty($merge['post_eligible']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<tr><td class="cred-key">PRE short_name</td><td class="val-raw"><?= esc((string) ($merge['pre_short_name'] ?? '')) ?></td></tr>
|
||||
<tr><td class="cred-key">POST short_name</td><td class="val-raw"><?= esc((string) ($merge['post_short_name'] ?? '')) ?></td></tr>
|
||||
<tr><td class="cred-key">short_name match</td><td><?= isset($merge['short_name_match']) ? ($merge['short_name_match'] ? 'Yes' : 'No') : '—' ?></td></tr>
|
||||
<tr><td class="cred-key">PRE created_at</td><td class="val-raw"><?= esc((string) ($merge['pre_created_at'] ?? '—')) ?></td></tr>
|
||||
<tr><td class="cred-key">POST created_at</td><td class="val-raw"><?= esc((string) ($merge['post_created_at'] ?? '—')) ?></td></tr>
|
||||
<tr><td class="cred-key">Would return both</td><td><?= ! empty($merge['would_return_both']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<tr><td class="cred-key">Winner</td><td><b><?= esc((string) ($merge['winner'] ?? '—')) ?></b></td></tr>
|
||||
<tr><td class="cred-key">OTP sync possible</td><td><?= ! empty($merge['otp_sync_possible']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<tr><td class="cred-key">Reason</td><td class="fix-text"><?= esc((string) ($merge['reason'] ?? '')) ?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-dup">
|
||||
<div class="dup-wrap">
|
||||
<?php
|
||||
$preDup = $pre['duplicates'] ?? [];
|
||||
$postDup = $post['duplicates'] ?? [];
|
||||
$renderSideDups = static function (string $title, array $side, array $dup): void {
|
||||
$selfRows = $dup['self_rows'] ?? [];
|
||||
$familyRows = $dup['family_rows'] ?? [];
|
||||
// Fallback if older payload
|
||||
if ($selfRows === [] && $familyRows === [] && ! empty($side['raw_matches'])) {
|
||||
foreach ($side['raw_matches'] as $r) {
|
||||
if (strtolower(trim((string) ($r['relationship'] ?? ''))) === 'self') {
|
||||
$selfRows[] = $r;
|
||||
} else {
|
||||
$familyRows[] = $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="dup-block">
|
||||
<h6><?= esc($title) ?></h6>
|
||||
<div class="dup-subhead">Self <span class="count">(<?= count($selfRows) ?>)</span></div>
|
||||
<?= view('admin/login_diagnostic_matches', ['rows' => $selfRows]) ?>
|
||||
<div class="dup-subhead">Family <span class="count">(<?= count($familyRows) ?>)</span></div>
|
||||
<?= view('admin/login_diagnostic_matches', ['rows' => $familyRows]) ?>
|
||||
</div>
|
||||
<?php
|
||||
};
|
||||
?>
|
||||
<?php $renderSideDups('PRE raw matches', $pre, $preDup); ?>
|
||||
<?php if (! empty($pre['raw_by_personal'])): ?>
|
||||
<div class="dup-block">
|
||||
<h6>PRE matches on email_personal only</h6>
|
||||
<?= view('admin/login_diagnostic_matches', ['rows' => $pre['raw_by_personal']]) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php $renderSideDups('POST raw matches', $post, $postDup); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-policies">
|
||||
<div class="policy-wrap">
|
||||
<p class="policy-note">PRE: enrollment open/close on <code>employee_polices</code>. POST: live policy mapping. Wellness details are on the <b>Wellness</b> tab (POST only).</p>
|
||||
<?php if (! empty($pre['policies_error'])): ?>
|
||||
<div class="alert-inline">PRE policies error: <?= esc($pre['policies_error']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($post['policies_error'])): ?>
|
||||
<div class="alert-inline">POST policies error: <?= esc($post['policies_error']) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$windowClass = static function (string $w): string {
|
||||
return match ($w) {
|
||||
'OPEN' => 'window-open',
|
||||
'CLOSED' => 'window-closed',
|
||||
'NOT_STARTED' => 'window-pending',
|
||||
default => 'window-missing',
|
||||
};
|
||||
};
|
||||
$renderPolicies = static function (string $title, array $policies, bool $showEnrollment) use ($windowClass): void {
|
||||
?>
|
||||
<div class="dup-block">
|
||||
<h6><?= esc($title) ?> <span class="count">(<?= count($policies) ?>)</span></h6>
|
||||
<?php if (empty($policies)): ?>
|
||||
<p class="muted" style="padding:0;">None</p>
|
||||
<?php else: ?>
|
||||
<div class="dup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Emp policy</th>
|
||||
<th>Client policy</th>
|
||||
<th>Policy no</th>
|
||||
<th>EP status</th>
|
||||
<th>EP active</th>
|
||||
<th>Policy period</th>
|
||||
<?php if ($showEnrollment): ?>
|
||||
<th>Enrollment open</th>
|
||||
<th>Enrollment close</th>
|
||||
<th>Window</th>
|
||||
<?php else: ?>
|
||||
<th>CP open_for_enrollment</th>
|
||||
<th>CP open/close</th>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($policies as $pol): ?>
|
||||
<?php
|
||||
$w = (string) ($pol['enrollment_window'] ?? '');
|
||||
$rowClass = ($showEnrollment && in_array($w, ['CLOSED', 'NOT_STARTED', 'MISSING'], true)) ? 'row-family-dup' : '';
|
||||
if ($showEnrollment && $w === 'CLOSED') {
|
||||
$rowClass = 'row-self-dup';
|
||||
}
|
||||
?>
|
||||
<tr class="<?= esc($rowClass) ?>">
|
||||
<td><?= esc((string) ($pol['emp_policy_id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['client_policy_id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['policy_no'] ?? '—')) ?></td>
|
||||
<td><?= esc((string) ($pol['emp_policy_status'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['emp_policy_is_active'] ?? '')) ?></td>
|
||||
<td><?= esc((string) (($pol['policy_start_date'] ?? '—') . ' → ' . ($pol['policy_end_date'] ?? '—'))) ?></td>
|
||||
<?php if ($showEnrollment): ?>
|
||||
<td class="val-raw"><?= esc((string) ($pol['enrollment_open_date'] ?? 'null')) ?></td>
|
||||
<td class="val-raw"><?= esc((string) ($pol['enrollment_close_date'] ?? 'null')) ?></td>
|
||||
<td class="<?= esc($windowClass($w)) ?>"><?= esc($w) ?></td>
|
||||
<?php else: ?>
|
||||
<td><?= esc((string) ($pol['open_for_enrollment'] ?? '—')) ?></td>
|
||||
<td><?= esc((string) (($pol['client_open_date'] ?? '—') . ' → ' . ($pol['client_close_date'] ?? '—'))) ?></td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
};
|
||||
$renderPolicies('PRE employee policies (enrollment dates)', $pre['policies'] ?? [], true);
|
||||
$renderPolicies('POST employee policies (live mapping)', $post['policies'] ?? [], false);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-wellness">
|
||||
<div class="policy-wrap">
|
||||
<p class="policy-note"><b>POST only.</b> Wellness SSO needs <code>wellness_onboard</code> not null and not <code>0</code> (same as <code>getWellnessUrl</code>). PRE has no wellness fields.</p>
|
||||
<?php
|
||||
$postPolicies = $post['policies'] ?? [];
|
||||
$wellnessReadyCount = 0;
|
||||
$wellnessPlanCount = 0;
|
||||
foreach ($postPolicies as $wp) {
|
||||
if (! empty($wp['wellness_ready'])) {
|
||||
$wellnessReadyCount++;
|
||||
}
|
||||
$pid = $wp['wellness_plan_id'] ?? null;
|
||||
if ($pid !== null && $pid !== '' && (string) $pid !== '0') {
|
||||
$wellnessPlanCount++;
|
||||
}
|
||||
}
|
||||
$overallReady = $wellnessReadyCount > 0;
|
||||
?>
|
||||
<table class="cred-table" style="margin-bottom:16px;">
|
||||
<tr>
|
||||
<td class="cred-key">Overall wellness ready</td>
|
||||
<td class="<?= $overallReady ? 'window-open' : 'window-closed' ?>">
|
||||
<?= $overallReady ? 'Yes' : 'No' ?>
|
||||
<span class="fix-text">(<?= (int) $wellnessReadyCount ?> of <?= count($postPolicies) ?> policies onboarded)</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cred-key">Policies with wellness_plan_id</td>
|
||||
<td><?= (int) $wellnessPlanCount ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cred-key">Rule</td>
|
||||
<td class="fix-text">Ready = <code>wellness_onboard</code> is not null and not 0</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="dup-block">
|
||||
<h6>POST wellness by policy <span class="count">(<?= count($postPolicies) ?>)</span></h6>
|
||||
<?php if (empty($postPolicies)): ?>
|
||||
<p class="muted" style="padding:0;">No POST employee policies to check.</p>
|
||||
<?php else: ?>
|
||||
<div class="dup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Emp policy</th>
|
||||
<th>Client policy</th>
|
||||
<th>Policy no</th>
|
||||
<th>EP status</th>
|
||||
<th>EP active</th>
|
||||
<th>wellness_onboard</th>
|
||||
<th>Wellness ready</th>
|
||||
<th>wellness_plan_id</th>
|
||||
<th>wellness_vendor_id</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($postPolicies as $pol): ?>
|
||||
<?php $ready = ! empty($pol['wellness_ready']); ?>
|
||||
<tr class="<?= $ready ? '' : 'row-self-dup' ?>">
|
||||
<td><?= esc((string) ($pol['emp_policy_id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['client_policy_id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['policy_no'] ?? '—')) ?></td>
|
||||
<td><?= esc((string) ($pol['emp_policy_status'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($pol['emp_policy_is_active'] ?? '')) ?></td>
|
||||
<td class="val-raw"><?= esc((string) ($pol['wellness_onboard_raw'] ?? 'null')) ?></td>
|
||||
<td class="<?= $ready ? 'window-open' : 'window-closed' ?>"><?= $ready ? 'Yes' : 'No' ?></td>
|
||||
<td class="val-raw"><?= esc((string) (($pol['wellness_plan_id'] ?? '') !== '' && ($pol['wellness_plan_id'] ?? null) !== null ? $pol['wellness_plan_id'] : 'null')) ?></td>
|
||||
<td class="val-raw"><?= esc((string) (($pol['wellness_vendor_id'] ?? '') !== '' && ($pol['wellness_vendor_id'] ?? null) !== null ? $pol['wellness_vendor_id'] : 'null')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-cred">
|
||||
<table class="cred-table">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="center">PRE</th>
|
||||
<th class="center">POST</th>
|
||||
</tr>
|
||||
<tr><td class="cred-key">OTP set</td><td class="center"><?= $yn(! empty($pc['otp_set'])) ?></td><td class="center"><?= $yn(! empty($oc['otp_set'])) ?></td></tr>
|
||||
<tr><td class="cred-key">MPIN set</td><td class="center"><?= $yn(! empty($pc['mpin_set'])) ?></td><td class="center"><?= $yn(! empty($oc['mpin_set'])) ?></td></tr>
|
||||
<tr><td class="cred-key">MPIN skipped</td><td class="center"><?= $yn(! empty($pc['mpin_skipped'])) ?></td><td class="center"><?= $yn(! empty($oc['mpin_skipped'])) ?></td></tr>
|
||||
<tr><td class="cred-key">Biometric set</td><td class="center"><?= $yn(! empty($pc['biometric_set'])) ?></td><td class="center"><?= $yn(! empty($oc['biometric_set'])) ?></td></tr>
|
||||
<tr>
|
||||
<td class="cred-key">is_biometric_enabled <span style="font-weight:400;color:var(--text-muted);">(raw)</span></td>
|
||||
<td class="center val-raw"><?= esc($rawFlag($pc['is_biometric_enabled'] ?? null)) ?></td>
|
||||
<td class="center val-raw"><?= esc($rawFlag($oc['is_biometric_enabled'] ?? null)) ?></td>
|
||||
</tr>
|
||||
<tr><td class="cred-key">Password set</td><td class="center"><?= $yn(! empty($pc['password_set'])) ?></td><td class="center"><?= $yn(! empty($oc['password_set'])) ?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-token">
|
||||
<table class="cred-table">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="center">PRE</th>
|
||||
<th class="center">POST</th>
|
||||
</tr>
|
||||
<tr><td class="cred-key">Status</td><td class="center"><?= esc((string) ($pt['status'] ?? '—')) ?></td><td class="center"><?= esc((string) ($ot['status'] ?? '—')) ?></td></tr>
|
||||
<tr><td class="cred-key">Details</td><td class="center fix-text"><?= esc((string) ($pt['human'] ?? '—')) ?></td><td class="center fix-text"><?= esc((string) ($ot['human'] ?? '—')) ?></td></tr>
|
||||
<tr><td class="cred-key">TOKENTIMEOUT env</td><td colspan="2"><?= esc((string) ($pt['tokentimeout_env'] ?? $ot['tokentimeout_env'] ?? '—')) ?> seconds</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" id="panel-conn">
|
||||
<table class="cred-table">
|
||||
<tr><td class="cred-key">POST_ENROLLMENT_BASEURL</td><td class="val-raw"><?= esc((string) ($connectivity['base_url'] ?? '')) ?></td></tr>
|
||||
<tr><td class="cred-key">App-Signature configured</td><td><?= ! empty($connectivity['app_signature']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<tr><td class="cred-key">POST API reachable</td><td><?= ! empty($connectivity['api_reachable']) ? 'Yes' : 'No' ?> (HTTP <?= esc((string) ($connectivity['api_http_code'] ?? '—')) ?>)</td></tr>
|
||||
<tr><td class="cred-key">API message</td><td class="fix-text"><?= esc((string) ($connectivity['api_message'] ?? '')) ?></td></tr>
|
||||
<tr><td class="cred-key">postDB connected</td><td><?= ! empty($connectivity['post_db']) ? 'Yes' : 'No' ?></td></tr>
|
||||
<?php if (! empty($connectivity['post_db_message'])): ?>
|
||||
<tr><td class="cred-key">postDB error</td><td class="fix-text"><?= esc((string) $connectivity['post_db_message']) ?></td></tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var tabs = document.querySelectorAll('.tab');
|
||||
var panels = {
|
||||
merge: document.getElementById('panel-merge'),
|
||||
dup: document.getElementById('panel-dup'),
|
||||
policies: document.getElementById('panel-policies'),
|
||||
wellness: document.getElementById('panel-wellness'),
|
||||
cred: document.getElementById('panel-cred'),
|
||||
token: document.getElementById('panel-token'),
|
||||
conn: document.getElementById('panel-conn')
|
||||
};
|
||||
tabs.forEach(function (tab) {
|
||||
tab.addEventListener('click', function () {
|
||||
tabs.forEach(function (t) { t.classList.remove('active'); });
|
||||
Object.keys(panels).forEach(function (k) { panels[k].classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
var key = tab.getAttribute('data-tab');
|
||||
if (panels[key]) panels[key].classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
var btn = document.getElementById('copyDiagSummary');
|
||||
if (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var lines = [];
|
||||
lines.push('Verdict: <?= esc($v, 'js') ?>');
|
||||
lines.push('<?= esc($result['verdict_message'] ?? '', 'js') ?>');
|
||||
lines.push('Input email=<?= esc($result['input']['email'] ?? '', 'js') ?> mobile=<?= esc($result['input']['mobile'] ?? '', 'js') ?>');
|
||||
lines.push('Merge winner: <?= esc($merge['winner'] ?? '', 'js') ?>');
|
||||
<?php foreach ($problems as $p): ?>
|
||||
lines.push('[<?= esc(strtoupper((string) ($p['severity'] ?? '')), 'js') ?>] <?= esc($p['code'] ?? '', 'js') ?>: <?= esc($p['message'] ?? '', 'js') ?>');
|
||||
<?php endforeach; ?>
|
||||
navigator.clipboard.writeText(lines.join('\n')).then(function () {
|
||||
btn.textContent = 'Copied';
|
||||
setTimeout(function () { btn.textContent = 'Copy summary'; }, 1500);
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php elseif (! empty($has_search)): ?>
|
||||
<div class="status-banner status-fail">
|
||||
<div class="txt">
|
||||
<strong>WILL_FAIL</strong>
|
||||
<span>No diagnostic result returned.</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
62
app/Views/admin/login_diagnostic_matches.php
Normal file
62
app/Views/admin/login_diagnostic_matches.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php /** @var array $rows */ ?>
|
||||
<?php if (empty($rows)): ?>
|
||||
<p class="muted" style="padding:0;">None</p>
|
||||
<?php else: ?>
|
||||
<div class="dup-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>ID</th>
|
||||
<th>Client</th>
|
||||
<th>Emp code</th>
|
||||
<th>Name</th>
|
||||
<th>Rel</th>
|
||||
<th>Status</th>
|
||||
<th>Active</th>
|
||||
<th>Mobile</th>
|
||||
<th>Email corp</th>
|
||||
<th>Policies</th>
|
||||
<th>Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($rows as $row): ?>
|
||||
<?php
|
||||
$rowClass = '';
|
||||
if (! empty($row['is_self_duplicate']) || ! empty($row['is_cross_self_dup'])) {
|
||||
$rowClass = 'row-self-dup';
|
||||
} elseif (! empty($row['is_family_duplicate'])) {
|
||||
$rowClass = 'row-family-dup';
|
||||
}
|
||||
?>
|
||||
<tr class="<?= esc($rowClass) ?>">
|
||||
<td>
|
||||
<?php if (! empty($row['is_login_winner'])): ?>
|
||||
<span class="winner">WINNER</span>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($row['dup_badge'])): ?>
|
||||
<span class="dup-badge <?= ! empty($row['is_self_duplicate']) || ! empty($row['is_cross_self_dup']) ? 'dup-self' : 'dup-family' ?>">
|
||||
<?= esc((string) $row['dup_badge']) ?>
|
||||
</span>
|
||||
<?php elseif (! empty($row['is_login_pick_if_filters_passed'])): ?>
|
||||
<span class="winner" style="background:#EDEFF1;color:#4A545C;">highest id</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= esc((string) ($row['id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['client_id'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['emp_code'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['name'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['relationship'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['emp_status'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['is_active'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['mobile'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['email_corporate'] ?? '')) ?></td>
|
||||
<td><?= esc((string) ($row['policies'] ?? '—')) ?></td>
|
||||
<td><?= esc((string) ($row['created_at'] ?? '')) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
48
app/Views/admin/login_diagnostic_side.php
Normal file
48
app/Views/admin/login_diagnostic_side.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/** @var array $side */
|
||||
/** @var callable $mark */
|
||||
$fs = $side['filters_summary'] ?? [];
|
||||
$eligible = $side['eligible'] ?? null;
|
||||
$error = $side['error'] ?? null;
|
||||
?>
|
||||
<?php if (! empty($error)): ?>
|
||||
<div class="alert-inline"><?= esc($error) ?></div>
|
||||
<?php endif; ?>
|
||||
<table class="kv-table">
|
||||
<tr>
|
||||
<td class="kv-key">Raw found</td>
|
||||
<td class="kv-val">
|
||||
<?= ! empty($side['raw_matches'])
|
||||
? $mark(true) . ' Yes (' . count($side['raw_matches']) . ')'
|
||||
: $mark(false) . ' No' ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="kv-key">Eligible for login</td>
|
||||
<td class="kv-val"><?= ! empty($eligible) ? $mark(true) . ' Yes' : $mark(false) . ' No' ?></td>
|
||||
</tr>
|
||||
<tr><td class="kv-key">self</td><td class="kv-val"><?= isset($fs['self']) ? $mark((bool) $fs['self']) : '—' ?></td></tr>
|
||||
<tr><td class="kv-key">is_active</td><td class="kv-val"><?= isset($fs['is_active']) ? $mark((bool) $fs['is_active']) : '—' ?></td></tr>
|
||||
<tr><td class="kv-key">emp_status OK</td><td class="kv-val"><?= isset($fs['emp_status_ok']) ? $mark((bool) $fs['emp_status_ok']) : '—' ?></td></tr>
|
||||
<tr><td class="kv-key">has policy</td><td class="kv-val"><?= isset($fs['has_policy']) ? $mark((bool) $fs['has_policy']) : '—' ?></td></tr>
|
||||
<tr><td class="kv-key">policy status OK</td><td class="kv-val"><?= isset($fs['policy_status_ok']) ? $mark((bool) $fs['policy_status_ok']) : '—' ?></td></tr>
|
||||
<tr><td class="kv-key">client_id</td><td class="kv-val"><?= esc((string) ($side['client_id'] ?? ($eligible['client_id'] ?? '—'))) ?></td></tr>
|
||||
<tr><td class="kv-key">short_name</td><td class="kv-val val-flag"><?= esc((string) ($side['client_short_name'] ?? '')) ?></td></tr>
|
||||
<?php if (! empty($eligible)): ?>
|
||||
<tr><td class="kv-key">employee id</td><td class="kv-val"><?= esc((string) ($eligible['id'] ?? '')) ?></td></tr>
|
||||
<tr><td class="kv-key">emp_code</td><td class="kv-val"><?= esc((string) ($eligible['emp_code'] ?? '')) ?></td></tr>
|
||||
<tr><td class="kv-key">name</td><td class="kv-val"><?= esc((string) ($eligible['name'] ?? '')) ?></td></tr>
|
||||
<tr><td class="kv-key">emp_status</td><td class="kv-val"><?= esc((string) ($eligible['emp_status'] ?? '')) ?></td></tr>
|
||||
<tr><td class="kv-key">mobile</td><td class="kv-val"><?= esc((string) ($eligible['mobile'] ?? '')) ?></td></tr>
|
||||
<tr><td class="kv-key">email_corporate</td><td class="kv-val"><?= esc((string) ($eligible['email_corporate'] ?? '')) ?></td></tr>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($fs['notes'])): ?>
|
||||
<tr><td class="kv-key">Notes</td><td class="kv-val" style="font-family:var(--sans);color:var(--text-secondary);"><?= esc(implode(' ', $fs['notes'])) ?></td></tr>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($side['eligible_via_api']) && empty($eligible)): ?>
|
||||
<tr>
|
||||
<td class="kv-key">API eligible</td>
|
||||
<td class="kv-val"><span class="check">✓</span> via getPostEmployeeDataForAuth (id <?= esc((string) ($side['eligible_via_api']['id'] ?? '')) ?>)</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
@ -393,13 +393,13 @@ input:checked + .slider:before {
|
||||
Is LGBTQ Enable</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4" style="padding-top:50px;padding-bottom: 0px;">
|
||||
<label for="is_premium_summery" style=" position: relative;bottom: 5px;">
|
||||
<label class="switch">
|
||||
<input id="is_premium_summery" type="checkbox" name="is_premium_summery" checked>
|
||||
<span class="slider round" style="height: 27px;"></span>
|
||||
</label>
|
||||
Is Premium Summary Display Enabled </label>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="is_premium_summery">Premium Summary Display</label>
|
||||
<select class="form-control" name="is_premium_summery" id="is_premium_summery">
|
||||
<option value="0">Disable Premium Summary Display</option>
|
||||
<option value="1" selected>Enable Premium Summary Display</option>
|
||||
<option value="2">Enable Premium Total Display</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -1114,11 +1114,7 @@ $('body').on('click', '.btnPolicyEdit', function() {
|
||||
$('#is_lgbtq').prop('checked', false);
|
||||
}
|
||||
|
||||
if (res.data.is_premium_summery == 1) {
|
||||
$('#is_premium_summery').prop('checked', true);
|
||||
} else {
|
||||
$('#is_premium_summery').prop('checked', false);
|
||||
}
|
||||
$('#is_premium_summery').val(res.data.is_premium_summery ?? 0).trigger('change');
|
||||
|
||||
// Member Modify Data Enable or Disable
|
||||
// if (res.data.is_member_modify_allowed == 1) {
|
||||
@ -2247,11 +2243,7 @@ function getClientPolicyDataForEdit(client_policy_id) {
|
||||
$('#is_lgbtq').prop('checked', false);
|
||||
}
|
||||
|
||||
if (res.data.is_premium_summery == 1) {
|
||||
$('#is_premium_summery').prop('checked', true);
|
||||
} else {
|
||||
$('#is_premium_summery').prop('checked', false);
|
||||
}
|
||||
$('#is_premium_summery').val(res.data.is_premium_summery ?? 0).trigger('change');
|
||||
|
||||
if (res.data.policy_type_id == '4' || res.data.policy_type_id == '5' || res.data.policy_type_id == '72') {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user