mirror of
https://github.com/we-promise/sure.git
synced 2026-05-30 07:49:01 +00:00
fix(goals): scale up card/widget/chart text, fix chart continuity, ease ring focal point
Five small audit follow-ups bundled because they were each one-line swaps and individually wouldn't earn their own commit. Card text scale (vs Sure house style — budget_category h3 ≈ text-base, budget _actuals_summary value text-xl, account row text-sm subtype): - goal card title text-sm → text-base - goal card balance text-lg → text-xl - goal card pace/footer/subtitle text-[11px] → text-xs - funding row subtype subtitle text-xs → text-sm - funding row "last 30d / last 90d" labels text-[10px] → text-xs Chart label scale (projection chart was an outlier at font-size: 10 while time_series_chart_controller uses 12): - every `font-size: 10` in goal_projection_chart_controller.js → 12 - tooltip cssText font-size: 11 → 12 Color-picker pen toggle on the new-goal avatar was w-6 h-6 (24px circle, ~55% of the lg 44px avatar). Shrink to w-5 h-5 + add a w-3 h-3 class on the inner icon so it scales down with it. Graph continuity bug: the saved-line endpoint and the projection-line start point could disagree by tens of $thousands. Saved came from `Balance::ChartSeriesBuilder` (daily snapshot in `balances`), projection started at `currentAmount = goal.current_balance.to_f` (live `linked_accounts.sum(:balance)`). When the snapshot lagged the live read, the chart showed a vertical gap at the "today" marker. Filter any same-day-or-later points out of the raw saved series, always extend the saved series to `(today, currentAmount)`. Saved line now closes at exactly the projection's start. The recent balance-drop story is still honestly shown (the line dips toward the live value rather than ending at the stale snapshot). Ring card focal-point (RUI audit): the left ring card on goals#show sat at the same `shadow-border-xs` elevation as the projection chart and funding card. "When every card is raised, nothing's primary." Drop the shadow + container background — the ring now reads as a status panel sitting on the page surface, not a content card competing with its neighbours. Paused/archived/celebration/empty right-slot variants keep elevation since they ARE content cards. Deferred: light-mode pink distribution-bar contrast. The fix needs a DS token decision (hairline outline vs darker step on the palette entries); rolling it into a polish PR risks dragging in DS changes unrelated to goals. Logged for a follow-up.
This commit is contained in:
@@ -89,7 +89,14 @@ export default class extends Controller {
|
||||
|
||||
const endDate = target || new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000);
|
||||
|
||||
const rawSavedSeries = (data.saved_series || []).map((p) => ({ date: new Date(p.date), value: p.value }));
|
||||
// Drop any same-day-or-later points from the balance series: we own the
|
||||
// endpoint with `currentAmount` (live `linked_accounts.sum(:balance)`)
|
||||
// so the saved line meets the projection's starting point with no gap.
|
||||
// Without this, the snapshot in `balances` for today could differ from
|
||||
// the live read (sync timing) and the chart showed a vertical jump.
|
||||
const rawSavedSeries = (data.saved_series || [])
|
||||
.map((p) => ({ date: new Date(p.date), value: p.value }))
|
||||
.filter((p) => p.date < today);
|
||||
const firstContribDate = rawSavedSeries[0]?.date;
|
||||
const savedSeries = [];
|
||||
// Only seed a (start, 0) point when start_date predates the first
|
||||
@@ -99,9 +106,10 @@ export default class extends Controller {
|
||||
savedSeries.push({ date: start, value: 0 });
|
||||
}
|
||||
savedSeries.push(...rawSavedSeries);
|
||||
if (savedSeries.length && savedSeries[savedSeries.length - 1].date < today) {
|
||||
savedSeries.push({ date: today, value: currentAmount });
|
||||
}
|
||||
// Always close the saved line at (today, currentAmount) — the projection
|
||||
// line starts here too, guaranteeing visual continuity at the today
|
||||
// marker.
|
||||
savedSeries.push({ date: today, value: currentAmount });
|
||||
|
||||
const projectionEnd = target
|
||||
? Math.max(currentAmount, currentAmount + avgMonthly * Math.max(0, this._monthsBetween(today, target)))
|
||||
@@ -179,7 +187,7 @@ export default class extends Controller {
|
||||
.attr("x", margin.left - 6)
|
||||
.attr("y", y(tickValue) + 3)
|
||||
.attr("text-anchor", "end")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textSecondary)
|
||||
.text(this._fmtMoneyShort(tickValue, data.currency));
|
||||
});
|
||||
@@ -205,7 +213,7 @@ export default class extends Controller {
|
||||
.attr("x", margin.left - 6)
|
||||
.attr("y", targetY + 3)
|
||||
.attr("text-anchor", "end")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textPrimary)
|
||||
.text(`Target · ${this._fmtMoneyShort(targetAmount, data.currency)}`);
|
||||
} else {
|
||||
@@ -215,7 +223,7 @@ export default class extends Controller {
|
||||
.attr("x", margin.left + innerWidth - 4)
|
||||
.attr("y", targetY - 6)
|
||||
.attr("text-anchor", "end")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textPrimary)
|
||||
.text(`Target · ${this._fmtMoney(targetAmount, data.currency)}`);
|
||||
}
|
||||
@@ -308,7 +316,7 @@ export default class extends Controller {
|
||||
.attr("x", x(target) - 8)
|
||||
.attr("y", y(projectionEnd) - 8)
|
||||
.attr("text-anchor", "end")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textSecondary)
|
||||
.text(labelText);
|
||||
}
|
||||
@@ -344,7 +352,7 @@ export default class extends Controller {
|
||||
.append("text")
|
||||
.attr("x", x(today) + 10)
|
||||
.attr("y", y(pendingTop) + 4)
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textSecondary)
|
||||
.text(`+ pending ${this._fmtMoneyShort(pendingPledgeAmount, data.currency)}`);
|
||||
}
|
||||
@@ -375,7 +383,7 @@ export default class extends Controller {
|
||||
.attr("x", x(today))
|
||||
.attr("y", margin.top - 4)
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textSecondary)
|
||||
.text("Today");
|
||||
}
|
||||
@@ -395,7 +403,7 @@ export default class extends Controller {
|
||||
.attr("x", (d) => x(d))
|
||||
.attr("y", height - 8)
|
||||
.attr("text-anchor", "middle")
|
||||
.attr("font-size", 10)
|
||||
.attr("font-size", 12)
|
||||
.attr("fill", textSecondary)
|
||||
.text((d) => tickFmt(d));
|
||||
// De-dupe adjacent equal tick labels (e.g. multiple "May '26" on a
|
||||
@@ -439,7 +447,7 @@ export default class extends Controller {
|
||||
|
||||
if (root.style.position !== "absolute") root.style.position = "relative";
|
||||
const tooltip = document.createElement("div");
|
||||
tooltip.style.cssText = "position:absolute;pointer-events:none;display:none;background:var(--color-gray-900);color:var(--color-white);font-size:11px;line-height:1.35;padding:6px 8px;border-radius:6px;white-space:nowrap;z-index:5;box-shadow:0 2px 8px rgba(0,0,0,0.15);";
|
||||
tooltip.style.cssText = "position:absolute;pointer-events:none;display:none;background:var(--color-gray-900);color:var(--color-white);font-size:12px;line-height:1.35;padding:6px 8px;border-radius:6px;white-space:nowrap;z-index:5;box-shadow:0 2px 8px rgba(0,0,0,0.15);";
|
||||
root.appendChild(tooltip);
|
||||
|
||||
const overlay = svg
|
||||
|
||||
Reference in New Issue
Block a user