Skip to content

Commit 73d0dd9

Browse files
YousufFFFFYousufFFFF
andauthored
refactor: improve loan product creation UI and localization (#3711)
Co-authored-by: YousufFFFF <ansariyousuf365@gmail.com>
1 parent 1d9c442 commit 73d0dd9

18 files changed

Lines changed: 126 additions & 110 deletions

src/app/products/loan-products/create-loan-product/loan-product-selection.component.html

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,9 @@
88

99
<div class="landing-page">
1010
<section class="landing-page__hero">
11-
<div>
12-
<p class="landing-page__eyebrow">{{ 'labels.text.Products' | translate }}</p>
13-
<h1>{{ 'labels.heading.Loan product creation' | translate }}</h1>
14-
<p class="landing-page__copy">{{ 'labels.text.Select a product below' | translate }}</p>
15-
</div>
16-
17-
<div class="landing-page__badge">
18-
<span>{{ 'labels.text.Version 2' | translate }}</span>
19-
<strong>{{ 'labels.text.Personal and Custom Loan enabled' | translate }}</strong>
20-
</div>
11+
<p class="landing-page__eyebrow">{{ 'labels.text.Products' | translate }}</p>
12+
<h1>{{ 'labels.heading.Loan product creation' | translate }}</h1>
13+
<p class="landing-page__copy">{{ 'labels.text.Select a product below' | translate }}</p>
2114
</section>
2215

2316
<section class="product-grid">
@@ -28,29 +21,27 @@ <h1>{{ 'labels.heading.Loan product creation' | translate }}</h1>
2821
[class.product-card--disabled]="product.disabled"
2922
>
3023
<div class="product-card__header">
31-
<div>
32-
<p class="product-card__eyebrow">{{ 'labels.inputs.Product' | translate }}</p>
33-
<h3>{{ product.name }}</h3>
24+
<div class="product-card__icon">
25+
<mat-icon aria-hidden="true">{{ product.icon }}</mat-icon>
3426
</div>
3527
<span class="product-chip" [class.product-chip--active]="product.active">
36-
{{ (product.active ? 'labels.inputs.Active' : 'labels.inputs.Disabled') | translate }}
28+
{{ (product.active ? 'labels.inputs.Active' : 'labels.text.Upcoming') | translate }}
3729
</span>
3830
</div>
3931

40-
<p class="product-card__description">{{ product.description }}</p>
32+
<h3 class="product-card__title">{{ product.name }}</h3>
33+
<p class="product-card__description">{{ product.description | translate }}</p>
4134

42-
<button
35+
<a
4336
*ngIf="product.active"
44-
mat-raised-button
37+
mat-button
4538
color="primary"
39+
class="product-card__cta"
4640
[routerLink]="['/products', 'loan-products', product.route]"
4741
[queryParams]="{ productType: 'loan' }"
4842
>
49-
{{ 'labels.buttons.Create' | translate }} {{ product.name }}
50-
</button>
51-
<button *ngIf="!product.active" mat-stroked-button disabled>
52-
{{ 'labels.text.Coming soon' | translate }}
53-
</button>
43+
{{ 'labels.buttons.Create' | translate }}
44+
</a>
5445
</mat-card>
5546
</section>
5647
</div>

src/app/products/loan-products/create-loan-product/loan-product-selection.component.scss

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
}
1717

1818
.landing-page__hero {
19-
display: flex;
20-
justify-content: space-between;
21-
gap: 1rem;
22-
align-items: flex-start;
2319
border-radius: 1rem;
2420
background: var(--mat-sys-surface-container, #2e2e2e);
2521
padding: 1.25rem;
@@ -38,20 +34,6 @@
3834
margin: 0.5rem 0 0;
3935
}
4036

41-
.landing-page__badge,
42-
.product-chip {
43-
border-radius: 999px;
44-
padding: 0.35rem 0.75rem;
45-
font-size: 0.8rem;
46-
}
47-
48-
.landing-page__badge {
49-
display: grid;
50-
gap: 0.25rem;
51-
background: rgb(255 255 255 / 8%);
52-
min-width: 12rem;
53-
}
54-
5537
.product-grid {
5638
display: flex;
5739
flex-wrap: wrap;
@@ -84,33 +66,55 @@
8466
.product-card__header {
8567
display: flex;
8668
justify-content: space-between;
69+
align-items: flex-start;
8770
gap: 0.75rem;
8871
}
8972

90-
.product-card__eyebrow {
91-
margin: 0 0 0.25rem;
92-
font-size: 0.75rem;
93-
text-transform: uppercase;
94-
opacity: 0.75;
73+
.product-card__icon {
74+
display: flex;
75+
align-items: center;
76+
justify-content: center;
77+
width: 2.5rem;
78+
height: 2.5rem;
79+
border-radius: 0.75rem;
80+
background: rgb(255 255 255 / 8%);
81+
color: rgb(255 255 255 / 70%);
82+
}
83+
84+
.product-card--active .product-card__icon {
85+
background: rgb(30 136 229 / 18%);
86+
color: var(--mat-sys-primary, #1e88e5);
87+
}
88+
89+
.product-card__title {
90+
margin: 0;
91+
font-size: 1.25rem;
92+
font-weight: 600;
9593
}
9694

9795
.product-card__description {
9896
margin: 0;
9997
line-height: 1.4;
10098
}
10199

100+
.product-card__cta {
101+
justify-self: start;
102+
padding: 0;
103+
min-width: 0;
104+
}
105+
106+
.product-card__cta::after {
107+
content: '';
108+
}
109+
102110
.product-chip {
103111
align-self: flex-start;
112+
border-radius: 999px;
113+
padding: 0.35rem 0.75rem;
114+
font-size: 0.8rem;
104115
background: rgb(255 255 255 / 8%);
105116
}
106117

107118
.product-chip--active {
108119
background: rgb(30 136 229 / 22%);
109120
}
110-
111-
@media (width <= 768px) {
112-
.landing-page__hero {
113-
flex-direction: column;
114-
align-items: stretch;
115-
}
116-
}

src/app/products/loan-products/create-loan-product/loan-product-selection.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
1010
import { RouterLink } from '@angular/router';
1111
import { MatCardModule } from '@angular/material/card';
1212
import { MatButtonModule } from '@angular/material/button';
13+
import { MatIconModule } from '@angular/material/icon';
1314
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
1415
import { PRODUCT_CARDS } from '../wizard/loan-product.config';
1516

@@ -22,6 +23,7 @@ import { PRODUCT_CARDS } from '../wizard/loan-product.config';
2223
...STANDALONE_SHARED_IMPORTS,
2324
MatCardModule,
2425
MatButtonModule,
26+
MatIconModule,
2527
RouterLink
2628
],
2729
changeDetection: ChangeDetectionStrategy.OnPush

src/app/products/loan-products/wizard/loan-product.config.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { LoanProducts } from '../loan-products';
10-
import { buildPayload } from './loan-product.config';
10+
import { buildPayload, PRODUCT_CARDS } from './loan-product.config';
1111

1212
describe('loan-product.config buildPayload', () => {
1313
it('removes unsupported hidden defaults from the personal loan payload', () => {
@@ -432,3 +432,13 @@ describe('loan-product.config buildPayload', () => {
432432
expect(payload.enableAutoRepaymentForDownPayment).toBe(true);
433433
});
434434
});
435+
436+
describe('loan-product.config PRODUCT_CARDS', () => {
437+
it('gives every product card a non-empty icon', () => {
438+
PRODUCT_CARDS.forEach((product) => {
439+
expect(product.icon).toBeDefined();
440+
expect(typeof product.icon).toBe('string');
441+
expect(product.icon.length).toBeGreaterThan(0);
442+
});
443+
});
444+
});

src/app/products/loan-products/wizard/loan-product.config.ts

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export interface ProductCard {
8686
disabled?: boolean;
8787
route?: string;
8888
ctaLabel?: string;
89+
icon: string;
8990
}
9091

9192
export type FieldType = 'text' | 'number' | 'select' | 'checkbox' | 'textarea' | 'date';
@@ -123,119 +124,140 @@ export interface FormStep {
123124
export const PRODUCT_CARDS: ProductCard[] = [
124125
{
125126
name: 'Custom / Advanced',
126-
description: 'Flexible configuration with advanced controls for tranche and arrears behavior.',
127+
// Fully qualified translation key (rather than literal display text like the other cards below) so
128+
// this specific description can be localized; the template applies `| translate` to every card's
129+
// `description`, and untranslated literal text safely falls through the missing-translation handler
130+
// unchanged, so this doesn't require touching the other, not-yet-translated cards.
131+
description: 'labels.text.Complete control over every aspect of product behavior',
127132
active: true,
128133
disabled: false,
129134
route: 'custom-advanced',
130-
ctaLabel: 'Create Custom / Advanced'
135+
ctaLabel: 'Create Custom / Advanced',
136+
icon: 'tune'
131137
},
132138
{
133139
name: 'Personal Loan',
134140
description:
135141
'Unsecured funding for personal needs like travel, medical expenses, or weddings, with flexible tenure and minimal documentation.',
136142
active: true,
137143
disabled: false,
138-
route: 'personal-loan'
144+
route: 'personal-loan',
145+
icon: 'account_balance_wallet'
139146
},
140147
{
141148
name: 'Two Wheeler Loan',
142149
description: 'Finance for new or used two-wheelers with quick approval and flexible down payment options.',
143150
active: false,
144-
disabled: true
151+
disabled: true,
152+
icon: 'pedal_bike'
145153
},
146154
{
147155
name: 'JLG Loan',
148156
description:
149157
'Group-backed microloans for individuals in a Joint Liability Group, typically for income-generating activities.',
150158
active: false,
151-
disabled: true
159+
disabled: true,
160+
icon: 'group'
152161
},
153162
{
154163
name: 'Education Loan',
155164
description:
156165
'Funding for tuition and related expenses for domestic or international studies, with repayment options aligned to course duration.',
157166
active: false,
158-
disabled: true
167+
disabled: true,
168+
icon: 'school'
159169
},
160170
{
161171
name: 'Home Loan',
162172
description: 'Long-tenure financing to purchase, construct, or renovate a residential property.',
163173
active: false,
164-
disabled: true
174+
disabled: true,
175+
icon: 'home'
165176
},
166177
{
167178
name: 'Mortgage Loan (LAP)',
168179
description: 'Loan against property where an existing residential or commercial asset is pledged as collateral.',
169180
active: false,
170-
disabled: true
181+
disabled: true,
182+
icon: 'home_work'
171183
},
172184
{
173185
name: 'Agri Loan',
174186
description:
175187
'Credit for farming-related needs such as crop production, equipment, or land development, often tied to agricultural cycles.',
176188
active: false,
177-
disabled: true
189+
disabled: true,
190+
icon: 'agriculture'
178191
},
179192
{
180193
name: 'Auto Loan',
181194
description: 'Financing for new or used car purchases with structured EMIs over a chosen tenure.',
182195
active: false,
183-
disabled: true
196+
disabled: true,
197+
icon: 'directions_car'
184198
},
185199
{
186200
name: 'Gold Loan',
187201
description:
188202
'Quick secured loan against pledged gold ornaments or coins, with fast disbursal and minimal paperwork.',
189203
active: false,
190-
disabled: true
204+
disabled: true,
205+
icon: 'diamond'
191206
},
192207
{
193208
name: 'Consumer Durable Loan',
194209
description:
195210
'Point-of-sale financing for electronics, appliances, and other durable goods, often with zero-cost EMI options.',
196211
active: false,
197-
disabled: true
212+
disabled: true,
213+
icon: 'devices'
198214
},
199215
{
200216
name: 'Loan vs Securities / FD',
201217
description:
202218
'Credit extended against shares, mutual funds, or fixed deposits without liquidating the underlying investment.',
203219
active: false,
204-
disabled: true
220+
disabled: true,
221+
icon: 'account_balance'
205222
},
206223
{
207224
name: 'Credit Card EMI',
208225
description: 'Converts card spends or available credit limit into structured EMIs.',
209226
active: false,
210-
disabled: true
227+
disabled: true,
228+
icon: 'credit_card'
211229
},
212230
{
213231
name: 'BNPL',
214232
description:
215233
'Buy now, pay later financing for short-term, often interest-free purchases, settled in fixed installments.',
216234
active: false,
217-
disabled: true
235+
disabled: true,
236+
icon: 'shopping_cart'
218237
},
219238
{
220239
name: 'Invoice Discounting',
221240
description:
222241
'Short-term financing against unpaid invoices to improve business cash flow before customer payment is due.',
223242
active: false,
224-
disabled: true
243+
disabled: true,
244+
icon: 'receipt_long'
225245
},
226246
{
227247
name: 'Merchant Cash Advance',
228248
description:
229249
'Working capital advanced against future card or digital sales, repaid as a percentage of daily transactions.',
230250
active: false,
231-
disabled: true
251+
disabled: true,
252+
icon: 'storefront'
232253
},
233254
{
234255
name: 'Line of Credit',
235256
description:
236257
'A revolving credit limit that can be drawn, repaid, and reused as needed, with interest charged only on the amount utilized.',
237258
active: false,
238-
disabled: true
259+
disabled: true,
260+
icon: 'credit_score'
239261
}
240262
];
241263

src/assets/translations/cs-CS.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3994,9 +3994,8 @@
39943994
"Tellers": "Věštci",
39953995
"Template defaults are preloaded": "Výchozí hodnoty šablony jsou předvyplněny",
39963996
"Select a product below": "Vyberte produkt níže",
3997-
"Version 2": "Verze 2",
3998-
"Personal and Custom Loan enabled": "Osobní a vlastní úvěr povolen",
3999-
"Coming soon": "Již brzy",
3997+
"Upcoming": "Nadcházející",
3998+
"Complete control over every aspect of product behavior": "Úplná kontrola nad každým aspektem chování produktu — od moratoria a subvencí až po struktury s více tranšemi, pravidla rozdělování plateb a mnohem více.",
40003999
"Template I am trying to use": "Toto je šablona, ​​kterou se snažím použít. Je to v pořádku?",
40014000
"Templates": "Šablony",
40024001
"Tenant": "Nájemce",

src/assets/translations/de-DE.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,9 +3995,8 @@
39953995
"Tellers": "Kassierer",
39963996
"Template defaults are preloaded": "Template defaults are preloaded",
39973997
"Select a product below": "Select a product below",
3998-
"Version 2": "Version 2",
3999-
"Personal and Custom Loan enabled": "Personal and Custom Loan enabled",
4000-
"Coming soon": "Coming soon",
3998+
"Upcoming": "Demnächst",
3999+
"Complete control over every aspect of product behavior": "Vollständige Kontrolle über jeden Aspekt des Produktverhaltens — von Moratorium und Subvention bis hin zu Multi-Tranchen-Strukturen, Aufteilungsregeln und mehr.",
40014000
"Template I am trying to use": "Dies ist die Vorlage, die ich verwenden möchte. Ist das gut.",
40024001
"Templates": "Vorlagen",
40034002
"Tenant": "Mandant",

0 commit comments

Comments
 (0)