mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 22:50:51 +00:00
Merge branch 'feat/w-e-score-rings' into release/v1.27.7
This commit is contained in:
commit
093a87e19e
21 files changed
+1230
-211
No files matched your search
@@ -22,8 +22,11 @@ import {
|
||||
DASHBOARD_WIDGET_CATALOGUE_IDS,
|
||||
COMPARISON_BASELINES,
|
||||
CHART_OVERLAY_KEYS,
|
||||
SCORE_RING_IDS,
|
||||
MAX_SELECTED_SCORE_RINGS,
|
||||
type ChartOverlayPrefsMap,
|
||||
type DashboardLayout,
|
||||
type ScoreRingId,
|
||||
} from "@/lib/dashboard-layout";
|
||||
import { Prisma } from "@/generated/prisma/client";
|
||||
import { z } from "zod/v4";
|
||||
@@ -121,6 +124,13 @@ const layoutSchema = z.object({
|
||||
// `chartOverlayPrefs` — a Settings save that doesn't know the field
|
||||
// must not silently reset the user's choice).
|
||||
heroVisible: z.boolean().optional(),
|
||||
// v1.27.7 — hero score rings (max 3, closed id set). Optional with the
|
||||
// same preserve-when-absent contract as `heroVisible`; the resolver
|
||||
// dedupes on read/serialize, `.max()` bounds the wire length.
|
||||
selectedScoreRings: z
|
||||
.array(z.enum(SCORE_RING_IDS))
|
||||
.max(MAX_SELECTED_SCORE_RINGS)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
async function buildDashboardLayout(userId: string): Promise<DashboardLayout> {
|
||||
@@ -262,16 +272,19 @@ export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
// didn't send. The dashboard-layout PUT typically saves widget
|
||||
// visibility / order; chart prefs are PUT through their own route
|
||||
// (`/api/dashboard/chart-overlay-prefs`) and would otherwise be
|
||||
// wiped here on a subsequent layout save. `heroVisible` rides the
|
||||
// same preserve-when-absent contract — an older client's layout
|
||||
// save must not reset the hero toggle. One stored-layout read
|
||||
// covers both fallbacks.
|
||||
// wiped here on a subsequent layout save. `heroVisible` and
|
||||
// `selectedScoreRings` ride the same preserve-when-absent contract —
|
||||
// an older client's layout save must not reset either choice. One
|
||||
// stored-layout read covers all fallbacks.
|
||||
let mergedChartOverlayPrefs: ChartOverlayPrefsMap | undefined = parsed.data
|
||||
.chartOverlayPrefs as ChartOverlayPrefsMap | undefined;
|
||||
let mergedHeroVisible: boolean | undefined = parsed.data.heroVisible;
|
||||
let mergedScoreRings: ScoreRingId[] | undefined =
|
||||
parsed.data.selectedScoreRings;
|
||||
if (
|
||||
mergedChartOverlayPrefs === undefined ||
|
||||
mergedHeroVisible === undefined
|
||||
mergedHeroVisible === undefined ||
|
||||
mergedScoreRings === undefined
|
||||
) {
|
||||
const existing = await prisma.user.findUnique({
|
||||
where: { id: user.id },
|
||||
@@ -286,11 +299,15 @@ export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
if (mergedHeroVisible === undefined) {
|
||||
mergedHeroVisible = existingLayout.heroVisible === true;
|
||||
}
|
||||
if (mergedScoreRings === undefined) {
|
||||
mergedScoreRings = existingLayout.selectedScoreRings;
|
||||
}
|
||||
}
|
||||
const normalized = serializeDashboardLayout({
|
||||
...parsed.data,
|
||||
chartOverlayPrefs: mergedChartOverlayPrefs,
|
||||
heroVisible: mergedHeroVisible,
|
||||
selectedScoreRings: mergedScoreRings,
|
||||
} as DashboardLayout);
|
||||
|
||||
await prisma.user.update({
|
||||
|
||||
Reference in new issue
Block a user