2026-08-10 19:08:04.235 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.5669 ms
2026-08-10 19:08:04.234 +00:00 [INF] [HTTP] [U:-] [E:-] [C:f9b0c2d2ddb5] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzqiL4MhAoCbiQbSPx9fhp4kgRZOCjxo7ZeaiXMfiQzpNrxHWFhibCxA4rgNX4WHLEhIw7fqZ_ZATs5unvSEyRnLI4xND0hept-8wSvKSoz3zCLQQ8XeRZ5s8UyaIGqilRM" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:08:04.139 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 2.9774 ms
2026-08-10 19:08:04.138 +00:00 [INF] [HTTP] [U:-] [E:-] [C:7920cdf93192] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzrKluuvST3UeyfVQOP4uazTslkz-ZeGnxnjE-aNy914C4nWM6_KeXNqA89PIVvUvIlcV9e12YPzrnN9e8C1A4F9ihYVItp5Qv_6nadwtU5FvD5Q7rwkrTc1AkNfM6ZalCo" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:08:04.042 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Commissions/Management responded 302 in 0.5646 ms
2026-08-10 19:08:04.042 +00:00 [INF] [HTTP] [U:-] [E:-] [C:f0d7a433a0cc] HTTP GET /UI/Commissions/Management 302
Req: [no body]
Res: [empty response]
2026-08-10 19:08:03.945 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/FactFindTemplates/Index responded 302 in 1.2342 ms
2026-08-10 19:08:03.944 +00:00 [INF] [HTTP] [U:-] [E:-] [C:d499ee6cdfc2] HTTP GET /UI/FactFindTemplates/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:07:33.022 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /swagger/index.html responded 200 in 0.7398 ms
2026-08-10 19:07:32.927 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /swagger responded 301 in 0.0521 ms
2026-08-10 19:07:26.110 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.5714 ms
2026-08-10 19:07:26.110 +00:00 [INF] [HTTP] [U:-] [E:-] [C:7ffd1a19ca8c] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzrB6YJKEeMXBgkA0OZgSoiPIFAIJwVbYkZpSw7Of1OfmFyXe3jJ5nOVwx0TjbNDWzJrYUDE7-44flCAHEN1QL716Pkj3eClXOGs5O83BSImASKZ0x4bKI2d7U24gSD2fC4" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:07:26.018 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Dashboard/Index responded 302 in 0.7470 ms
2026-08-10 19:07:26.018 +00:00 [INF] [HTTP] [U:-] [E:-] [C:fd1aa8c90e85] HTTP GET /UI/Dashboard/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:07:25.684 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.5806 ms
2026-08-10 19:07:25.684 +00:00 [INF] [HTTP] [U:-] [E:-] [C:8eb90499cd29] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzoe1fVQIMPnYNM6-0m9t2qKImlv6ZTpyTKT1FbOQSUR9JMrf4dKOeGKoXOcL8b3DhF7DurWWdm8L9NJxyJ7F0xDH2WxvNDwaP9XSRg5OHC6DR3H5OYwpYO3vZaM9ao5bcM" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:07:25.588 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /demo/solution-builder responded 200 in 4.4232 ms
2026-08-10 19:07:25.587 +00:00 [INF] [HTTP] [U:-] [E:-] [C:e556299d9942] HTTP GET /demo/solution-builder 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>iPipeline Demo — Wealthmax CRM</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8fafc;
color: #1e293b;
min-height: 100vh;
}
/* ── Header ── */
.page-header {
background: #fff;
border-bottom: 1px solid #e2e8f0;
padding: 1rem 2rem;
display: flex;
align-items: center;
gap: 1rem;
}
.page-header h1 {
font-size: 1rem;
font-weight: 700;
color: #0f172a;
letter-spacing: -.01em;
}
.badge {
font-size: .6rem;
font-weight: 800;
letter-spacing: .08em;
text-transform: uppercase;
padding: .18rem .5rem;
border-radius: 9999px;
}
.badge-demo { background: #fef3c7; color: #92400e; }
.page-header nav {
margin-left: auto;
display: flex;
gap: 1.25rem;
font-size: .8rem;
}
.page-header nav a {
color: #6366f1;
text-decoration: none;
font-weight: 500;
}
.page-header nav a:hover { text-decoration: underline; }
/* ── Page layout ── */
.page-body {
max-width: 820px;
margin: 2rem auto;
padding: 0 1.5rem 4rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
/* ── Card ── */
.card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,.04), 0 1px 2px rgba(0,0,0,.03);
overflow: hidden;
}
.card-header {
padding: .875rem 1.5rem;
border-bottom: 1px solid #f1f5f9;
display: flex;
align-items: center;
gap: .6rem;
background: #fafafa;
}
.card-header h2 {
font-size: .8rem;
font-weight: 700;
color: #374151;
letter-spacing: .04em;
text-transform: uppercase;
}
.card-body {
padding: 1.25rem 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
/* ── Sub-section divider inside a card ── */
.sub-section {
padding-top: 1rem;
border-top: 1px solid #f1f5f9;
display: flex;
flex-direction: column;
gap: .85rem;
}
.sub-label {
font-size: .68rem;
font-weight: 700;
letter-spacing: .09em;
text-transform: uppercase;
color: #6366f1;
}
/* ── Field grid ── */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: .875rem; }
.field-row.single { grid-template-columns: 1fr; }
.field-row.triple { grid-template-columns: 1fr 1fr 1fr; }
.field-group { display: flex; flex-direction: column; gap: .3rem; }
.field-group label {
font-size: .72rem;
font-weight: 600;
color: #475569;
}
.field-hint {
font-size: .68rem;
font-weight: 400;
color: #94a3b8;
margin-left: .2rem;
}
.field-group input,
.field-group select {
background: #fff;
color: #0f172a;
border: 1px solid #d1d5db;
border-radius: 7px;
padding: .52rem .75rem;
font-size: .875rem;
width: 100%;
transition: border-color .15s, box-shadow .15s;
appearance: auto;
}
.field-group input::placeholder { color: #c8d1db; }
.field-group input:focus,
.field-group select:focus {
outline: none;
border-color: #818cf8;
box-shadow: 0 0 0 3px rgba(99,102,241,.1);
}
/* ── Second-life toggle ── */
.toggle-card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,.04);
}
.toggle-card label {
display: flex;
align-items: center;
gap: .75rem;
padding: .95rem 1.5rem;
cursor: pointer;
user-select: none;
}
.toggle-card input[type=checkbox] {
accent-color: #6366f1;
width: 16px;
height: 16px;
cursor: pointer;
flex-shrink: 0;
}
.toggle-card .toggle-text {
font-size: .85rem;
font-weight: 500;
color: #374151;
}
.toggle-card .toggle-sub {
font-size: .75rem;
color: #94a3b8;
margin-left: auto;
}
/* ── Second life collapsible ── */
.second-life-section { display: none; flex-direction: column; gap: 1rem; }
.second-life-section.visible { display: flex; }
/* ── Policy settings card accent ── */
.card.settings .card-header { background: #f5f3ff; border-bottom-color: #ede9fe; }
.card.settings .card-header h2 { color: #5b21b6; }
/* ── Launch button ── */
.launch-wrap {
display: flex;
flex-direction: column;
gap: .6rem;
padding-top: .25rem;
}
.launch-btn {
width: 100%;
background: #4f46e5;
color: #fff;
border: none;
border-radius: 10px;
padding: .85rem 1rem;
font-size: .925rem;
font-weight: 600;
cursor: pointer;
transition: background .15s, transform .1s, box-shadow .15s;
display: flex;
align-items: center;
justify-content: center;
gap: .5rem;
box-shadow: 0 2px 8px rgba(79,70,229,.25);
}
.launch-btn:hover { background: #4338ca; box-shadow: 0 4px 12px rgba(79,70,229,.35); }
.launch-btn:active { transform: scale(.985); }
.launch-btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.launch-hint {
font-size: .72rem;
color: #94a3b8;
text-align: center;
}
</style>
</head>
<body>
<!-- ── Header ── -->
<header class="page-header">
<h1>iPipeline Solution Builder</h1>
<span class="badge badge-demo">Demo</span>
<nav>
<a href="/">Home</a>
<a href="/demo/solution-builder/events">Fetch Quotes →</a>
</nav>
</header>
<div class="page-body">
<form id="demoForm" method="post" action="/demo/solution-builder/launch" target="_blank">
<!-- ── Case selector ── -->
<div class="card">
<div class="card-body">
<div class="field-group">
<label for="caseSelect">Select Demo Case</label>
<select id="caseSelect" name="CaseRef" onchange="loadCase(this.value)">
<option value="">— Choose a case to pre-fill the form —</option>
<option value="WM-DEMO-001">James Wilson — Single, Male, Non-Smoker (35 yrs)</option>
<option value="WM-DEMO-002">Sarah Mitchell — Single, Female, Smoker (33 yrs)</option>
<option value="WM-DEMO-003">Robert & Emma Clarke — Joint Life, Non-Smokers</option>
<option value="WM-DEMO-004">David Thompson — Single, Male, Smoker (51 yrs)</option>
<option value="WM-DEMO-005">Michael & Lisa Brown — Joint Life, Both Smokers</option>
</select>
</div>
</div>
</div>
<!-- ── First Life ── -->
<div class="card">
<div class="card-header">
<h2>First Life</h2>
</div>
<div class="card-body">
<div class="field-row">
<div class="field-group">
<label>First Name</label>
<input id="firstFirstName" name="FirstFirstName" type="text" placeholder="e.g. James" required />
</div>
<div class="field-group">
<label>Last Name</label>
<input id="firstLastName" name="FirstLastName" type="text" placeholder="e.g. Wilson" required />
</div>
</div>
<div class="field-row">
<div class="field-group">
<label>Date of Birth</label>
<input id="firstDateOfBirth" name="FirstDateOfBirth" type="date" required />
</div>
<div class="field-group">
<label>Gender</label>
<select id="firstGender" name="FirstGender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<div class="field-row single">
<div class="field-group">
<label>Smoker Status</label>
<select id="firstIsSmoker" name="FirstIsSmoker">
<option value="false">Non-Smoker</option>
<option value="true">Smoker</option>
</select>
</div>
</div>
<!-- Cover details -->
<div class="sub-section">
<div class="sub-label">Cover Details</div>
<div class="field-row">
<div class="field-group">
<label>Life Cover Amount (£)</label>
<input id="lifeCoverAmount" name="LifeCoverAmount" type="number" value="300000" />
</div>
<div class="field-group">
<label>Life Cover Up to Age <span class="field-hint">46 – 99</span></label>
<input id="lifeToAge" name="LifeToAge" type="number" value="85" min="46" max="99" />
</div>
</div>
<div class="field-row">
<div class="field-group">
<label>Critical Illness Amount (£)</label>
<input id="ciCoverAmount" name="CiCoverAmount" type="number" value="30000" />
</div>
<div class="field-group">
<label>CI Cover Up to Age <span class="field-hint">43 – 99</span></label>
<input id="ciToAge" name="CiToAge" type="number" value="70" min="43" max="99" />
</div>
</div>
<div class="field-row single">
<div class="field-group">
<label>Waiver of Premium</label>
<select id="waiverOfPremium" name="WaiverOfPremium">
<option value="None" selected>None</option>
<option value="FirstLife">FirstLife</option>
</select>
</div>
</div>
</div>
</div>
</div>
<!-- ── Second Life toggle ── -->
<div class="toggle-card">
<label for="hasSecondLife">
<input type="checkbox" id="hasSecondLife" name="HasSecondLife" value="true"
onchange="toggleSecondLife(this.checked)" />
<span class="toggle-text">Add Second Life</span>
<span class="toggle-sub">Joint Policy</span>
</label>
</div>
<!-- ── Second Life ── -->
<div id="secondLifeSection" class="second-life-section">
<div class="card">
<div class="card-header">
<h2>Second Life</h2>
</div>
<div class="card-body">
<div class="field-row">
<div class="field-group">
<label>First Name</label>
<input id="secondFirstName" name="SecondFirstName" type="text" placeholder="e.g. Emma" />
</div>
<div class="field-group">
<label>Last Name</label>
<input id="secondLastName" name="SecondLastName" type="text" placeholder="e.g. Clarke" />
</div>
</div>
<div class="field-row">
<div class="field-group">
<label>Date of Birth</label>
<input id="secondDateOfBirth" name="SecondDateOfBirth" type="date" />
</div>
<div class="field-group">
<label>Gender</label>
<select id="secondGender" name="SecondGender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<div class="field-row single">
<div class="field-group">
<label>Smoker Status</label>
<select id="secondIsSmoker" name="SecondIsSmoker">
<option value="false">Non-Smoker</option>
<option value="true">Smoker</option>
</select>
</div>
</div>
<!-- Second life cover details -->
<div class="sub-section">
<div class="sub-label">Cover Details</div>
<div class="field-row">
<div class="field-group">
<label>Life Cover Amount (£)</label>
<input id="secondLifeCoverAmount" name="SecondLifeCoverAmount" type="number" value="300000" />
</div>
<div class="field-group">
<label>Life Cover Up to Age <span class="field-hint">46 – 99</span></label>
<input id="secondLifeToAge" name="SecondLifeToAge" type="number" value="85" min="46" max="99" />
</div>
</div>
<div class="field-row">
<div class="field-group">
<label>Critical Illness Amount (£)</label>
<input id="secondCiCoverAmount" name="SecondCiCoverAmount" type="number" value="30000" />
</div>
<div class="field-group">
<label>CI Cover Up to Age <span class="field-hint">43 – 99</span></label>
<input id="secondCiToAge" name="SecondCiToAge" type="number" value="70" min="43" max="99" />
</div>
</div>
<div class="field-row single">
<div class="field-group">
<label>Waiver of Premium</label>
<select id="secondWaiverOfPremium" name="SecondWaiverOfPremium">
<option value="None" selected>None</option>
<option value="SecondLife">SecondLife</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ── Policy Settings (shared) ── -->
<div class="card settings">
<div class="card-header">
<h2>Policy Settings</h2>
</div>
<div class="card-body">
<div class="field-row triple">
<div class="field-group">
<label>Premium Type</label>
<select id="premiumType" name="PremiumType">
<option value="Guaranteed" selected>Guaranteed</option>
<option value="Reviewable">Reviewable</option>
</select>
</div>
<div class="field-group">
<label>Indexation</label>
<select id="indexation" name="Indexation">
<option value="Level" selected>Level</option>
<option value="RPI">RPI</option>
<option value="AWEI">AWEI</option>
<option value="One">1%</option>
<option value="Two">2%</option>
<option value="Three">3%</option>
<option value="Four">4%</option>
<option value="Five">5%</option>
<option value="Six">6%</option>
<option value="Seven">7%</option>
<option value="Eight">8%</option>
<option value="Nine">9%</option>
<option value="Ten">10%</option>
</select>
</div>
<div class="field-group">
<label>Exclude Low Start</label>
<select name="ExcludeLowStart">
<option value="False" selected>No</option>
<option value="True">Yes</option>
</select>
</div>
</div>
</div>
</div>
<!-- ── Launch ── -->
<div class="launch-wrap">
<button type="submit" class="launch-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M15 3h6v6M10 14L21 3M9 21H3v-6"/>
</svg>
Launch in iPipeline Solution Builder
</button>
<p class="launch-hint">Encrypts the payload into a 5-minute one-time token and auto-submits to iPipeline.</p>
</div>
</form>
</div>
<script>
const CASES = [{"caseId":"WM-DEMO-001","displayName":"James Wilson \u2014 Single, Male, Non-Smoker (35 yrs)","firstLife":{"firstName":"James","lastName":"Wilson","dateOfBirth":"1989-03-15","gender":"Male","isSmoker":false},"secondLife":null},{"caseId":"WM-DEMO-002","displayName":"Sarah Mitchell \u2014 Single, Female, Smoker (33 yrs)","firstLife":{"firstName":"Sarah","lastName":"Mitchell","dateOfBirth":"1991-07-22","gender":"Female","isSmoker":true},"secondLife":null},{"caseId":"WM-DEMO-003","displayName":"Robert \u0026 Emma Clarke \u2014 Joint Life, Non-Smokers","firstLife":{"firstName":"Robert","lastName":"Clarke","dateOfBirth":"1978-11-08","gender":"Male","isSmoker":false},"secondLife":{"firstName":"Emma","lastName":"Clarke","dateOfBirth":"1980-05-14","gender":"Female","isSmoker":false}},{"caseId":"WM-DEMO-004","displayName":"David Thompson \u2014 Single, Male, Smoker (51 yrs)","firstLife":{"firstName":"David","lastName":"Thompson","dateOfBirth":"1972-09-30","gender":"Male","isSmoker":true},"secondLife":null},{"caseId":"WM-DEMO-005","displayName":"Michael \u0026 Lisa Brown \u2014 Joint Life, Both Smokers","firstLife":{"firstName":"Michael","lastName":"Brown","dateOfBirth":"1982-04-17","gender":"Male","isSmoker":true},"secondLife":{"firstName":"Lisa","lastName":"Brown","dateOfBirth":"1984-12-03","gender":"Female","isSmoker":true}}];
function loadCase(caseId) {
const c = CASES.find(x => x.caseId === caseId);
if (!c) return;
setVal('firstFirstName', c.firstLife.firstName);
setVal('firstLastName', c.firstLife.lastName);
setVal('firstDateOfBirth', c.firstLife.dateOfBirth);
setVal('firstGender', c.firstLife.gender);
setVal('firstIsSmoker', c.firstLife.isSmoker ? 'true' : 'false');
const hasSecond = c.secondLife !== null;
document.getElementById('hasSecondLife').checked = hasSecond;
toggleSecondLife(hasSecond);
if (hasSecond) {
setVal('secondFirstName', c.secondLife.firstName);
setVal('secondLastName', c.secondLife.lastName);
setVal('secondDateOfBirth', c.secondLife.dateOfBirth);
setVal('secondGender', c.secondLife.gender);
setVal('secondIsSmoker', c.secondLife.isSmoker ? 'true' : 'false');
}
}
function setVal(id, val) {
const el = document.getElementById(id);
if (el) el.value = val ?? '';
}
function toggleSecondLife(show) {
document.getElementById('secondLifeSection').classList.toggle('visible', show);
}
</script>
</body>
</html>
2026-08-10 19:07:25.491 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Cases/Index responded 302 in 0.8048 ms
2026-08-10 19:07:25.491 +00:00 [INF] [HTTP] [U:-] [E:-] [C:edd88404bec2] HTTP GET /UI/Cases/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:06:08.951 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /demo/solution-builder/events responded 200 in 4.6346 ms
2026-08-10 19:06:08.950 +00:00 [INF] [HTTP] [U:-] [E:-] [C:fadee2235844] HTTP GET /demo/solution-builder/events 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>iPipeline Event Notifications — Wealthmax CRM</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f1f5f9;
color: #1e293b;
min-height: 100vh;
}
.demo-header {
background: #fff;
border-bottom: 1px solid #e2e8f0;
padding: .875rem 2rem;
display: flex;
align-items: center;
gap: .875rem;
}
.demo-header h1 { font-size: 1.1rem; font-weight: 700; color: #0f172a; }
.badge-demo {
background: #f59e0b; color: #fff;
font-size: .6rem; font-weight: 800; letter-spacing: .07em;
padding: .2rem .5rem; border-radius: 9999px; text-transform: uppercase;
}
.demo-header p { margin-left: auto; font-size: .78rem; color: #94a3b8; }
.demo-body {
max-width: 980px;
margin: 2rem auto;
padding: 0 1.5rem 3rem;
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 1.25rem 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.section-label {
font-size: .7rem; font-weight: 700;
letter-spacing: .1em; text-transform: uppercase;
color: #6366f1;
padding-bottom: .4rem;
border-bottom: 1px solid #e2e8f0;
}
.field-group { display: flex; flex-direction: column; gap: .3rem; }
.field-group label { font-size: .73rem; color: #64748b; font-weight: 500; }
.field-group select {
background: #fff; color: #0f172a;
border: 1px solid #cbd5e1; border-radius: 6px;
padding: .48rem .7rem; font-size: .875rem;
transition: border-color .15s; width: 100%;
}
.field-group select:focus {
outline: none; border-color: #6366f1;
box-shadow: 0 0 0 3px rgba(99,102,241,.12);
}
.quote-btn {
width: 100%;
background: #6366f1; color: #fff;
border: none; border-radius: 8px;
padding: .78rem 1rem; font-size: .9rem; font-weight: 600;
cursor: pointer; transition: background .15s, transform .1s;
display: flex; align-items: center; justify-content: center; gap: .5rem;
}
.quote-btn:hover { background: #4f46e5; }
.quote-btn:active { transform: scale(.98); }
.quote-btn:disabled { background: #c7d2fe; cursor: not-allowed; }
.hint { font-size: .72rem; color: #94a3b8; }
.status { font-size: .8rem; color: #475569; min-height: 1.1rem; }
.status.error { color: #dc2626; }
/* ── Results ── */
.event-card {
background: #fff; border: 1px solid #e2e8f0; border-radius: 10px;
padding: 1.1rem 1.3rem; display: flex; flex-direction: column; gap: .9rem;
}
.event-top { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.badge {
font-size: .62rem; font-weight: 800; letter-spacing: .06em;
padding: .2rem .5rem; border-radius: 9999px; text-transform: uppercase; color: #fff;
}
.badge.like { background: #0ea5e9; }
.badge.apply { background: #16a34a; }
.event-meta { font-size: .73rem; color: #64748b; }
.event-meta b { color: #334155; font-weight: 600; }
.group-label {
font-size: .68rem; font-weight: 700; letter-spacing: .08em;
text-transform: uppercase; color: #6366f1; margin-top: .3rem;
}
.comparison {
border: 1px solid #e2e8f0; border-radius: 8px; padding: .8rem .9rem;
display: flex; flex-direction: column; gap: .6rem; background: #f8fafc;
}
.comparison-head { font-size: .74rem; color: #475569; display: flex; gap: 1rem; flex-wrap: wrap; }
table.quotes { width: 100%; border-collapse: collapse; font-size: .76rem; }
table.quotes th, table.quotes td {
text-align: left; padding: .4rem .55rem; border-bottom: 1px solid #e2e8f0;
}
table.quotes th { color: #64748b; font-weight: 600; background: #fff; }
table.quotes td.num { text-align: right; font-variant-numeric: tabular-nums; }
.benefit {
font-size: .74rem; color: #334155;
border-left: 3px solid #c7d2fe; padding: .25rem .6rem; background: #fff; border-radius: 4px;
}
.benefit .bt { font-weight: 700; color: #4f46e5; }
.benefit .pairs { color: #64748b; }
.empty {
text-align: center; color: #94a3b8; font-size: .85rem;
padding: 2rem; border: 1px dashed #cbd5e1; border-radius: 10px; background: #fff;
}
</style>
</head>
<body>
<header class="demo-header">
<h1>iPipeline Event Notifications <span class="badge-demo">Demo</span></h1>
<nav style="margin-left:auto;display:flex;gap:1rem;font-size:.8rem;">
<a href="/" style="color:#6366f1;text-decoration:none;">Home</a>
<a href="/demo/solution-builder" style="color:#6366f1;text-decoration:none;">← Solution Builder</a>
</nav>
</header>
<div class="demo-body">
<div class="card">
<div class="section-label">Get Quotes</div>
<div class="field-group">
<label for="caseSelect">Demo Case</label>
<select id="caseSelect">
<option value="">— All recent notifications —</option>
<option value="WM-DEMO-001">James Wilson — Single, Male, Non-Smoker (35 yrs) (WM-DEMO-001)</option>
<option value="WM-DEMO-002">Sarah Mitchell — Single, Female, Smoker (33 yrs) (WM-DEMO-002)</option>
<option value="WM-DEMO-003">Robert & Emma Clarke — Joint Life, Non-Smokers (WM-DEMO-003)</option>
<option value="WM-DEMO-004">David Thompson — Single, Male, Smoker (51 yrs) (WM-DEMO-004)</option>
<option value="WM-DEMO-005">Michael & Lisa Brown — Joint Life, Both Smokers (WM-DEMO-005)</option>
</select>
</div>
<button id="getQuotesBtn" class="quote-btn" onclick="getQuotes()">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
</svg>
Get Quotes
</button>
<div id="status" class="status"></div>
<p class="hint">The selected case ref is sent to iPipeline as the External Client Reference filter. Choose “All recent notifications” to fetch everything for the demo account (last 30 days).</p>
</div>
<div id="results"></div>
</div>
<script>
const $ = id => document.getElementById(id);
const esc = s => (s ?? '').toString().replace(/[&<>"']/g, m =>
({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[m]));
function fmtDate(s) {
if (!s) return '—';
const d = new Date(s);
return isNaN(d) ? s : d.toLocaleString();
}
function fmtMoney(v) {
if (v === null || v === undefined) return '—';
return '£' + Number(v).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
async function getQuotes() {
const caseRef = $('caseSelect').value;
const btn = $('getQuotesBtn');
const status = $('status');
const results = $('results');
btn.disabled = true;
status.className = 'status';
status.textContent = 'Contacting iPipeline…';
results.innerHTML = '';
try {
const res = await fetch('/demo/solution-builder/events/data?caseRef=' + encodeURIComponent(caseRef));
const body = await res.json();
if (!body.success) {
status.className = 'status error';
status.textContent = (body.errorCode || 'ERROR') + ': ' + (body.errorMessage || 'Request failed.');
return;
}
const events = body.data || [];
status.textContent = events.length + ' notification(s) returned.';
renderEvents(events);
} catch (e) {
status.className = 'status error';
status.textContent = 'Request failed: ' + e.message;
} finally {
btn.disabled = false;
}
}
function renderEvents(events) {
const results = $('results');
if (!events.length) {
results.innerHTML = '<div class="empty">No event notifications found for this selection.</div>';
return;
}
results.innerHTML = events.map(renderEvent).join('');
}
function renderEvent(ev) {
const cls = (ev.eventType || '').toLowerCase() === 'like' ? 'like' : 'apply';
const meta = [
['Client', ev.sbClientId],
['External Ref', ev.externalClientReference],
['User', ev.userId],
['Request No', ev.requestNo],
['Event Key', ev.eventKey]
].filter(p => p[1] !== null && p[1] !== undefined && p[1] !== '')
.map(p => `<b>${esc(p[0])}:</b> ${esc(p[1])}`).join(' · ');
const applies = (ev.applies || []).map(a => renderApply(a)).join('');
const likes = (ev.likes || []).map(l => renderLike(l)).join('');
let body = '';
if (applies) body += `<div class="group-label">Applies</div>${applies}`;
if (likes) body += `<div class="group-label">Likes</div>${likes}`;
if (!applies && !likes) body += `<div class="event-meta">No model detail (likes/applies) returned for this event.</div>`;
return `
<div class="event-card">
<div class="event-top">
<span class="badge ${cls}">${esc(ev.eventType)}</span>
<span class="event-meta">${fmtDate(ev.eventTimeUtc)}</span>
</div>
<div class="event-meta">${meta}</div>
${body}
</div>`;
}
function renderApply(a) {
const head = `<b>Apply #${esc(a.applyId)}</b> · ${esc(a.applicationType)} · ${fmtDate(a.dateTimeApplied)}`;
return wrapComparisons(head, a.comparisons);
}
function renderLike(l) {
const head = `<b>Solution #${esc(l.solutionId)}</b> · ${esc(l.solutionType)} · ${fmtDate(l.dateTimeLiked)}`;
return wrapComparisons(head, l.comparisons);
}
function wrapComparisons(head, comparisons) {
const inner = (comparisons || []).map(renderComparison).join('') ||
'<div class="event-meta">No comparisons.</div>';
return `<div class="comparison"><div class="comparison-head">${head}</div>${inner}</div>`;
}
function renderComparison(c) {
const head = [
['Service', c.serviceId],
['IFA Ref', c.ifaReference],
['Expires', fmtDate(c.comparisonExpiryDate)]
].filter(p => p[1]).map(p => `${esc(p[0])}: ${esc(p[1])}`).join(' · ');
const quotes = (c.quotes || []);
const quotesTable = quotes.length ? `
<table class="quotes">
<thead><tr>
<th>Quote ID</th><th>Product</th><th>Provider</th>
<th class="num">Premium</th><th class="num">Commission</th>
<th>Underwriting</th><th>Expiry</th>
</tr></thead>
<tbody>
${quotes.map(q => `<tr>
<td><code>${esc(q.quoteId)}</code></td>
<td>${esc(q.productName) || ('#' + esc(q.productId))}</td>
<td>${esc(q.providerName)}</td>
<td class="num">${fmtMoney(q.premium)}</td>
<td class="num">${fmtMoney(q.commissionAmount)}</td>
<td>${esc(q.overallUnderwritingDecision) || '—'}</td>
<td>${fmtDate(q.expiryDate)}</td>
</tr>`).join('')}
</tbody>
</table>` : '';
const benefits = (c.benefits || []).map(renderBenefit).join('');
return `<div style="display:flex;flex-direction:column;gap:.5rem;margin-top:.4rem">
${head ? `<div class="comparison-head">${head}</div>` : ''}
${quotesTable}
${benefits}
</div>`;
}
function renderBenefit(b) {
const d = b.details || {};
const pairs = Object.entries(d)
.filter(([, v]) => v !== null && v !== undefined && v !== '')
.map(([k, v]) => `${esc(prettyKey(k))}: ${esc(v)}`)
.join(' · ');
return `<div class="benefit"><span class="bt">${esc(b.benefitType)}</span>
${pairs ? `<span class="pairs"> — ${pairs}</span>` : ''}</div>`;
}
function prettyKey(k) {
return k.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase()).trim();
}
</script>
</body>
</html>
2026-08-10 19:05:44.379 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.6731 ms
2026-08-10 19:05:44.379 +00:00 [INF] [HTTP] [U:-] [E:-] [C:dd0898415e35] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzqYJ5aLOK1KAsYgSgK50F4yXile8RgnKIDGuSZbvP69WnHF-Orkebu03R9sm1uCLR81i2peW99bLxPaCdL76O6IVp4MwJk8WnyDVVWjWa6hfQF29NDCWb04jB-v_eVmySQ" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:05:44.287 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Tokens/Index responded 302 in 0.8115 ms
2026-08-10 19:05:44.287 +00:00 [INF] [HTTP] [U:-] [E:-] [C:7ec163e8f1f7] HTTP GET /UI/Tokens/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:05:43.976 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 2.6564 ms
2026-08-10 19:05:43.975 +00:00 [INF] [HTTP] [U:-] [E:-] [C:d1c38b401c23] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzpvcHe5bYgjaWB9f5LCHnvp84e-m8xkf3l5pvu8v88BTf7YXt_oI3cwkxa75ub1uaARDdKd8ZsO8YPzx-fAxuuhGApXNy8zUps4gYola89fspW2dXrYsyYgdnWvL55X10w" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:05:43.883 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Templates/Index responded 302 in 0.6323 ms
2026-08-10 19:05:43.882 +00:00 [INF] [HTTP] [U:-] [E:-] [C:930439697ed3] HTTP GET /UI/Templates/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:05:43.788 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.8391 ms
2026-08-10 19:05:43.788 +00:00 [INF] [HTTP] [U:-] [E:-] [C:5aa0b86c3d71] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzpzFaXvKL7XOm7qw7uzPzD2xe9b0UKPhavmOY1ihyHhWLNdl6iXn0SE3oy6cFnGWmvXTv6vlJgpa_kFzHwK8b7F5XBwZPtCBTnG3rNcRQFqrCVr7Leo-8uBL7o-T-saBM8" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:05:31.695 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 2.0827 ms
2026-08-10 19:05:31.694 +00:00 [INF] [HTTP] [U:-] [E:-] [C:a5a6cdb20963] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzqSFHvw9d7uFFAM6Q8fuXuokdga4CCMvnyoKz-bcVl3lVRqBrOFfMngyJ9G5EoxVW0BQgGtANOT0BpJ0wNjNNuKNCsZxrZ8Ikl9-tvWveBpRtMZPC4lqi4ng-COLBosAR8" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:05:31.600 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Clients/Index responded 302 in 0.5742 ms
2026-08-10 19:05:31.600 +00:00 [INF] [HTTP] [U:-] [E:-] [C:a3e0f5a70234] HTTP GET /UI/Clients/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:04:39.934 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 1.7449 ms
2026-08-10 19:04:39.934 +00:00 [INF] [HTTP] [U:-] [E:-] [C:fcf2db91f29e] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzqsNYFHEhl2Lo9iNISz7rnYFH8X3JDDewdFOg7xn-WzeI2SNnkt2YDvXlE2Ylp6w_xl0UaJQtYCt6IahlsEK_mSO5u35TlbG4nlylRo_VMB3rU3q6BK-G841nDnKZjmQuU" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:04:39.841 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/FactFindGenerate responded 302 in 0.5553 ms
2026-08-10 19:04:39.841 +00:00 [INF] [HTTP] [U:-] [E:-] [C:e67ebe5990a8] HTTP GET /UI/FactFindGenerate 302
Req: [no body]
Res: [empty response]
2026-08-10 19:04:39.747 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /test-signalr.html responded 200 in 1.0088 ms
2026-08-10 19:04:39.746 +00:00 [INF] [HTTP] [U:-] [E:-] [C:-] HTTP GET /test-signalr.html 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SignalR Notification Hub Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1000px;
margin: 20px auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
h1 { color: #333; margin-top: 0; }
h2 {
color: #666;
font-size: 18px;
margin-top: 20px;
border-bottom: 2px solid #e0e0e0;
padding-bottom: 5px;
}
.input-group { margin: 15px 0; }
label { display: block; margin-bottom: 5px; color: #555; font-weight: bold; }
input[type="text"], input[type="password"], select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
font-size: 14px;
}
select { background: white; cursor: pointer; }
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-right: 10px;
}
button:hover { background: #0056b3; }
button:disabled { background: #ccc; cursor: not-allowed; }
button.disconnect { background: #dc3545; }
button.disconnect:hover { background: #c82333; }
button.success-btn { background: #28a745; }
button.success-btn:hover { background: #1e7e34; }
.status {
padding: 10px;
border-radius: 4px;
margin: 10px 0;
font-weight: bold;
}
.status.disconnected { background: #f8d7da; color: #721c24; }
.status.connected { background: #d4edda; color: #155724; }
.status.connecting { background: #fff3cd; color: #856404; }
#messages {
max-height: 400px;
overflow-y: auto;
border: 1px solid #ddd;
padding: 15px;
background: #fafafa;
border-radius: 4px;
}
.message {
padding: 10px;
margin: 5px 0;
border-radius: 4px;
background: white;
border-left: 4px solid #007bff;
}
.message.error { border-left-color: #dc3545; background: #fff5f5; }
.message.success { border-left-color: #28a745; background: #f0fff4; }
.message.notification { background: #e7f3ff; border-left-color: #17a2b8; }
.message-time { font-size: 11px; color: #999; margin-bottom: 5px; }
.message-content { color: #333; }
code {
background: #f4f4f4;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 13px;
}
.info-box {
background: #e7f3ff;
border-left: 4px solid #17a2b8;
padding: 15px;
margin: 15px 0;
border-radius: 4px;
}
.info-box strong { color: #0c5460; }
.otp-section {
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 6px;
padding: 15px;
margin-top: 15px;
}
.otp-section h3 { margin-top: 0; color: #856404; font-size: 16px; }
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
margin-left: 8px;
}
.badge.platform { background: #cfe2ff; color: #084298; }
.badge.business { background: #d1e7dd; color: #0a3622; }
.type-selector {
display: flex;
gap: 10px;
margin: 15px 0;
}
.type-btn {
flex: 1;
padding: 12px;
border: 2px solid #ddd;
border-radius: 6px;
background: white;
color: #555;
font-size: 15px;
font-weight: bold;
cursor: pointer;
}
.type-btn.active.platform { border-color: #084298; background: #cfe2ff; color: #084298; }
.type-btn.active.business { border-color: #0a3622; background: #d1e7dd; color: #0a3622; }
.type-btn:hover:not(.active) { border-color: #999; background: #f8f9fa; }
</style>
</head>
<body>
<div class="container">
<h1>🔔 SignalR Notification Hub Test</h1>
<div class="info-box">
<strong>How to connect:</strong>
<ol style="margin: 10px 0 0 0; padding-left: 20px;">
<li>Select your user type: <strong>Platform</strong> (super-admin) or <strong>Business</strong> (adviser/tenant user)</li>
<li>Enter the API URL, email, and password then click <strong>Login & Send OTP</strong></li>
<li>Check your email for the 6-digit OTP code</li>
<li>Enter the OTP and click <strong>Verify OTP & Get Token</strong> — the JWT is auto-filled</li>
<li>Click <strong>Connect to Hub</strong> to open the SignalR connection</li>
<li>Trigger events in the system and watch real-time notifications appear below</li>
</ol>
</div>
<h2>Step 1: Choose User Type</h2>
<div class="type-selector">
<button class="type-btn platform" id="btnPlatform" onclick="setUserType('platform')">
🏢 Platform User<br><small style="font-weight:normal">Super-admin / platform staff</small>
</button>
<button class="type-btn business" id="btnBusiness" onclick="setUserType('business')">
👤 Business User<br><small style="font-weight:normal">Adviser / tenant user</small>
</button>
</div>
<div id="userTypeBadge" style="margin-bottom:10px; font-size:14px; color:#555;">
Selected: <span id="selectedTypeLabel"><em>none</em></span>
</div>
<h2>Step 2: Login & Get OTP</h2>
<div class="input-group">
<label>API Base URL:</label>
<input type="text" id="apiUrl" value="http://localhost:8099" placeholder="http://localhost:[port]">
</div>
<div class="input-group">
<label>Email:</label>
<input type="text" id="email" placeholder="example@wealthmax.co.uk">
</div>
<div class="input-group">
<label>Password:</label>
<input type="password" id="password" placeholder="Enter password">
</div>
<button onclick="login()" id="loginBtn">Login & Send OTP</button>
<div id="otpSection" class="otp-section" style="display:none;">
<h3>📧 OTP Sent — Check Your Email</h3>
<p style="margin:0 0 10px 0; color:#856404;">Enter the 6-digit code from your email:</p>
<div class="input-group" style="margin:0;">
<input type="text" id="otpCode" maxlength="6" placeholder="000000" style="letter-spacing:6px; font-size:22px; text-align:center;">
</div>
<br>
<button class="success-btn" onclick="verifyOtp()" id="verifyBtn">Verify OTP & Get Token</button>
<button onclick="login()" style="background:#6c757d;">Resend OTP</button>
<p id="challengeInfo" style="font-size:12px; color:#999; margin-top:8px;"></p>
</div>
<h2>Step 3: Connect to SignalR Hub</h2>
<div class="input-group">
<label>JWT Token: <span style="font-weight:normal; font-size:12px; color:#999;">(auto-filled after OTP verify, or paste manually)</span></label>
<input type="text" id="token" placeholder="Paste your JWT token here (or complete login above)">
</div>
<div id="status" class="status disconnected">⚫ Disconnected</div>
<button id="connectBtn" onclick="connect()">Connect to Hub</button>
<button id="disconnectBtn" onclick="disconnect()" class="disconnect" disabled>Disconnect</button>
<button onclick="clearMessages()">Clear Messages</button>
<h2>Connection Log & Notifications</h2>
<div id="messages"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr@latest/dist/browser/signalr.min.js"></script>
<script>
let connection = null;
let currentUserType = null; // 'platform' | 'business'
let currentChallengeToken = null;
const messagesDiv = document.getElementById('messages');
const statusDiv = document.getElementById('status');
const connectBtn = document.getElementById('connectBtn');
const disconnectBtn = document.getElementById('disconnectBtn');
const tokenInput = document.getElementById('token');
const otpSection = document.getElementById('otpSection');
function setUserType(type) {
currentUserType = type;
document.getElementById('btnPlatform').classList.toggle('active', type === 'platform');
document.getElementById('btnBusiness').classList.toggle('active', type === 'business');
document.getElementById('selectedTypeLabel').textContent =
type === 'platform' ? 'Platform User (super-admin)' : 'Business User (adviser/tenant)';
otpSection.style.display = 'none';
currentChallengeToken = null;
}
// Default to platform on load
setUserType('platform');
function addMessage(text, type = 'info') {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}`;
const timeDiv = document.createElement('div');
timeDiv.className = 'message-time';
timeDiv.textContent = new Date().toLocaleTimeString();
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
if (typeof text === 'object') {
contentDiv.innerHTML = `<pre>${JSON.stringify(text, null, 2)}</pre>`;
} else {
contentDiv.textContent = text;
}
messageDiv.appendChild(timeDiv);
messageDiv.appendChild(contentDiv);
messagesDiv.insertBefore(messageDiv, messagesDiv.firstChild);
}
function updateStatus(text, state) {
statusDiv.textContent = text;
statusDiv.className = `status ${state}`;
}
async function login() {
if (!currentUserType) {
addMessage('❌ Please select a user type first (Platform or Business)', 'error');
return;
}
const apiUrl = document.getElementById('apiUrl').value.trim();
const email = document.getElementById('email').value.trim();
const password = document.getElementById('password').value;
if (!apiUrl || !email || !password) {
addMessage('❌ Please fill in API URL, email, and password', 'error');
return;
}
const endpoint = currentUserType === 'platform'
? `${apiUrl}/api/Auth/login`
: `${apiUrl}/api/v1/business/auth/login`;
addMessage(`🔑 [${currentUserType.toUpperCase()}] Sending login request for ${email}...`, 'info');
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const data = await response.json();
if (!response.ok || !data.success) {
addMessage(`❌ Login failed: ${data.error?.message || data.message || 'Unknown error'}`, 'error');
return;
}
currentChallengeToken = data.data.challengeToken;
const expiresIn = data.data.otpExpiresInSeconds ?? data.data.oTPExpiresInSeconds ?? '?';
addMessage(`✅ Login accepted — OTP sent to ${email}`, 'success');
addMessage(`⏱️ OTP expires in ${expiresIn} seconds`, 'info');
document.getElementById('challengeInfo').textContent =
`Challenge token received. OTP expires in ${expiresIn}s.`;
document.getElementById('otpCode').value = '';
otpSection.style.display = 'block';
document.getElementById('otpCode').focus();
} catch (error) {
addMessage(`❌ Login error: ${error.message}`, 'error');
}
}
async function verifyOtp() {
if (!currentChallengeToken) {
addMessage('❌ No active login session — click "Login & Send OTP" first', 'error');
return;
}
const apiUrl = document.getElementById('apiUrl').value.trim();
const otp = document.getElementById('otpCode').value.trim();
if (otp.length !== 6 || !/^\d{6}$/.test(otp)) {
addMessage('❌ OTP must be exactly 6 digits', 'error');
return;
}
const endpoint = currentUserType === 'platform'
? `${apiUrl}/api/Auth/verify-2fa`
: `${apiUrl}/api/v1/business/auth/verify-2fa`;
// Field name differs: platform uses "code", business uses "otp"
const body = currentUserType === 'platform'
? { challengeToken: currentChallengeToken, code: otp }
: { challengeToken: currentChallengeToken, otp };
addMessage(`🔐 Verifying OTP...`, 'info');
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
const data = await response.json();
if (!response.ok || !data.success) {
addMessage(`❌ OTP verification failed: ${data.error?.message || data.message || 'Invalid OTP'}`, 'error');
return;
}
const accessToken = data.data.accessToken;
if (!accessToken) {
addMessage('❌ Token not found in response', 'error');
return;
}
tokenInput.value = accessToken;
currentChallengeToken = null;
otpSection.style.display = 'none';
const userName = data.data.user?.fullName ?? data.data.user?.email ?? email;
addMessage(`✅ OTP verified! Token auto-filled for ${userName}`, 'success');
addMessage(`ℹ️ Click "Connect to Hub" to open the SignalR connection`, 'info');
} catch (error) {
addMessage(`❌ OTP verify error: ${error.message}`, 'error');
}
}
// Allow pressing Enter in OTP field to submit
document.getElementById('otpCode').addEventListener('keydown', e => {
if (e.key === 'Enter') verifyOtp();
});
async function connect() {
const token = tokenInput.value.trim();
const apiUrl = document.getElementById('apiUrl').value.trim();
if (!token) {
addMessage('❌ Please complete login first to get a JWT token', 'error');
return;
}
try {
updateStatus('🟡 Connecting...', 'connecting');
connectBtn.disabled = true;
const hubUrl = `${apiUrl}/hubs/notifications`;
addMessage(`📡 Connecting to ${hubUrl}...`, 'info');
connection = new signalR.HubConnectionBuilder()
.withUrl(hubUrl, { accessTokenFactory: () => token })
.withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Information)
.build();
connection.onclose((error) => {
updateStatus('⚫ Disconnected', 'disconnected');
connectBtn.disabled = false;
disconnectBtn.disabled = true;
if (error) addMessage(`❌ Connection closed with error: ${error}`, 'error');
else addMessage('🔌 Connection closed', 'info');
});
connection.onreconnecting((error) => {
updateStatus('🟡 Reconnecting...', 'connecting');
addMessage(`🔄 Reconnecting... ${error || ''}`, 'info');
});
connection.onreconnected((connectionId) => {
updateStatus('🟢 Connected', 'connected');
addMessage(`✅ Reconnected! Connection ID: ${connectionId}`, 'success');
});
connection.on("ReceiveNotification", (notification) => {
addMessage({
type: 'NOTIFICATION',
title: notification.title,
message: notification.message,
audienceType: notification.audienceType,
metadata: notification.metadata
}, 'notification');
});
connection.on("ReceiveNotificationCount", (count) => {
addMessage(`📊 Unread notification count: ${count}`, 'info');
});
await connection.start();
updateStatus('🟢 Connected', 'connected');
connectBtn.disabled = true;
disconnectBtn.disabled = false;
addMessage(`✅ Successfully connected to SignalR hub!`, 'success');
addMessage(`🎯 Connection ID: ${connection.connectionId}`, 'success');
addMessage(`👂 Listening for notifications...`, 'info');
} catch (error) {
updateStatus('⚫ Connection Failed', 'disconnected');
connectBtn.disabled = false;
disconnectBtn.disabled = true;
addMessage(`❌ Connection error: ${error.message}`, 'error');
if (error.message.includes('401')) {
addMessage('🔐 Authentication failed — your token may be expired. Try logging in again.', 'error');
}
}
}
async function disconnect() {
if (connection) {
try {
await connection.stop();
addMessage('🔌 Disconnected from hub', 'info');
updateStatus('⚫ Disconnected', 'disconnected');
connectBtn.disabled = false;
disconnectBtn.disabled = true;
} catch (error) {
addMessage(`❌ Disconnect error: ${error.message}`, 'error');
}
}
}
function clearMessages() {
messagesDiv.innerHTML = '';
addMessage('🗑️ Messages cleared', 'info');
}
window.addEventListener('load', () => {
addMessage('👋 SignalR Hub Test Client Ready', 'info');
addMessage('ℹ️ Select a user type and follow the steps above to connect', 'info');
});
</script>
</body>
</html>
2026-08-10 19:03:57.920 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/business/login responded 200 in 8.0886 ms
2026-08-10 19:03:57.919 +00:00 [INF] [HTTP] [U:-] [E:-] [C:762d37ec15e5] HTTP GET /UI/business/login 200
Req: [no body]
Res: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In - Wealthmax</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" />
<style>
html, body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f7fa;
}
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: 1.5rem;
}
.brand-logo {
margin-bottom: 1.75rem;
text-align: center;
}
.brand-logo span {
font-size: 1.4rem;
font-weight: 700;
color: #1a1a2e;
letter-spacing: -0.5px;
}
.brand-logo small {
display: block;
font-size: 0.7rem;
color: #6c757d;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 2px;
}
</style>
</head>
<body>
<div class="login-wrapper">
<div class="brand-logo">
<span>Wealthmax</span>
<small>PM CRM</small>
</div>
<div class="card shadow-sm" style="width: 100%; max-width: 400px;">
<div class="card-body p-4">
<h4 class="card-title mb-1 fw-semibold">Sign In</h4>
<p class="text-muted small mb-4">Enter your credentials to access the portal.</p>
<form method="post" novalidate action="/UI/business/login">
<div class="mb-3">
<label class="form-label" for="Email">Email</label>
<input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div class="mb-4">
<label class="form-label" for="Password">Password</label>
<input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of '8'." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-primary w-100">Sign In</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PkPKADDi0hCi7-PdeVDOzpJ4MgPWPZa_-ExCHxBhwo-xP8wbS1tUiFm9wvKzHfvxq-iGFI0ZCv4hCiHTlEyLVb-AaZYn5txQw3_3taLT354iwIYCcAWOioNiKrpJ24X5I2GaEs0-W08gdoWbMW8y5A" /></form>
<div class="mt-3 text-center">
<a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a>
</div>
</div>
</div>
</div>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
</body>
</html>
2026-08-10 19:03:57.819 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /UI/Reporting/Index responded 302 in 0.5947 ms
2026-08-10 19:03:57.819 +00:00 [INF] [HTTP] [U:-] [E:-] [C:2d4b59d53437] HTTP GET /UI/Reporting/Index 302
Req: [no body]
Res: [empty response]
2026-08-10 19:03:07.773 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /css/commissions.css responded 200 in 1.0770 ms
2026-08-10 19:03:07.773 +00:00 [INF] [HTTP] [U:-] [E:-] [C:-] HTTP GET /css/commissions.css 200
Req: [no body]
Res: /* ============================================================
Wealthmax UI — scoped clean-fintech light theme
Applies under .commissions-area (Commissions module) and
.wm-ui-area (all other modernised UI pages) so that the
design tokens and cm-* components are shared across the app
without leaking into legacy Bootstrap pages.
============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
/* ── Design tokens ─────────────────────────────────────────── */
.commissions-area,
.wm-ui-area {
--cm-canvas: #f4f6fb;
--cm-surface: #ffffff;
--cm-border: #e8ecf4;
--cm-border-light: #f0f3f9;
--cm-radius: 14px;
--cm-radius-sm: 8px;
--cm-shadow: 0 1px 3px rgba(30,41,80,.06), 0 4px 16px rgba(30,41,80,.07);
--cm-shadow-hover: 0 4px 12px rgba(30,41,80,.10), 0 12px 32px rgba(30,41,80,.10);
--cm-font: 'Inter', system-ui, -apple-system, sans-serif;
--cm-accent: #4361ee;
--cm-accent-muted: #eef1fc;
--cm-text: #1a2035;
--cm-text-muted: #7b8ab8;
--cm-text-light: #a8b4d0;
--cm-green: #10b981;
--cm-green-muted: #ecfdf5;
--cm-amber: #f59e0b;
--cm-amber-muted: #fffbeb;
--cm-red: #ef4444;
--cm-red-muted: #fef2f2;
--cm-blue: #3b82f6;
--cm-blue-muted: #eff6ff;
--cm-violet: #8b5cf6;
--cm-violet-muted: #f5f3ff;
--cm-slate: #64748b;
--cm-slate-muted: #f8fafc;
font-family: var(--cm-font);
background-color: var(--cm-canvas);
color: var(--cm-text);
}
/* ── Page background (full main viewport) ───────────────────── */
.commissions-area .page-bg-fix {
background: var(--cm-canvas);
}
/* ── Page header ────────────────────────────────────────────── */
.cm-page-head {
margin-bottom: 1.75rem;
}
.cm-page-head h3,
.cm-page-head .cm-title {
font-size: 1.5rem;
font-weight: 700;
color: var(--cm-text);
letter-spacing: -0.02em;
margin: 0;
}
.cm-page-head .cm-subtitle {
font-size: 0.8125rem;
color: var(--cm-text-muted);
margin-top: 0.2rem;
}
/* ── Preview badge (replaces the stock warning badge) ───────── */
.cm-preview-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 2px 8px;
border-radius: 20px;
background: #fff8e6;
color: #b45309;
border: 1px solid #fcd34d;
vertical-align: middle;
}
/* ── KPI tiles ───────────────────────────────────────────────── */
.cm-kpi {
background: var(--cm-surface);
border-radius: var(--cm-radius);
box-shadow: var(--cm-shadow);
padding: 1.25rem 1.375rem;
position: relative;
overflow: hidden;
transition: box-shadow .18s, transform .18s;
border: 1px solid var(--cm-border-light);
}
.cm-kpi:hover {
box-shadow: var(--cm-shadow-hover);
transform: translateY(-2px);
}
.cm-kpi::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
border-radius: var(--cm-radius) var(--cm-radius) 0 0;
}
.cm-kpi-green::before { background: linear-gradient(90deg, #10b981, #34d399); }
.cm-kpi-amber::before { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
.cm-kpi-blue::before { background: linear-gradient(90deg, #3b82f6, #60a5fa); }
.cm-kpi-red::before { background: linear-gradient(90deg, #ef4444, #f87171); }
.cm-kpi-violet::before { background: linear-gradient(90deg, #8b5cf6, #a78bfa); }
.cm-kpi-slate::before { background: linear-gradient(90deg, #64748b, #94a3b8); }
.cm-kpi-icon {
width: 36px; height: 36px;
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 1rem;
margin-bottom: 0.875rem;
flex-shrink: 0;
}
.cm-kpi-green .cm-kpi-icon { background: var(--cm-green-muted); color: var(--cm-green); }
.cm-kpi-amber .cm-kpi-icon { background: var(--cm-amber-muted); color: var(--cm-amber); }
.cm-kpi-blue .cm-kpi-icon { background: var(--cm-blue-muted); color: var(--cm-blue); }
.cm-kpi-red .cm-kpi-icon { background: var(--cm-red-muted); color: var(--cm-red); }
.cm-kpi-violet .cm-kpi-icon { background: var(--cm-violet-muted); color: var(--cm-violet); }
.cm-kpi-slate .cm-kpi-icon { background: var(--cm-slate-muted); color: var(--cm-slate); }
.cm-kpi-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--cm-text-muted);
margin-bottom: 0.25rem;
}
.cm-kpi-value {
font-size: 1.625rem;
font-weight: 700;
color: var(--cm-text);
letter-spacing: -0.025em;
line-height: 1.1;
}
.cm-kpi-sub {
font-size: 0.75rem;
color: var(--cm-text-muted);
margin-top: 0.3rem;
}
/* ── Cards ───────────────────────────────────────────────────── */
.cm-card {
background: var(--cm-surface);
border-radius: var(--cm-radius);
box-shadow: var(--cm-shadow);
border: 1px solid var(--cm-border-light);
overflow: hidden;
}
.cm-card-header {
padding: 1rem 1.375rem;
border-bottom: 1px solid var(--cm-border);
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
background: var(--cm-surface);
}
.cm-card-header-title {
font-size: 0.875rem;
font-weight: 600;
color: var(--cm-text);
display: flex;
align-items: center;
gap: 0.5rem;
}
.cm-card-header-title i {
color: var(--cm-accent);
font-size: 1rem;
}
.cm-card-header-meta {
font-size: 0.75rem;
color: var(--cm-text-muted);
}
.cm-card-body {
padding: 1.25rem 1.375rem;
}
/* Nav cards (dashboard) */
.cm-nav-card {
background: var(--cm-surface);
border-radius: var(--cm-radius);
box-shadow: var(--cm-shadow);
border: 1px solid var(--cm-border-light);
padding: 1.25rem 1.375rem;
display: flex;
align-items: flex-start;
gap: 1rem;
text-decoration: none;
transition: box-shadow .18s, transform .18s, border-color .18s;
height: 100%;
}
.cm-nav-card:hover {
box-shadow: var(--cm-shadow-hover);
transform: translateY(-3px);
border-color: var(--cm-accent);
text-decoration: none;
}
.cm-nav-card-icon {
width: 44px; height: 44px;
border-radius: 12px;
background: var(--cm-accent-muted);
color: var(--cm-accent);
display: flex; align-items: center; justify-content: center;
font-size: 1.25rem;
flex-shrink: 0;
}
.cm-nav-card-title {
font-size: 0.9rem;
font-weight: 600;
color: var(--cm-text);
margin-bottom: 0.25rem;
}
.cm-nav-card-desc {
font-size: 0.78rem;
color: var(--cm-text-muted);
line-height: 1.4;
margin: 0;
}
/* ── Tables ──────────────────────────────────────────────────── */
.commissions-area .cm-table,
.wm-ui-area .cm-table {
margin: 0;
font-size: 0.8375rem;
color: var(--cm-text);
border-collapse: collapse;
width: 100%;
}
.commissions-area .cm-table thead th,
.wm-ui-area .cm-table thead th {
background: var(--cm-canvas);
color: var(--cm-text-muted);
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--cm-border);
border-top: none;
white-space: nowrap;
}
.commissions-area .cm-table tbody td,
.wm-ui-area .cm-table tbody td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--cm-border-light);
vertical-align: middle;
}
.commissions-area .cm-table tbody tr:last-child td,
.wm-ui-area .cm-table tbody tr:last-child td {
border-bottom: none;
}
.commissions-area .cm-table tbody tr:hover td,
.wm-ui-area .cm-table tbody tr:hover td {
background: var(--cm-canvas);
}
.commissions-area .cm-table tfoot td,
.wm-ui-area .cm-table tfoot td {
padding: 0.75rem 1rem;
border-top: 2px solid var(--cm-border);
background: var(--cm-canvas);
font-weight: 600;
font-size: 0.8375rem;
}
/* ── Badges / pills ──────────────────────────────────────────── */
.cm-pill {
display: inline-flex;
align-items: center;
gap: 3px;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.02em;
padding: 2px 9px;
border-radius: 20px;
line-height: 1.6;
white-space: nowrap;
}
.cm-pill-green { background: var(--cm-green-muted); color: #065f46; }
.cm-pill-amber { background: var(--cm-amber-muted); color: #92400e; }
.cm-pill-blue { background: var(--cm-blue-muted); color: #1e40af; }
.cm-pill-red { background: var(--cm-red-muted); color: #991b1b; }
.cm-pill-violet { background: var(--cm-violet-muted); color: #5b21b6; }
.cm-pill-slate { background: var(--cm-slate-muted); color: #334155; border: 1px solid #e2e8f0; }
.cm-pill-info { background: #eff6ff; color: #1e40af; }
.cm-pill-warn { background: var(--cm-amber-muted); color: #92400e; }
/* ── Buttons ─────────────────────────────────────────────────── */
.commissions-area .cm-btn-back,
.wm-ui-area .cm-btn-back {
font-size: 0.8125rem;
font-weight: 500;
padding: 0.375rem 0.875rem;
border-radius: var(--cm-radius-sm);
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.35rem;
transition: border-color .14s, color .14s, background .14s;
}
.commissions-area .cm-btn-back:hover,
.wm-ui-area .cm-btn-back:hover {
border-color: var(--cm-accent);
color: var(--cm-accent);
background: var(--cm-accent-muted);
text-decoration: none;
}
.commissions-area .cm-btn-primary,
.wm-ui-area .cm-btn-primary {
font-size: 0.8125rem;
font-weight: 500;
padding: 0.375rem 0.875rem;
border-radius: var(--cm-radius-sm);
border: 1px solid var(--cm-accent);
background: var(--cm-accent);
color: #fff;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.35rem;
transition: opacity .14s;
}
.commissions-area .cm-btn-primary:hover,
.wm-ui-area .cm-btn-primary:hover {
opacity: 0.88;
color: #fff;
text-decoration: none;
}
.commissions-area .cm-btn-action,
.wm-ui-area .cm-btn-action {
font-size: 0.75rem;
font-weight: 500;
padding: 0.25rem 0.625rem;
border-radius: 6px;
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.25rem;
transition: border-color .14s, color .14s;
white-space: nowrap;
}
.commissions-area .cm-btn-action:hover,
.wm-ui-area .cm-btn-action:hover {
border-color: var(--cm-accent);
color: var(--cm-accent);
text-decoration: none;
}
.commissions-area .cm-btn-action.cm-btn-action-primary,
.wm-ui-area .cm-btn-action.cm-btn-action-primary {
border-color: var(--cm-accent);
color: var(--cm-accent);
}
.commissions-area .cm-btn-action.cm-btn-action-primary:hover,
.wm-ui-area .cm-btn-action.cm-btn-action-primary:hover {
background: var(--cm-accent-muted);
}
/* ── Form controls inside tables ─────────────────────────────── */
.commissions-area .cm-table .form-control,
.wm-ui-area .cm-table .form-control {
font-size: 0.8125rem;
border-radius: 6px;
border-color: var(--cm-border);
background: var(--cm-canvas);
color: var(--cm-text);
}
.commissions-area .cm-table .input-group-text,
.wm-ui-area .cm-table .input-group-text {
font-size: 0.8125rem;
background: var(--cm-border-light);
border-color: var(--cm-border);
color: var(--cm-text-muted);
}
/* ── Info callout ────────────────────────────────────────────── */
.cm-callout {
display: flex;
align-items: flex-start;
gap: 0.6rem;
padding: 0.875rem 1rem;
border-radius: var(--cm-radius-sm);
font-size: 0.8rem;
line-height: 1.5;
border: 1px solid;
}
.cm-callout-info {
background: var(--cm-blue-muted);
border-color: #bfdbfe;
color: #1e40af;
}
.cm-callout-warn {
background: var(--cm-amber-muted);
border-color: #fde68a;
color: #92400e;
}
.cm-callout-success {
background: var(--cm-green-muted);
border-color: #a7f3d0;
color: #065f46;
}
.cm-callout-danger {
background: var(--cm-red-muted);
border-color: #fecaca;
color: #991b1b;
}
.cm-callout i {
margin-top: 1px;
flex-shrink: 0;
font-size: 0.95rem;
}
/* ── Audit / event stream ────────────────────────────────────── */
.cm-event-list {
list-style: none;
padding: 0; margin: 0;
}
.cm-event-item {
padding: 0.875rem 0;
border-bottom: 1px solid var(--cm-border-light);
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.cm-event-item:last-child {
border-bottom: none;
}
.cm-event-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.cm-event-type {
font-size: 0.8375rem;
font-weight: 600;
color: var(--cm-text);
display: flex;
align-items: center;
gap: 0.375rem;
}
.cm-event-ref {
font-size: 0.7rem;
font-weight: 500;
padding: 1px 7px;
border-radius: 4px;
background: var(--cm-canvas);
border: 1px solid var(--cm-border);
color: var(--cm-text-muted);
font-family: ui-monospace, 'Cascadia Code', monospace;
}
.cm-event-meta {
font-size: 0.75rem;
color: var(--cm-text-light);
white-space: nowrap;
}
.cm-event-detail {
font-size: 0.78rem;
color: var(--cm-text-muted);
}
/* ── Metadata row (key/value pairs) ─────────────────────────── */
.cm-meta-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.45rem 0;
border-bottom: 1px solid var(--cm-border-light);
font-size: 0.8125rem;
}
.cm-meta-row:last-child {
border-bottom: none;
}
.cm-meta-label {
color: var(--cm-text-muted);
}
.cm-meta-value {
font-weight: 600;
color: var(--cm-text);
}
/* ── Total banner (Profile page) ────────────────────────────── */
.cm-total-banner {
border-radius: var(--cm-radius-sm);
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.8375rem;
font-weight: 500;
border: 1px solid;
margin-top: 1rem;
}
.cm-total-banner.ok {
background: var(--cm-green-muted);
border-color: #a7f3d0;
color: #065f46;
}
.cm-total-banner.err {
background: var(--cm-red-muted);
border-color: #fecaca;
color: #991b1b;
}
/* ── Section divider label ───────────────────────────────────── */
.cm-section-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--cm-text-muted);
margin-bottom: 0.75rem;
padding-bottom: 0.4rem;
border-bottom: 1px solid var(--cm-border-light);
}
/* ── Tabbed output card (shared by AllocationDetail + Lifecycle) ─ */
.commissions-area .sim-tabs-card,
.wm-ui-area .sim-tabs-card { overflow: visible; }
.commissions-area .sim-tabnav,
.wm-ui-area .sim-tabnav {
display: flex;
gap: 2px;
padding: 0 0.5rem;
border-bottom: 1px solid var(--cm-border);
background: var(--cm-canvas);
border-radius: var(--cm-radius) var(--cm-radius) 0 0;
flex-wrap: wrap;
}
.commissions-area .sim-tab,
.wm-ui-area .sim-tab {
position: relative;
border: none;
background: transparent;
cursor: pointer;
font-size: 0.8125rem;
font-weight: 600;
color: var(--cm-text-muted);
padding: 0.75rem 0.95rem;
display: inline-flex;
align-items: center;
gap: 0.4rem;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: color .14s, border-color .14s;
}
.commissions-area .sim-tab i,
.wm-ui-area .sim-tab i { font-size: 0.9rem; }
.commissions-area .sim-tab:hover,
.wm-ui-area .sim-tab:hover { color: var(--cm-text); }
.commissions-area .sim-tab.is-active,
.wm-ui-area .sim-tab.is-active {
color: var(--cm-accent);
border-bottom-color: var(--cm-accent);
}
.commissions-area .sim-tab-sub,
.wm-ui-area .sim-tab-sub {
font-weight: 400;
color: var(--cm-text-muted);
font-size: 0.75rem;
}
.commissions-area .sim-tab-count,
.wm-ui-area .sim-tab-count {
font-size: 0.68rem;
font-weight: 700;
line-height: 1;
padding: 2px 6px;
border-radius: 20px;
background: var(--cm-accent-muted);
color: var(--cm-accent);
}
.commissions-area .sim-tabpanel,
.wm-ui-area .sim-tabpanel { display: none; }
.commissions-area .sim-tabpanel.is-active,
.wm-ui-area .sim-tabpanel.is-active { display: block; }
/* Toolbar strip inside a panel (legend / heading row) */
.commissions-area .sim-panel-toolbar,
.wm-ui-area .sim-panel-toolbar {
padding: 0.75rem 1.375rem;
border-bottom: 1px solid var(--cm-border-light);
background: var(--cm-surface);
}
.commissions-area .sim-panel-toolbar-between,
.wm-ui-area .sim-panel-toolbar-between {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
}
.commissions-area .sim-panel-heading,
.wm-ui-area .sim-panel-heading {
font-size: 0.8rem;
font-weight: 600;
color: var(--cm-text);
}
/* Stronger totals band in a ledger footer */
.commissions-area .cm-table.cm-table-totals tfoot td,
.wm-ui-area .cm-table.cm-table-totals tfoot td {
border-top: 2px solid var(--cm-accent);
background: var(--cm-accent-muted);
color: var(--cm-text);
}
.commissions-area .cm-table.cm-table-totals tfoot td:first-child,
.wm-ui-area .cm-table.cm-table-totals tfoot td:first-child {
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.72rem;
color: var(--cm-accent);
}
/* Bounded event-log items so entries don't blend together */
.commissions-area .cm-event-list.cm-event-list-cards .cm-event-item,
.wm-ui-area .cm-event-list.cm-event-list-cards .cm-event-item {
padding: 0.75rem 0.85rem;
margin-bottom: 0.55rem;
border: 1px solid var(--cm-border-light);
border-left-width: 3px;
border-radius: var(--cm-radius-sm);
background: var(--cm-surface);
}
.commissions-area .cm-event-list.cm-event-list-cards .cm-event-item:last-child,
.wm-ui-area .cm-event-list.cm-event-list-cards .cm-event-item:last-child {
margin-bottom: 0;
}
/* ── Chart legend ────────────────────────────────────────────── */
.cm-legend {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
font-size: 0.75rem;
color: var(--cm-text-muted);
align-items: center;
}
.cm-legend-item {
display: flex;
align-items: center;
gap: 5px;
}
.cm-legend-dot {
width: 10px; height: 10px;
border-radius: 3px;
display: inline-block;
flex-shrink: 0;
}
.cm-legend-dot-circle {
border-radius: 50%;
}
/* ── Form controls (wm-ui-area pages: Reporting, Templates, etc.) */
.wm-ui-area .form-control,
.wm-ui-area .form-select {
font-size: 0.8375rem;
border-color: var(--cm-border);
border-radius: var(--cm-radius-sm);
background: var(--cm-surface);
color: var(--cm-text);
}
.wm-ui-area .form-control:focus,
.wm-ui-area .form-select:focus {
border-color: var(--cm-accent);
box-shadow: 0 0 0 3px rgba(67,97,238,.12);
}
.wm-ui-area .form-label {
font-size: 0.8rem;
font-weight: 600;
color: var(--cm-text-muted);
letter-spacing: 0.02em;
}
.wm-ui-area .form-check-input:checked {
background-color: var(--cm-accent);
border-color: var(--cm-accent);
}
/* ── Status badge override (replaces Bootstrap badge) ─────────── */
.wm-ui-area .cm-status-active { background: var(--cm-green-muted); color: #065f46; }
.wm-ui-area .cm-status-inactive { background: var(--cm-slate-muted); color: #334155; border: 1px solid #e2e8f0; }
.wm-ui-area .cm-status-system { background: var(--cm-blue-muted); color: #1e40af; }
/* ── Pagination ─────────────────────────────────────────────── */
.wm-ui-area .pagination .page-link {
font-size: 0.8rem;
color: var(--cm-text-muted);
border-color: var(--cm-border);
background: var(--cm-surface);
}
.wm-ui-area .pagination .page-item.active .page-link {
background: var(--cm-accent);
border-color: var(--cm-accent);
color: #fff;
}
/* ── Upload Commission Statement modal ─────────────────────────── */
.cm-upload-modal {
border-radius: var(--cm-radius);
border: 1px solid var(--cm-border);
}
.cm-upload-icon {
width: 44px;
height: 44px;
flex-shrink: 0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: var(--cm-accent-muted);
color: var(--cm-accent);
font-size: 1.1rem;
}
.cm-upload-template-card {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.875rem 1rem;
margin: 1rem 0;
border-radius: var(--cm-radius-sm);
background: var(--cm-canvas);
border: 1px solid var(--cm-border-light);
}
.cm-upload-template-icon {
width: 34px;
height: 34px;
flex-shrink: 0;
border-radius: var(--cm-radius-sm);
display: flex;
align-items: center;
justify-content: center;
background: var(--cm-green-muted);
color: var(--cm-green);
}
.cm-upload-template-text { flex: 1 1 auto; }
.cm-upload-template-title {
font-size: 0.8375rem;
font-weight: 600;
color: var(--cm-text);
}
.cm-upload-template-desc {
font-size: 0.75rem;
color: var(--cm-text-muted);
}
.cm-upload-segment {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.cm-upload-segment-btn {
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-size: 0.8125rem;
font-weight: 600;
padding: 0.4rem 1rem;
border-radius: 20px;
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
transition: border-color .14s, color .14s, background .14s;
}
.cm-upload-segment-btn.is-active {
background: var(--cm-accent);
border-color: var(--cm-accent);
color: #fff;
}
.cm-upload-segment-btn:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.cm-upload-dropzone {
border: 2px dashed var(--cm-border);
border-radius: var(--cm-radius-sm);
background: var(--cm-canvas);
padding: 2rem 1rem;
text-align: center;
cursor: pointer;
transition: border-color .14s, background .14s;
margin-bottom: 1rem;
}
.cm-upload-dropzone.is-dragover {
border-color: var(--cm-accent);
background: var(--cm-accent-muted);
}
.cm-upload-dropzone-icon {
display: inline-flex;
width: 44px;
height: 44px;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--cm-accent-muted);
color: var(--cm-accent);
font-size: 1.25rem;
margin-bottom: 0.6rem;
}
.cm-upload-dropzone-text {
font-size: 0.8375rem;
color: var(--cm-text);
}
.cm-upload-link {
background: none;
border: none;
padding: 0;
color: var(--cm-accent);
font-weight: 600;
font-size: 0.8375rem;
}
.cm-upload-dropzone-hint {
font-size: 0.72rem;
color: var(--cm-text-light);
margin-top: 0.3rem;
}
.cm-upload-file {
display: flex;
align-items: flex-start;
gap: 0.75rem;
padding: 0.875rem 1rem;
margin-bottom: 1rem;
border-radius: var(--cm-radius-sm);
background: var(--cm-surface);
border: 1px solid var(--cm-border);
}
.cm-upload-file-icon {
width: 34px;
height: 34px;
flex-shrink: 0;
border-radius: var(--cm-radius-sm);
display: flex;
align-items: center;
justify-content: center;
background: var(--cm-green-muted);
color: var(--cm-green);
}
.cm-upload-file-info { flex: 1 1 auto; min-width: 0; }
.cm-upload-file-name {
font-size: 0.8375rem;
font-weight: 600;
color: var(--cm-text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cm-upload-file-size {
font-size: 0.72rem;
color: var(--cm-text-muted);
margin-bottom: 0.4rem;
}
.cm-upload-file-actions {
display: flex;
gap: 0.5rem;
flex-shrink: 0;
}
.cm-upload-remove-btn:hover {
border-color: var(--cm-red) !important;
color: var(--cm-red) !important;
background: var(--cm-red-muted) !important;
}
.cm-upload-progress {
height: 6px;
border-radius: 4px;
background: var(--cm-border-light);
overflow: hidden;
}
.cm-upload-progress-bar {
height: 100%;
width: 0%;
background: var(--cm-accent);
border-radius: 4px;
transition: width .2s ease;
}
/* ── State panels ────────────────────────────────────────────── */
.cm-upload-alert {
border-radius: var(--cm-radius-sm);
border: 1px solid;
padding: 1rem;
margin-bottom: 1rem;
}
.cm-upload-alert--error { background: var(--cm-red-muted); border-color: #fecaca; }
.cm-upload-alert--warning { background: var(--cm-amber-muted); border-color: #fde68a; }
.cm-upload-alert--success {
background: var(--cm-green-muted);
border-color: #a7f3d0;
display: flex;
align-items: center;
gap: 0.6rem;
color: #065f46;
font-size: 0.8375rem;
font-weight: 500;
}
.cm-upload-alert--success i { font-size: 1.1rem; }
.cm-upload-alert-header {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.8375rem;
font-weight: 600;
color: var(--cm-text);
margin-bottom: 0.5rem;
}
.cm-upload-alert--error .cm-upload-alert-header i { color: var(--cm-red); }
.cm-upload-alert--warning .cm-upload-alert-header i { color: var(--cm-amber); }
.cm-upload-warning-list {
margin: 0 0 0.85rem;
padding-left: 1.1rem;
font-size: 0.8rem;
color: #92400e;
}
.cm-upload-warning-list li { margin-bottom: 0.2rem; }
.cm-upload-review-btn { font-size: 0.8125rem; }
.cm-upload-stats {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 0.6rem;
margin-bottom: 0.85rem;
}
.cm-upload-stat {
background: var(--cm-surface);
border: 1px solid var(--cm-border-light);
border-radius: var(--cm-radius-sm);
padding: 0.6rem 0.7rem;
text-align: center;
}
.cm-upload-stat-label {
font-size: 0.65rem;
color: var(--cm-text-muted);
text-transform: uppercase;
letter-spacing: 0.03em;
margin-bottom: 0.2rem;
}
.cm-upload-stat-value {
font-size: 1.15rem;
font-weight: 700;
color: var(--cm-text);
margin-bottom: 0.3rem;
}
.cm-upload-section-label {
font-size: 0.75rem;
font-weight: 600;
color: var(--cm-text);
margin-bottom: 0.5rem;
}
/* ── Warning review table ────────────────────────────────────── */
.cm-upload-review {
border-radius: var(--cm-radius-sm);
border: 1px solid #fde68a;
background: var(--cm-amber-muted);
padding: 1rem;
margin-bottom: 1rem;
}
.cm-upload-review-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 1rem;
flex-wrap: wrap;
margin-bottom: 0.75rem;
}
.cm-upload-review-actions {
display: flex;
gap: 0.5rem;
flex-shrink: 0;
}
.cm-upload-skipall-btn:hover {
border-color: var(--cm-red) !important;
color: var(--cm-red) !important;
}
.cm-upload-review-progress {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.75rem;
color: #92400e;
font-weight: 500;
margin-bottom: 0.85rem;
}
.cm-upload-review-progress .cm-upload-progress {
flex: 1 1 auto;
background: rgba(255,255,255,.6);
}
.cm-upload-review .cm-table {
background: var(--cm-surface);
}
.cm-upload-muted { color: var(--cm-text-light); }
.cm-upload-subtext {
font-size: 0.7rem;
color: var(--cm-text-muted);
margin-top: 1px;
}
.cm-upload-kebab-btn {
width: 28px;
height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 6px;
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
}
.cm-upload-kebab-btn:hover {
border-color: var(--cm-accent);
color: var(--cm-accent);
}
.cm-upload-fix-row input.form-control {
font-size: 0.8125rem;
}
.cm-upload-fix-inputs {
display: flex;
gap: 0.4rem;
}
.cm-upload-fix-inputs input.form-control {
flex: 1 1 0;
min-width: 0;
}
.cm-upload-fix-error {
margin-top: 0.3rem;
font-size: 0.75rem;
color: var(--cm-red);
}
.cm-upload-fix-actions {
display: flex;
gap: 0.35rem;
justify-content: flex-end;
}
.cm-upload-fix-actions button {
width: 28px;
height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 6px;
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
}
.cm-upload-fix-confirm:hover {
border-color: var(--cm-green);
color: var(--cm-green);
}
.cm-upload-fix-cancel:hover {
border-color: var(--cm-red);
color: var(--cm-red);
}
.cm-upload-fix-trigger:hover {
border-color: var(--cm-accent);
color: var(--cm-accent);
}
.cm-upload-skip-trigger:hover {
border-color: var(--cm-red);
color: var(--cm-red);
}
.cm-upload-tips { margin-top: 0.25rem; }
@media (max-width: 640px) {
.cm-upload-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cm-upload-review-header { flex-direction: column; }
}
/* ============================================================
Commission Allocation Management page (tabs, bulk-action bar,
filters, expandable rows, pagination, Overwrite modal)
============================================================ */
/* ── Segment toggle (Protection / Mortgage) ─────────────────── */
.cm-segment-toggle {
display: inline-flex;
gap: 0.35rem;
background: var(--cm-slate-muted);
border: 1px solid var(--cm-border);
border-radius: 999px;
padding: 3px;
}
.cm-segment-btn {
display: inline-flex;
align-items: center;
gap: 0.35rem;
border: none;
background: transparent;
color: var(--cm-text-muted);
font-size: 0.8125rem;
font-weight: 600;
padding: 0.4rem 0.9rem;
border-radius: 999px;
white-space: nowrap;
}
.cm-segment-btn.is-active {
background: var(--cm-surface);
color: var(--cm-accent);
box-shadow: var(--cm-shadow);
}
.cm-segment-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* ── Tab strip ───────────────────────────────────────────────── */
.cm-tabstrip {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
background: var(--cm-surface);
border: 1px solid var(--cm-border);
border-radius: var(--cm-radius-sm);
padding: 0.5rem;
margin-bottom: 0.75rem;
}
.cm-tabstrip-tabs {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
}
.cm-tab-btn {
display: inline-flex;
align-items: center;
gap: 0.4rem;
border: none;
background: transparent;
color: var(--cm-text-muted);
font-size: 0.8125rem;
font-weight: 600;
padding: 0.5rem 0.9rem;
border-radius: var(--cm-radius-sm);
}
.cm-tab-btn:hover {
background: var(--cm-slate-muted);
color: var(--cm-text);
}
.cm-tab-btn.is-active {
background: var(--cm-accent);
color: #fff;
}
.cm-tab-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 5px;
border-radius: 999px;
background: rgba(255,255,255,.25);
font-size: 0.7rem;
font-weight: 700;
}
.cm-tab-btn:not(.is-active) .cm-tab-count {
background: var(--cm-accent-muted);
color: var(--cm-accent);
}
/* ── Bulk-allocate action bar (Unallocated tab) ─────────────── */
.cm-bulk-bar {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
}
.cm-bulk-bar label {
font-size: 0.8125rem;
font-weight: 600;
color: var(--cm-text-muted);
white-space: nowrap;
}
.cm-bulk-bar .form-control,
.cm-bulk-bar .form-select {
font-size: 0.8125rem;
padding: 0.4rem 0.65rem;
}
/* ── Filter row ──────────────────────────────────────────────── */
.cm-filter-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.75rem;
}
.cm-filter-row .form-control,
.cm-filter-row .form-select {
font-size: 0.8125rem;
padding: 0.45rem 0.75rem;
border-color: var(--cm-border);
}
.cm-filter-search {
position: relative;
flex: 1 1 220px;
max-width: 280px;
}
.cm-filter-search i {
position: absolute;
left: 0.7rem;
top: 50%;
transform: translateY(-50%);
color: var(--cm-text-light);
font-size: 0.8rem;
}
.cm-filter-search input {
padding-left: 2rem;
}
.cm-reset-link {
color: var(--cm-red);
font-size: 0.8125rem;
font-weight: 600;
background: none;
border: none;
display: inline-flex;
align-items: center;
gap: 0.3rem;
}
/* ── Expandable line rows ───────────────────────────────────── */
.cm-expand-toggle {
border: none;
background: none;
color: var(--cm-accent);
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
border-radius: 6px;
}
.cm-expand-toggle:hover { background: var(--cm-accent-muted); }
.cm-expand-toggle i { transition: transform .15s ease; }
.cm-expand-toggle.is-open i { transform: rotate(90deg); }
.cm-row-subtext {
font-size: 0.7rem;
color: var(--cm-text-muted);
margin-top: 1px;
}
.cm-row-link {
color: var(--cm-accent);
font-weight: 600;
text-decoration: none;
}
.cm-breakdown-row td {
background: var(--cm-slate-muted);
padding: 0 !important;
}
.cm-breakdown-panel {
padding: 0.9rem 1.1rem 1.1rem;
}
.cm-breakdown-title {
font-size: 0.75rem;
font-weight: 700;
color: var(--cm-text-muted);
text-transform: uppercase;
letter-spacing: .03em;
margin-bottom: 0.5rem;
}
/* ── Pagination footer ──────────────────────────────────────── */
.cm-pagination-footer {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 0.5rem;
padding: 0.85rem 1.1rem;
font-size: 0.8125rem;
color: var(--cm-text-muted);
}
.cm-pagination-pages {
display: flex;
align-items: center;
gap: 0.25rem;
}
.cm-page-btn {
min-width: 30px;
height: 30px;
padding: 0 0.4rem;
border-radius: 7px;
border: 1px solid var(--cm-border);
background: var(--cm-surface);
color: var(--cm-text-muted);
font-size: 0.8125rem;
font-weight: 600;
}
.cm-page-btn:hover:not(:disabled) {
border-color: var(--cm-accent);
color: var(--cm-accent);
}
.cm-page-btn.is-active {
background: var(--cm-accent);
border-color: var(--cm-accent);
color: #fff;
}
.cm-page-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* ── Overwrite modal ─────────────────────────────────────────── */
.cm-overwrite-list {
border: 1px solid var(--cm-blue);
border-radius: var(--cm-radius-sm);
overflow: hidden;
}
.cm-overwrite-row {
display: grid;
grid-template-columns: 1fr 1.4fr 0.9fr;
gap: 0.75rem;
align-items: center;
padding: 0.6rem 0.9rem;
border-bottom: 1px dashed var(--cm-border);
}
.cm-overwrite-row:last-child { border-bottom: none; }
.cm-overwrite-row-label {
font-size: 0.8125rem;
font-weight: 600;
color: var(--cm-text);
}
.cm-overwrite-pct-input {
position: relative;
}
.cm-overwrite-pct-input input {
padding-right: 1.75rem;
}
.cm-overwrite-pct-input i {
position: absolute;
right: 0.65rem;
top: 50%;
transform: translateY(-50%);
color: var(--cm-text-light);
font-size: 0.75rem;
}
.cm-overwrite-total {
font-size: 0.75rem;
font-weight: 600;
margin-top: 0.5rem;
text-align: right;
}
.cm-overwrite-total.is-invalid { color: var(--cm-red); }
.cm-overwrite-total.is-valid { color: var(--cm-green); }
.cm-empty-state {
text-align: center;
padding: 2.5rem 1rem;
color: var(--cm-text-muted);
font-size: 0.8125rem;
}
.cm-checkbox {
width: 16px;
height: 16px;
cursor: pointer;
}
@media (max-width: 992px) {
.cm-overwrite-row { grid-template-columns: 1fr; gap: 0.35rem; }
}
/* ── Responsive tweaks ───────────────────────────────────────── */
@media (max-width: 576px) {
.cm-kpi-value { font-size: 1.25rem; }
.cm-page-head h3, .cm-page-head .cm-title { font-size: 1.25rem; }
}
2026-08-10 19:03:07.640 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /robots.txt responded 401 in 0.6269 ms
2026-08-10 18:42:34.707 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-unallocated responded 200 in 5.8630 ms
2026-08-10 18:42:34.706 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:492fefb04bfa] HTTP GET /api/v1/business/commissions-mortgage-unallocated 200
Req: [no body]
Res: {"success":true,"data":{"content":[],"pagination":{"page":0,"size":10,"totalElements":0,"totalPages":0,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Unallocated mortgage commission entries retrieved successfully.","timestamp":"2026-08-10T18:42:34.706215Z"}
2026-08-10 18:42:30.547 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-overview responded 200 in 10.3503 ms
2026-08-10 18:42:30.547 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:b145e0a4589e] HTTP GET /api/v1/business/commissions-mortgage-overview 200
Req: [no body]
Res: {"success":true,"data":{"entries":{"totalEntries":3,"totalGrossAmount":2900.00,"unallocatedCount":0,"unallocatedGrossAmount":0,"allocatedCount":0,"allocatedGrossAmount":0,"approvedCount":3,"approvedGrossAmount":2900.00,"unpaidSummaryCount":2,"statementsCount":4,"batchesCount":2},"money":{"approvedShareAmount":2900.00,"paidAmount":2140.00,"unpaidAmount":760.00,"accumulatingAmount":0,"adjustments":100.00,"netPayableAmount":860.00,"unpaidRecipientCount":2},"attention":{"unmatchedEntryCount":0,"unallocatableEntryCount":0,"inactiveRecipientAllocationCount":0}},"message":"Mortgage commissions overview retrieved successfully.","timestamp":"2026-08-10T18:42:30.5468459Z"}
2026-08-10 18:42:29.977 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-approved responded 200 in 12.2299 ms
2026-08-10 18:42:29.976 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:5907878b1375] HTTP GET /api/v1/business/commissions-mortgage-approved 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"allocationId":5,"recipientUserId":923,"recipientNameSnapshot":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":60.0000,"amount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":6,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":40.0000,"amount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":1,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":2,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":20.00,"procurationShare":0.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":3,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":880.00,"procurationShare":800.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"},{"allocationId":4,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":220.00,"procurationShare":200.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"}],"pagination":{"page":0,"size":10,"totalElements":6,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Approved mortgage commission retrieved successfully.","timestamp":"2026-08-10T18:42:29.9765116Z"}
2026-08-10 18:42:29.629 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP POST /api/v1/business/commissions-mortgage-approved/move-to-unallocated responded 200 in 5.6148 ms
2026-08-10 18:42:29.629 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:972dcd62c0d8] HTTP POST /api/v1/business/commissions-mortgage-approved/move-to-unallocated 200
Req: {"lineIds":[3,2,1]}
Res: {"success":true,"data":{"revertedCount":0,"skippedLineIds":[],"blockedLineIds":[3,2,1],"skippedEntries":[],"blockedEntries":[{"entryId":3,"reasonCode":"ENTRY_STATEMENTED","reason":"A statement has already been generated for at least one recipient on this entry, so it can no longer be moved or changed."},{"entryId":2,"reasonCode":"ENTRY_STATEMENTED","reason":"A statement has already been generated for at least one recipient on this entry, so it can no longer be moved or changed."},{"entryId":1,"reasonCode":"ENTRY_STATEMENTED","reason":"A statement has already been generated for at least one recipient on this entry, so it can no longer be moved or changed."}],"removedCustomEntryCount":0},"message":"Mortgage commission entries moved to Unallocated successfully.","timestamp":"2026-08-10T18:42:29.6292827Z"}
2026-08-10 18:42:24.021 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-approved responded 200 in 76.1535 ms
2026-08-10 18:42:24.020 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:f5d79b6b9309] HTTP GET /api/v1/business/commissions-mortgage-approved 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"allocationId":5,"recipientUserId":923,"recipientNameSnapshot":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":60.0000,"amount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":6,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":40.0000,"amount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":1,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":2,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":20.00,"procurationShare":0.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":3,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":880.00,"procurationShare":800.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"},{"allocationId":4,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":220.00,"procurationShare":200.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"}],"pagination":{"page":0,"size":10,"totalElements":6,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Approved mortgage commission retrieved successfully.","timestamp":"2026-08-10T18:42:24.0203076Z"}
2026-08-10 18:42:22.400 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-approved responded 200 in 16.7616 ms
2026-08-10 18:42:22.400 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:a84d320d5cb1] HTTP GET /api/v1/business/commissions-mortgage-approved 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"allocationId":5,"recipientUserId":923,"recipientNameSnapshot":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":60.0000,"amount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":6,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":40.0000,"amount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":3,"entryNumber":6,"commissionBatchId":4,"batchReference":"BAT-0004","lenderReferenceNumber":"123456789","clientName":"Steve John","caseId":156,"userFacingCaseId":"CASE-0125","lenderName":"Skipton BS","receivedDate":"01-01-2027","approvedAt":"10-08-2026 18:35"},{"allocationId":1,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Unpaid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":2,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":20.00,"procurationShare":0.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":2,"entryNumber":2,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:42"},{"allocationId":3,"recipientUserId":918,"recipientNameSnapshot":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","isCompanyShare":false,"chainDepth":0,"percentageOfGross":80.0000,"amount":880.00,"procurationShare":800.00,"conveyanceShare":80.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"},{"allocationId":4,"recipientUserId":656,"recipientNameSnapshot":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","isCompanyShare":true,"chainDepth":1,"percentageOfGross":20.0000,"amount":220.00,"procurationShare":200.00,"conveyanceShare":20.00,"brokerageShare":0.00,"paymentStatus":"Paid","isRecipientInactive":false,"entryHasStatementedAllocation":true,"mortgageCommissionEntryId":1,"entryNumber":1,"commissionBatchId":1,"batchReference":"BAT-0001","lenderReferenceNumber":"1212121212","clientName":"AARON FINCH","caseId":331,"userFacingCaseId":"CASE-0264","lenderName":"The Mortgage Works","receivedDate":"02-08-2026","approvedAt":"10-08-2026 14:34"}],"pagination":{"page":0,"size":10,"totalElements":6,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Approved mortgage commission retrieved successfully.","timestamp":"2026-08-10T18:42:22.4001877Z"}
2026-08-10 18:42:20.340 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-statements responded 200 in 8.2426 ms
2026-08-10 18:42:20.340 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:a1082b7f996c] HTTP GET /api/v1/business/commissions-mortgage-statements 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"id":5,"statementReference":"STM-00005","paidDate":"10-08-2026","recipientUserId":923,"recipientName":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":1020.00,"totalPaid":1020.00,"totalAdjustment":200.00,"netAmount":1220.00,"entriesCount":3,"isVisibleToUser":true},{"id":3,"statementReference":"STM-00003","paidDate":"10-08-2026","recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":20.00,"totalPaid":20.00,"totalAdjustment":0.00,"netAmount":20.00,"entriesCount":3,"isVisibleToUser":true},{"id":2,"statementReference":"STM-00002","paidDate":"10-08-2026","recipientUserId":918,"recipientName":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":880.00,"totalPaid":880.00,"totalAdjustment":0,"netAmount":880.00,"entriesCount":1,"isVisibleToUser":true},{"id":1,"statementReference":"STM-00001","paidDate":"10-08-2026","recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":220.00,"totalPaid":220.00,"totalAdjustment":0,"netAmount":220.00,"entriesCount":1,"isVisibleToUser":true}],"pagination":{"page":0,"size":10,"totalElements":4,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Mortgage commission statements retrieved successfully.","timestamp":"2026-08-10T18:42:20.3398718Z"}
2026-08-10 18:42:20.320 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-overview responded 200 in 8.9295 ms
2026-08-10 18:42:20.319 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:71130e899ab0] HTTP GET /api/v1/business/commissions-mortgage-overview 200
Req: [no body]
Res: {"success":true,"data":{"entries":{"totalEntries":3,"totalGrossAmount":2900.00,"unallocatedCount":0,"unallocatedGrossAmount":0,"allocatedCount":0,"allocatedGrossAmount":0,"approvedCount":3,"approvedGrossAmount":2900.00,"unpaidSummaryCount":2,"statementsCount":4,"batchesCount":2},"money":{"approvedShareAmount":2900.00,"paidAmount":2140.00,"unpaidAmount":760.00,"accumulatingAmount":0,"adjustments":100.00,"netPayableAmount":860.00,"unpaidRecipientCount":2},"attention":{"unmatchedEntryCount":0,"unallocatableEntryCount":0,"inactiveRecipientAllocationCount":0}},"message":"Mortgage commissions overview retrieved successfully.","timestamp":"2026-08-10T18:42:20.3192226Z"}
2026-08-10 18:41:59.553 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-statements/5 responded 200 in 11.8798 ms
2026-08-10 18:41:59.553 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:57aad712410e] HTTP GET /api/v1/business/commissions-mortgage-statements/5 200
Req: [no body]
Res: {"success":true,"data":{"allocations":[{"allocationId":5,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[{"id":6,"recipientUserId":923,"entryType":"Adjustment","category":"Mortgage","description":"ADjj","amount":-100.00,"createdAt":"10-08-2026 18:41","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null},{"id":7,"recipientUserId":923,"entryType":"Bonus / Incentive Added","category":"Mortgage","description":"bonusss","amount":300.00,"createdAt":"10-08-2026 18:41","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}],"id":5,"statementReference":"STM-00005","paidDate":"10-08-2026","recipientUserId":923,"recipientName":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":1020.00,"totalPaid":1020.00,"totalAdjustment":200.00,"netAmount":1220.00,"entriesCount":3,"isVisibleToUser":true},"message":"Mortgage commission statement retrieved successfully.","timestamp":"2026-08-10T18:41:59.553021Z"}
2026-08-10 18:41:56.337 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-statements responded 200 in 9.0821 ms
2026-08-10 18:41:56.337 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:40ba5beebe5c] HTTP GET /api/v1/business/commissions-mortgage-statements 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"id":5,"statementReference":"STM-00005","paidDate":"10-08-2026","recipientUserId":923,"recipientName":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":1020.00,"totalPaid":1020.00,"totalAdjustment":200.00,"netAmount":1220.00,"entriesCount":3,"isVisibleToUser":true},{"id":3,"statementReference":"STM-00003","paidDate":"10-08-2026","recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":20.00,"totalPaid":20.00,"totalAdjustment":0.00,"netAmount":20.00,"entriesCount":3,"isVisibleToUser":true},{"id":2,"statementReference":"STM-00002","paidDate":"10-08-2026","recipientUserId":918,"recipientName":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":880.00,"totalPaid":880.00,"totalAdjustment":0,"netAmount":880.00,"entriesCount":1,"isVisibleToUser":true},{"id":1,"statementReference":"STM-00001","paidDate":"10-08-2026","recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","category":"Mortgage","branchName":"Wealthmax Financial Advisers Ltd.","totalCommission":220.00,"totalPaid":220.00,"totalAdjustment":0,"netAmount":220.00,"entriesCount":1,"isVisibleToUser":true}],"pagination":{"page":0,"size":10,"totalElements":4,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Mortgage commission statements retrieved successfully.","timestamp":"2026-08-10T18:41:56.3367496Z"}
2026-08-10 18:41:54.413 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-overview responded 200 in 9.1570 ms
2026-08-10 18:41:54.413 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:ac6ee39b9649] HTTP GET /api/v1/business/commissions-mortgage-overview 200
Req: [no body]
Res: {"success":true,"data":{"entries":{"totalEntries":3,"totalGrossAmount":2900.00,"unallocatedCount":0,"unallocatedGrossAmount":0,"allocatedCount":0,"allocatedGrossAmount":0,"approvedCount":3,"approvedGrossAmount":2900.00,"unpaidSummaryCount":2,"statementsCount":4,"batchesCount":2},"money":{"approvedShareAmount":2900.00,"paidAmount":2140.00,"unpaidAmount":760.00,"accumulatingAmount":0,"adjustments":100.00,"netPayableAmount":860.00,"unpaidRecipientCount":2},"attention":{"unmatchedEntryCount":0,"unallocatableEntryCount":0,"inactiveRecipientAllocationCount":0}},"message":"Mortgage commissions overview retrieved successfully.","timestamp":"2026-08-10T18:41:54.4133266Z"}
2026-08-10 18:41:54.076 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary responded 200 in 11.2898 ms
2026-08-10 18:41:54.076 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:70c98947f6b4] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","entriesCount":1,"totalShareAmount":680.00,"adjustments":0,"netPayable":680.00,"allocations":[{"allocationId":6,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[]},{"recipientUserId":918,"recipientName":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","entriesCount":2,"totalShareAmount":80.00,"adjustments":100.00,"netPayable":180.00,"allocations":[{"allocationId":1,"mortgageCommissionEntryId":2,"caseId":331,"userFacingCaseId":"CASE-0264","lenderReferenceNumber":"1212121212","shareAmount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"approvedAt":"10-08-2026 14:42","receivedDate":"02-08-2026","clientName":"AARON FINCH","lenderName":"The Mortgage Works","productName":"Intermediary BTL 5 Year Fixed 3% Fee","termYears":25,"termMonths":3,"termDays":null,"caseStatusId":595,"policyStatusName":"New Case","caseReviewGrade":null}],"customEntries":[{"id":3,"recipientUserId":918,"entryType":"Bonus / Incentive Added","category":"Mortgage","description":"Bonus","amount":100.00,"createdAt":"10-08-2026 14:44","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}]}],"pagination":{"page":0,"size":10,"totalElements":2,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Unpaid mortgage commission summary retrieved successfully.","timestamp":"2026-08-10T18:41:54.0762456Z"}
2026-08-10 18:41:53.736 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP POST /api/v1/business/commissions-mortgage-statements responded 200 in 79.4389 ms
2026-08-10 18:41:53.735 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:86e5562482c6] HTTP POST /api/v1/business/commissions-mortgage-statements 200
Req: {"recipientUserIds":[923]}
Res: {"success":true,"data":{"createdStatementIds":[5],"skippedUserIds":[]},"message":"Mortgage commission statements created successfully.","timestamp":"2026-08-10T18:41:53.7356203Z"}
2026-08-10 18:41:28.905 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-overview responded 200 in 8.5207 ms
2026-08-10 18:41:28.905 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:666dbe1d5c9d] HTTP GET /api/v1/business/commissions-mortgage-overview 200
Req: [no body]
Res: {"success":true,"data":{"entries":{"totalEntries":3,"totalGrossAmount":2900.00,"unallocatedCount":0,"unallocatedGrossAmount":0,"allocatedCount":0,"allocatedGrossAmount":0,"approvedCount":3,"approvedGrossAmount":2900.00,"unpaidSummaryCount":3,"statementsCount":3,"batchesCount":2},"money":{"approvedShareAmount":2900.00,"paidAmount":1120.00,"unpaidAmount":1780.00,"accumulatingAmount":0,"adjustments":300.00,"netPayableAmount":2080.00,"unpaidRecipientCount":3},"attention":{"unmatchedEntryCount":0,"unallocatableEntryCount":0,"inactiveRecipientAllocationCount":0}},"message":"Mortgage commissions overview retrieved successfully.","timestamp":"2026-08-10T18:41:28.9056105Z"}
2026-08-10 18:41:28.563 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary responded 200 in 11.4192 ms
2026-08-10 18:41:28.563 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:5b5ad7fd9b89] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","entriesCount":1,"totalShareAmount":680.00,"adjustments":0,"netPayable":680.00,"allocations":[{"allocationId":6,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[]},{"recipientUserId":918,"recipientName":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","entriesCount":2,"totalShareAmount":80.00,"adjustments":100.00,"netPayable":180.00,"allocations":[{"allocationId":1,"mortgageCommissionEntryId":2,"caseId":331,"userFacingCaseId":"CASE-0264","lenderReferenceNumber":"1212121212","shareAmount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"approvedAt":"10-08-2026 14:42","receivedDate":"02-08-2026","clientName":"AARON FINCH","lenderName":"The Mortgage Works","productName":"Intermediary BTL 5 Year Fixed 3% Fee","termYears":25,"termMonths":3,"termDays":null,"caseStatusId":595,"policyStatusName":"New Case","caseReviewGrade":null}],"customEntries":[{"id":3,"recipientUserId":918,"entryType":"Bonus / Incentive Added","category":"Mortgage","description":"Bonus","amount":100.00,"createdAt":"10-08-2026 14:44","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}]},{"recipientUserId":923,"recipientName":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","entriesCount":3,"totalShareAmount":1020.00,"adjustments":200.00,"netPayable":1220.00,"allocations":[{"allocationId":5,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[{"id":6,"recipientUserId":923,"entryType":"Adjustment","category":"Mortgage","description":"ADjj","amount":-100.00,"createdAt":"10-08-2026 18:41","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null},{"id":7,"recipientUserId":923,"entryType":"Bonus / Incentive Added","category":"Mortgage","description":"bonusss","amount":300.00,"createdAt":"10-08-2026 18:41","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}]}],"pagination":{"page":0,"size":10,"totalElements":3,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Unpaid mortgage commission summary retrieved successfully.","timestamp":"2026-08-10T18:41:28.562704Z"}
2026-08-10 18:41:28.225 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP POST /api/v1/business/commissions-mortgage-unpaid-summary/custom-entries responded 200 in 6.7346 ms
2026-08-10 18:41:28.225 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:57d5859cee28] HTTP POST /api/v1/business/commissions-mortgage-unpaid-summary/custom-entries 200
Req: {"recipientUserIds":[923],"entryType":"Bonus / Incentive Added","description":"bonusss","amount":300}
Res: {"success":true,"data":{"affectedIds":[7],"count":1},"message":"Custom mortgage commission entries added successfully.","timestamp":"2026-08-10T18:41:28.2253533Z"}
2026-08-10 18:41:06.730 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-overview responded 200 in 11.0151 ms
2026-08-10 18:41:06.730 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:ddbd9e1fba4b] HTTP GET /api/v1/business/commissions-mortgage-overview 200
Req: [no body]
Res: {"success":true,"data":{"entries":{"totalEntries":3,"totalGrossAmount":2900.00,"unallocatedCount":0,"unallocatedGrossAmount":0,"allocatedCount":0,"allocatedGrossAmount":0,"approvedCount":3,"approvedGrossAmount":2900.00,"unpaidSummaryCount":3,"statementsCount":3,"batchesCount":2},"money":{"approvedShareAmount":2900.00,"paidAmount":1120.00,"unpaidAmount":1780.00,"accumulatingAmount":0,"adjustments":0.00,"netPayableAmount":1780.00,"unpaidRecipientCount":3},"attention":{"unmatchedEntryCount":0,"unallocatableEntryCount":0,"inactiveRecipientAllocationCount":0}},"message":"Mortgage commissions overview retrieved successfully.","timestamp":"2026-08-10T18:41:06.7300061Z"}
2026-08-10 18:41:06.389 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //erty.php responded 401 in 0.9367 ms
2026-08-10 18:41:06.389 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary responded 200 in 11.0020 ms
2026-08-10 18:41:06.388 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:a3820f1c0914] HTTP GET /api/v1/business/commissions-mortgage-unpaid-summary 200
Req: [no body]
Res: {"success":true,"data":{"content":[{"recipientUserId":656,"recipientName":"Anmol Kaur Bhatti","recipientDesignation":"Administrator","entriesCount":1,"totalShareAmount":680.00,"adjustments":0,"netPayable":680.00,"allocations":[{"allocationId":6,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":680.00,"procurationShare":400.00,"conveyanceShare":200.00,"brokerageShare":80.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[]},{"recipientUserId":918,"recipientName":"Mortgage Adviser User3","recipientDesignation":"Mortgage Adviser","entriesCount":2,"totalShareAmount":80.00,"adjustments":100.00,"netPayable":180.00,"allocations":[{"allocationId":1,"mortgageCommissionEntryId":2,"caseId":331,"userFacingCaseId":"CASE-0264","lenderReferenceNumber":"1212121212","shareAmount":80.00,"procurationShare":0.00,"conveyanceShare":80.00,"brokerageShare":0.00,"approvedAt":"10-08-2026 14:42","receivedDate":"02-08-2026","clientName":"AARON FINCH","lenderName":"The Mortgage Works","productName":"Intermediary BTL 5 Year Fixed 3% Fee","termYears":25,"termMonths":3,"termDays":null,"caseStatusId":595,"policyStatusName":"New Case","caseReviewGrade":null}],"customEntries":[{"id":3,"recipientUserId":918,"entryType":"Bonus / Incentive Added","category":"Mortgage","description":"Bonus","amount":100.00,"createdAt":"10-08-2026 14:44","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}]},{"recipientUserId":923,"recipientName":"Protection & Mortgage Adviser User5","recipientDesignation":"Protection & Mortgage Adviser","entriesCount":2,"totalShareAmount":1020.00,"adjustments":-100.00,"netPayable":920.00,"allocations":[{"allocationId":5,"mortgageCommissionEntryId":3,"caseId":156,"userFacingCaseId":"CASE-0125","lenderReferenceNumber":"123456789","shareAmount":1020.00,"procurationShare":600.00,"conveyanceShare":300.00,"brokerageShare":120.00,"approvedAt":"10-08-2026 18:35","receivedDate":"01-01-2027","clientName":"Steve John","lenderName":"Skipton BS","productName":"2 Year Fixed £1495 Fee Remortgage","termYears":null,"termMonths":null,"termDays":20,"caseStatusId":599,"policyStatusName":"Pre Offer Processing","caseReviewGrade":null}],"customEntries":[{"id":6,"recipientUserId":923,"entryType":"Adjustment","category":"Mortgage","description":"ADjj","amount":-100.00,"createdAt":"10-08-2026 18:41","sourceEntryId":null,"caseId":null,"userFacingCaseId":null,"clientName":null,"lenderName":null,"lenderReferenceNumber":null}]}],"pagination":{"page":0,"size":10,"totalElements":3,"totalPages":1,"hasNext":false,"hasPrevious":false,"isFirst":true,"isLast":true}},"message":"Unpaid mortgage commission summary retrieved successfully.","timestamp":"2026-08-10T18:41:06.3886129Z"}
2026-08-10 18:41:06.322 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //1.php responded 401 in 0.5137 ms
2026-08-10 18:41:06.276 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /Zoo.php responded 401 in 0.6419 ms
2026-08-10 18:41:06.050 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP POST /api/v1/business/commissions-mortgage-unpaid-summary/custom-entries responded 200 in 71.1768 ms
2026-08-10 18:41:06.049 +00:00 [INF] [HTTP] [U:656] [E:anmol.b@wealthmax.co.uk] [C:60de1247d64d] HTTP POST /api/v1/business/commissions-mortgage-unpaid-summary/custom-entries 200
Req: {"recipientUserIds":[923],"entryType":"Adjustment","description":"ADjj","amount":-100}
Res: {"success":true,"data":{"affectedIds":[6],"count":1},"message":"Custom mortgage commission entries added successfully.","timestamp":"2026-08-10T18:41:06.0496587Z"}
2026-08-10 18:41:06.031 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /ws85.php responded 401 in 0.5070 ms
2026-08-10 18:41:05.851 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /echkm.php responded 401 in 0.4857 ms
2026-08-10 18:41:05.807 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /k.php responded 401 in 0.6394 ms
2026-08-10 18:41:05.727 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //w.php responded 401 in 0.5158 ms
2026-08-10 18:41:05.682 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-trackback.php responded 401 in 0.5995 ms
2026-08-10 18:41:05.628 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /mgrr.php responded 401 in 0.4825 ms
2026-08-10 18:41:05.222 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wps.php responded 401 in 0.5289 ms
2026-08-10 18:41:05.165 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /file.php responded 401 in 0.8638 ms
2026-08-10 18:41:05.061 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wyzer3.php responded 401 in 0.4931 ms
2026-08-10 18:41:04.990 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /explorer/index_.php responded 401 in 0.5050 ms
2026-08-10 18:41:04.793 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /hp2.php responded 401 in 0.4865 ms
2026-08-10 18:41:04.738 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /0x.php responded 401 in 0.5488 ms
2026-08-10 18:41:04.698 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /x.php responded 401 in 0.5386 ms
2026-08-10 18:41:04.633 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /xrp.php responded 401 in 0.6366 ms
2026-08-10 18:41:04.533 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /about/function.php responded 401 in 0.6725 ms
2026-08-10 18:41:04.477 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //aa1.php responded 401 in 0.5747 ms
2026-08-10 18:41:04.305 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //403.php responded 401 in 0.5126 ms
2026-08-10 18:41:04.264 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /shiny.php responded 401 in 0.6487 ms
2026-08-10 18:41:04.201 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //11.php responded 401 in 0.6303 ms
2026-08-10 18:41:04.160 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-content/plugins/admin.php responded 401 in 0.6334 ms
2026-08-10 18:41:04.102 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /css/index.php responded 401 in 0.6046 ms
2026-08-10 18:41:04.032 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /sc.php responded 401 in 0.4604 ms
2026-08-10 18:41:03.991 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /inso.php responded 401 in 0.6973 ms
2026-08-10 18:41:03.950 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /admin-footer.php responded 401 in 0.6108 ms
2026-08-10 18:41:03.902 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /elp.php responded 401 in 0.5063 ms
2026-08-10 18:41:03.862 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /r.php responded 401 in 0.6502 ms
2026-08-10 18:41:03.449 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-admin/options-privacy.php responded 401 in 0.4798 ms
2026-08-10 18:41:03.408 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /25.php responded 401 in 0.5089 ms
2026-08-10 18:41:03.344 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /xwx1.php responded 401 in 0.5372 ms
2026-08-10 18:41:02.931 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /pn.php responded 401 in 0.4560 ms
2026-08-10 18:41:02.890 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-admin/includes/about.php responded 401 in 0.4813 ms
2026-08-10 18:41:02.850 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /panel.php responded 401 in 0.4817 ms
2026-08-10 18:41:02.809 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //byp.php responded 401 in 0.5138 ms
2026-08-10 18:41:02.762 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-content/themes/about.php responded 401 in 0.5198 ms
2026-08-10 18:41:02.721 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /inputs.php responded 401 in 1.1126 ms
2026-08-10 18:41:02.675 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /amp.php responded 401 in 0.5151 ms
2026-08-10 18:41:02.631 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /re.php responded 401 in 0.6670 ms
2026-08-10 18:41:01.386 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-config.php responded 401 in 0.5063 ms
2026-08-10 18:41:01.345 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /stdin.php responded 401 in 0.5396 ms
2026-08-10 18:41:00.185 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //buy.php responded 401 in 0.5331 ms
2026-08-10 18:41:00.129 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp.php responded 401 in 0.5448 ms
2026-08-10 18:41:00.089 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /dragonshell.php responded 401 in 0.5329 ms
2026-08-10 18:41:00.045 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /motu.php responded 401 in 0.5012 ms
2026-08-10 18:40:59.991 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /docs.php responded 401 in 0.5603 ms
2026-08-10 18:40:59.923 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /ioxi-o.php responded 401 in 0.5262 ms
2026-08-10 18:40:59.883 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-access.php responded 401 in 0.5337 ms
2026-08-10 18:40:59.842 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /xxw.php responded 401 in 0.5249 ms
2026-08-10 18:40:59.802 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-admin/setup-config.php responded 401 in 0.5220 ms
2026-08-10 18:40:59.748 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /themes.php responded 401 in 0.5282 ms
2026-08-10 18:40:59.098 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /ssjpxze.php responded 401 in 0.9844 ms
2026-08-10 18:40:59.011 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /erty.php responded 401 in 0.6254 ms
2026-08-10 18:40:58.703 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET //002.php responded 401 in 0.4948 ms
2026-08-10 18:40:58.646 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] HTTP GET /wp-mail.php responded 401 in 0.4929 ms