diff --git a/src/screens/Overview.jsx b/src/screens/Overview.jsx
index b0db725..f680db3 100644
--- a/src/screens/Overview.jsx
+++ b/src/screens/Overview.jsx
@@ -47,6 +47,16 @@ function inr(n) {
return '₹' + Math.round(n).toLocaleString('en-IN')
}
+/* The renewal-exposure buckets, as predicates on days-to-expiry, so the filter
+ and the three counts stay one definition. */
+const EXPO_BUCKETS = {
+ lapsed: (d) => d < 0,
+ week: (d) => d >= 0 && d <= 7,
+ month: (d) => d > 7 && d <= 30,
+}
+const EXPO_LABEL = { lapsed: 'Lapsed', week: 'Within 7 days', month: '8 to 30 days' }
+function expoLabel(k) { return EXPO_LABEL[k] || '' }
+
function expiryTone(d) {
if (d === null) return 'later'
if (d < 0) return 'lapsed'
@@ -63,6 +73,8 @@ export default function Overview() {
// Filing a lead happens over this page, not instead of it — see
// NewLeadDialog. The overview behind it keeps its counts and its poll.
const [adding, setAdding] = useState(false)
+ // Which renewal-exposure bucket the table is narrowed to, or null for all.
+ const [expo, setExpo] = useState(null)
const state = usePortfolio()
const m = useMemo(() => {
@@ -158,6 +170,10 @@ export default function Overview() {
const mine = new Set(visibleStages(roles).map((s) => s.uid))
+ // The exposure table, narrowed to the chosen bucket (or the soonest-due
+ // across all buckets when no filter is set).
+ const expoRows = expo ? m.attention.filter((r) => EXPO_BUCKETS[expo](r._d)) : m.attention
+
if (state.status === 'error') {
const said = describeError(state.error)
return (
@@ -302,26 +318,43 @@ export default function Overview() {
Renewal exposureopen leads by time to expiry
-
-
- {m.exposure.lapsed.length}Lapsed
-
-
- {m.exposure.week.length}Within 7 days
-
-
- {m.exposure.month.length}8 to 30 days
-
+ {/* The three buckets double as the filter: click one to narrow the
+ table to it, click again (or Clear) to show every open renewal. A
+ bucket with nothing in it is not clickable — there is nothing to
+ show. */}
+