feat: complete UI redesign — client creation tabs, footer, home page, CIF & occupation fields

- Client creation: replaced vertical stepper with 3-tab layout (General, KYC & Nominee, Preview)
- All form fields redesigned with appearance="outline" and section grouping
- Preview tab with profile card, info tables, KYC details, family members
- Footer redesigned: security bar, LincShield certifications, regulatory & legal, quick navigation, support & contact, LincPay branding
- Home page redesigned: welcome banner, quick action cards, info row
- Client view header redesigned: ID chips row (Account No, CIF Number, External Id), 4-column details grid
- Added CIF Number column to clients list table
- Added CIF Number display to client view sidebar and personal data tab
- Added occupationCategoryId and occupationId dropdowns to client creation form
- Added occupation fields to client view sidebar, personal data tab, and preview
- Added 51+ missing translation keys to en-US.json
- Toolbar: added Last login chip
- Registered faUserPlus icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-20 19:19:47 +05:30
co-authored by Claude Opus 4.6
parent b3a4cce0cf
commit 7b1f2e8ad7
81 changed files with 8384 additions and 3923 deletions
@@ -0,0 +1,686 @@
/**
* Copyright since 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
$demand: #1d4ed8;
$demand-bg: #eff6ff;
$demand-b: #bfdbfe;
$time: #0f766e;
$time-bg: #f0fdfa;
$time-b: #99f6e4;
$asset: #7c3aed;
$asset-bg: #f5f3ff;
$asset-b: #ddd6fe;
$ink: #0f172a;
$ink2: #334155;
$ink3: #64748b;
$ink4: #94a3b8;
$border: #e2e8f0;
$border2: #cbd5e1;
$surface: #fff;
$surface2: #f8fafc;
$red: #dc2626;
$green: #16a34a;
$amber: #d97706;
$mono: 'IBM Plex Mono', 'Roboto Mono', monospace;
.crr-dialog {
max-height: 85vh;
overflow-y: auto;
padding: 0;
font-size: 14px;
line-height: 1.6;
color: $ink;
}
// ===== Header =====
.dialog-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 24px 28px 20px;
border-bottom: 1px solid $border;
gap: 16px;
flex-wrap: wrap;
position: sticky;
top: 0;
background: $surface;
z-index: 10;
}
.header-badge {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 10px;
font-weight: 600;
padding: 3px 10px;
border-radius: 4px;
background: #fff7ed;
color: #c2410c;
border: 1px solid #fed7aa;
letter-spacing: 0.5px;
margin-bottom: 8px;
font-family: $mono;
}
.dialog-title {
font-size: 20px;
font-weight: 600;
color: $ink;
margin: 0 0 4px;
}
.dialog-sub {
font-size: 12px;
color: $ink3;
font-family: $mono;
letter-spacing: 0.5px;
margin: 0;
}
.header-right {
display: flex;
align-items: flex-start;
gap: 12px;
}
.as-of-box {
font-size: 11px;
color: $ink3;
font-family: $mono;
text-align: right;
background: $surface2;
border: 1px solid $border;
padding: 8px 14px;
border-radius: 8px;
strong {
color: $ink2;
display: block;
font-size: 13px;
margin-bottom: 2px;
}
}
.rbi-circular-btn {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-family: $mono;
font-weight: 500;
padding: 7px 14px;
border-radius: 8px;
background: #fff7ed;
color: #c2410c;
border: 1px solid #fed7aa;
text-decoration: none;
transition: all 0.15s;
white-space: nowrap;
&:hover {
background: #ffedd5;
border-color: #fb923c;
color: #9a3412;
}
fa-icon {
font-size: 10px;
}
}
.close-btn {
width: 32px;
height: 32px;
border-radius: 8px;
background: $surface2;
border: 1px solid $border;
cursor: pointer;
font-size: 16px;
color: $ink3;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.15s;
&:hover {
background: #fef2f2;
color: $red;
border-color: #fecaca;
}
}
// ===== Summary Cards =====
.summary-row {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 14px;
padding: 20px 28px;
}
.summary-card {
background: $surface;
border: 1px solid $border;
border-radius: 12px;
padding: 16px 18px;
position: relative;
overflow: hidden;
transition: box-shadow 0.2s;
&:hover {
box-shadow: 0 4px 16px rgb(0 0 0 / 8%);
}
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
}
}
.sc-demand::before { background: $demand; }
.sc-time::before { background: $time; }
.sc-asset::before { background: $asset; }
.sc-ndtl::before { background: linear-gradient(90deg, $asset, $time, $demand); }
.sc-crr::before { background: $amber; }
.sc-label {
font-size: 10px;
color: $ink3;
font-family: $mono;
letter-spacing: 1px;
text-transform: uppercase;
margin-bottom: 6px;
}
.sc-value {
font-size: 20px;
font-weight: 600;
color: $ink;
font-family: $mono;
}
.cr {
font-size: 11px;
color: $ink3;
font-weight: 400;
margin-left: 3px;
}
.sc-change {
font-size: 11px;
margin-top: 4px;
}
.sc-sub {
font-size: 11px;
color: $ink3;
margin-top: 4px;
}
.up { color: $green; }
.dn { color: $red; }
// ===== Tab Navigation =====
.tab-nav {
display: flex;
gap: 8px;
padding: 0 28px 16px;
border-bottom: 1px solid $border;
}
.tab-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border-radius: 8px;
border: 1px solid $border;
background: $surface;
color: $ink2;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
&:hover {
border-color: $border2;
background: $surface2;
}
&.active {
background: $ink;
color: #fff;
border-color: $ink;
.tab-pill {
background: rgb(255 255 255 / 20%);
color: #fff;
border-color: transparent;
}
}
}
.tab-pill {
font-size: 10px;
font-family: $mono;
font-weight: 600;
padding: 2px 8px;
border-radius: 12px;
letter-spacing: 0.5px;
}
.pill-demand { background: $demand-bg; color: $demand; border: 1px solid $demand-b; }
.pill-time { background: $time-bg; color: $time; border: 1px solid $time-b; }
.pill-asset { background: $asset-bg; color: $asset; border: 1px solid $asset-b; }
.section-desc {
font-size: 12px;
color: $ink3;
font-style: italic;
padding: 12px 28px 8px;
}
// ===== Table =====
.table-wrap {
margin: 0 28px 20px;
background: $surface;
border: 1px solid $border;
border-radius: 12px;
overflow: hidden;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
thead tr {
background: $surface2;
border-bottom: 1px solid $border;
}
thead th {
padding: 10px 14px;
text-align: left;
font-size: 10px;
font-family: $mono;
font-weight: 500;
color: $ink3;
letter-spacing: 1px;
text-transform: uppercase;
white-space: nowrap;
&.right { text-align: right; }
}
tbody tr {
border-bottom: 1px solid $border;
transition: background 0.15s;
&:last-child { border-bottom: none; }
&:hover { background: #f8fafc; }
}
td {
padding: 10px 14px;
color: $ink2;
vertical-align: middle;
&.right { text-align: right; font-family: $mono; }
}
.sl {
color: $ink4;
font-family: $mono;
font-size: 11px;
width: 36px;
}
.mono { font-family: $mono; font-size: 12px; }
.item-name {
font-weight: 500;
color: $ink;
}
.item-sub {
font-size: 11px;
color: $ink3;
margin-top: 2px;
}
.amt {
font-family: $mono;
font-weight: 500;
}
.amt-demand { color: $demand; }
.amt-time { color: $time; }
.amt-asset { color: $asset; }
.status-chip {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 10px;
font-family: $mono;
font-weight: 500;
padding: 2px 8px;
border-radius: 4px;
}
.chip-active { background: #dcfce7; color: #15803d; }
.chip-overdue { background: #fef2f2; color: $red; }
.chip-locked { background: #fefce8; color: #92400e; }
tfoot tr {
background: $surface2;
border-top: 2px solid $border2;
}
tfoot td {
font-weight: 600;
color: $ink;
font-family: $mono;
padding: 12px 14px;
&.right { text-align: right; font-size: 14px; }
}
$slr: #0369a1;
$slr-bg: #f0f9ff;
$slr-b: #bae6fd;
.foot-demand { color: $demand; }
.foot-time { color: $time; }
.foot-asset { color: $asset; }
.foot-slr { color: $slr; }
.deduct-tag { font-size: 10px; color: $asset; font-family: $mono; margin-left: 8px; }
.amt-slr { color: $slr; }
.chip-slr { background: $slr-bg; color: $slr; border: 1px solid $slr-b; }
.pill-slr { background: $slr-bg; color: $slr; border: 1px solid $slr-b; }
.ft-slr {
border-color: $slr-b;
background: $slr-bg;
.formula-term-label, .formula-term-val { color: $slr; }
}
.ft-slr-result {
border-color: #bbf7d0;
background: linear-gradient(135deg, #f0fdf4, #ecfdf5);
.formula-term-label { color: #15803d; }
.formula-term-val { color: $green; font-size: 20px; }
}
.slr-formula::before {
background: linear-gradient(90deg, $slr, $green) !important;
}
// ===== SLR Status Bar =====
.slr-status-bar {
margin: 0 28px 20px;
background: linear-gradient(135deg, #ecfdf5, #f0fdf4);
border: 1px solid #bbf7d0;
border-radius: 10px;
padding: 16px 24px;
display: flex;
align-items: center;
gap: 20px;
flex-wrap: wrap;
}
.slr-status-left { flex: 1; }
.slr-status-title {
font-size: 13px;
font-weight: 600;
color: #14532d;
margin-bottom: 3px;
}
.slr-status-desc {
font-size: 12px;
color: #166534;
}
.slr-status-calcs {
display: flex;
gap: 24px;
}
.slr-calc { text-align: right; }
.slr-calc-label {
font-size: 10px;
color: #166534;
font-family: $mono;
letter-spacing: 1px;
}
.slr-calc-val {
font-size: 15px;
font-weight: 600;
color: #14532d;
font-family: $mono;
&.surplus { color: $green; }
}
// ===== Formula Block =====
.formula-block {
margin: 20px 28px;
background: $surface;
border: 1px solid $border;
border-radius: 14px;
padding: 20px 24px;
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, $demand, $time, $asset);
}
}
.formula-title {
font-size: 11px;
font-family: $mono;
color: $ink3;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 16px;
}
.formula-row {
display: flex;
align-items: center;
gap: 0;
flex-wrap: wrap;
}
.formula-term {
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 16px;
border-radius: 10px;
border: 1px solid $border;
background: $surface2;
min-width: 130px;
flex: 1;
}
.formula-term-label {
font-size: 9.5px;
font-family: $mono;
letter-spacing: 1.5px;
text-transform: uppercase;
margin-bottom: 4px;
}
.formula-term-val {
font-size: 16px;
font-weight: 600;
font-family: $mono;
}
.formula-term-sub {
font-size: 9px;
color: $ink4;
font-family: $mono;
margin-top: 2px;
}
.formula-op {
font-size: 20px;
font-weight: 300;
color: $ink3;
padding: 0 8px;
flex-shrink: 0;
&.minus { color: $red; }
&.equals { color: $ink2; font-weight: 500; }
}
.ft-demand { border-color: $demand-b; background: $demand-bg; .formula-term-label, .formula-term-val { color: $demand; } }
.ft-time { border-color: $time-b; background: $time-bg; .formula-term-label, .formula-term-val { color: $time; } }
.ft-asset { border-color: $asset-b; background: $asset-bg; .formula-term-label, .formula-term-val { color: $asset; } }
.ft-ndtl {
border-color: #a78bfa;
background: linear-gradient(135deg, #f5f3ff, #f0fdfa);
.formula-term-label { color: #6d28d9; }
.formula-term-val { color: $ink; font-size: 18px; }
}
// ===== CRR Bar =====
.crr-bar {
margin: 0 28px 20px;
background: linear-gradient(135deg, #fefce8, #fff7ed);
border: 1px solid #fed7aa;
border-radius: 10px;
padding: 16px 24px;
display: flex;
align-items: center;
gap: 20px;
flex-wrap: wrap;
}
.crr-title {
font-size: 13px;
font-weight: 600;
color: #92400e;
margin-bottom: 3px;
}
.crr-desc {
font-size: 12px;
color: #a16207;
}
.crr-text { flex: 1; }
.crr-calcs {
display: flex;
gap: 24px;
}
.crr-calc { text-align: right; }
.crr-calc-label {
font-size: 10px;
color: #92400e;
font-family: $mono;
letter-spacing: 1px;
}
.crr-calc-val {
font-size: 15px;
font-weight: 600;
color: #78350f;
font-family: $mono;
}
// ===== Footer =====
.dialog-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 28px;
border-top: 1px solid $border;
font-size: 11px;
color: $ink4;
font-family: $mono;
background: $surface2;
flex-wrap: wrap;
gap: 8px;
position: sticky;
bottom: 0;
}
// ===== Responsive =====
/* stylelint-disable-next-line media-feature-range-notation -- Safari compatibility */
@media (max-width: 900px) {
.summary-row {
grid-template-columns: repeat(2, 1fr);
}
.formula-row {
gap: 8px;
}
.formula-term {
min-width: 100px;
}
.crr-calcs,
.slr-status-calcs {
flex-direction: column;
gap: 8px;
}
}
/* stylelint-disable-next-line media-feature-range-notation -- Safari compatibility */
@media (max-width: 600px) {
.summary-row {
grid-template-columns: 1fr;
}
.dialog-header {
padding: 16px 20px;
}
.summary-row,
.table-wrap,
.formula-block,
.crr-bar,
.slr-status-bar {
margin-left: 16px;
margin-right: 16px;
}
.tab-nav {
padding: 0 16px 12px;
flex-wrap: wrap;
}
.section-desc {
padding: 8px 16px;
}
}