rohitsar567 Claude Opus 4.7 (1M context) commited on
Commit
e04b308
·
1 Parent(s): 7a8965b

fix(ui): KI-273 — EST. PREMIUM chip always visible (was hidden at <50% profile)

Browse files

User feedback: after KI-269 merged the two premium chips into one, the
chip-CTA disappears at 0% profile completeness. Lost the entry point
to the premium calculator for users exploring before any conversation.

Fix: remove the `completeness_pct >= 50` gate on the chip. Now ALWAYS
renders, with two display states:
- Profile <50% complete (or no sample): label reads "Tap to estimate"
(Hindi: "Tap करें"). Clicking still opens the panel — sliders default
to standard fallbacks (35yo, 10L SI, metro, no PED, 0 copay) which the
user can move manually.
- Profile ≥50% complete with sample: label reads the actual band
"₹X–₹Y/yr" derived from estimate_premium_band.

Tooltip updated to "Tap to estimate / refine premium with sliders" so
it reads sensibly in both states.

Behavior preserved:
- Same onClick (toggles showPremium, closes sibling panels)
- Same amber/orange gradient + RupeeIcon + edit-pencil affordance
- Active ring when panel is open
- KI-270 + KI-272 panel pre-fill from profile still applies on open

Verification:
- npx tsc --noEmit clean
- Logic: hasMeaningfulBand boolean gates the label only; the wrapper
button always renders. Optional chaining + non-null assertion for
premiumBand fields (TypeScript-safe).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. frontend/src/app/page.tsx +19 -13
frontend/src/app/page.tsx CHANGED
@@ -1395,21 +1395,26 @@ export default function Page() {
1395
  )}
1396
  </div>
1397
  </button>
1398
- {/* Predicted-premium BAND chip sits RIGHT NEXT TO the profile
1399
- completeness pill. Shown only once the profile is materially
1400
- populated (≥50%); below that the band would be too wide to
1401
- inform anything. Amber/orange to signal "estimate, not quote". */}
1402
- {profileCompleteness &&
1403
- profileCompleteness.completeness_pct >= 50 &&
1404
- premiumBand &&
1405
- premiumBand.sample_size > 0 && (
 
 
 
 
 
1406
  <button
1407
  type="button"
1408
  onClick={() => { setShowPremium(!showPremium); setShowMarketplace(false); setShowCoverage(false); setShowProfile(false); setShowAdmin(false); }}
1409
  className={`group relative overflow-hidden rounded-xl shadow-sm transition-all hover:shadow-md hover:brightness-110 cursor-pointer ${
1410
  showPremium ? "ring-2 ring-[var(--primary)]" : ""
1411
  }`}
1412
- title={uiLang === "hi" ? "Premium को sliders से refine करने के लिए tap करें" : "Tap to refine premium with sliders"}
1413
  >
1414
  <div className="absolute inset-0 bg-gradient-to-br from-amber-500 via-orange-500 to-amber-600" />
1415
  <div className="relative flex items-stretch text-white">
@@ -1421,11 +1426,11 @@ export default function Page() {
1421
  {uiLang === "hi" ? "अनुमानित premium" : "Est. premium"}
1422
  </div>
1423
  <div className="text-xs font-bold leading-tight whitespace-nowrap">
1424
- {premiumBand.min_inr.toLocaleString("en-IN")}–₹{premiumBand.max_inr.toLocaleString("en-IN")}/yr
 
 
1425
  </div>
1426
  </div>
1427
- {/* Subtle "edit" affordance — pencil-on-slider icon hints
1428
- that tapping the chip opens the slider panel. */}
1429
  <div className="flex items-center justify-center px-2 py-2 bg-white/15 border-l border-white/20 transition-transform group-hover:translate-x-0.5">
1430
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
1431
  <path d="M4 21v-4l11-11 4 4-11 11H4z" />
@@ -1434,7 +1439,8 @@ export default function Page() {
1434
  </div>
1435
  </div>
1436
  </button>
1437
- )}
 
1438
  {/* Admin access — opens the LLM control panel in an embedded view.
1439
  Backend admin API is password-gated (KI-097); enter the admin
1440
  password in the embedded dashboard to unlock the live data. */}
 
1395
  )}
1396
  </div>
1397
  </button>
1398
+ {/* KI-273 Premium chip is now ALWAYS visible (the entry point
1399
+ to the premium calculator). Shows a real band ("₹X–₹Y/yr")
1400
+ when profile is ≥50% complete AND we have a sample; below
1401
+ that it shows a tap-to-start placeholder so the user always
1402
+ has a way to open the calculator regardless of profile state.
1403
+ Amber/orange signals "estimate, not a binding quote". */}
1404
+ {(() => {
1405
+ const hasMeaningfulBand =
1406
+ profileCompleteness &&
1407
+ profileCompleteness.completeness_pct >= 50 &&
1408
+ premiumBand &&
1409
+ premiumBand.sample_size > 0;
1410
+ return (
1411
  <button
1412
  type="button"
1413
  onClick={() => { setShowPremium(!showPremium); setShowMarketplace(false); setShowCoverage(false); setShowProfile(false); setShowAdmin(false); }}
1414
  className={`group relative overflow-hidden rounded-xl shadow-sm transition-all hover:shadow-md hover:brightness-110 cursor-pointer ${
1415
  showPremium ? "ring-2 ring-[var(--primary)]" : ""
1416
  }`}
1417
+ title={uiLang === "hi" ? "Premium को sliders से refine करने के लिए tap करें" : "Tap to estimate / refine premium with sliders"}
1418
  >
1419
  <div className="absolute inset-0 bg-gradient-to-br from-amber-500 via-orange-500 to-amber-600" />
1420
  <div className="relative flex items-stretch text-white">
 
1426
  {uiLang === "hi" ? "अनुमानित premium" : "Est. premium"}
1427
  </div>
1428
  <div className="text-xs font-bold leading-tight whitespace-nowrap">
1429
+ {hasMeaningfulBand
1430
+ ? `₹${premiumBand!.min_inr.toLocaleString("en-IN")}–₹${premiumBand!.max_inr.toLocaleString("en-IN")}/yr`
1431
+ : (uiLang === "hi" ? "Tap करें" : "Tap to estimate")}
1432
  </div>
1433
  </div>
 
 
1434
  <div className="flex items-center justify-center px-2 py-2 bg-white/15 border-l border-white/20 transition-transform group-hover:translate-x-0.5">
1435
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
1436
  <path d="M4 21v-4l11-11 4 4-11 11H4z" />
 
1439
  </div>
1440
  </div>
1441
  </button>
1442
+ );
1443
+ })()}
1444
  {/* Admin access — opens the LLM control panel in an embedded view.
1445
  Backend admin API is password-gated (KI-097); enter the admin
1446
  password in the embedded dashboard to unlock the live data. */}