- Add /planner/variety route with mobile stacked + desktop 2-column layout - Implement VarietyScoreHero: Fraunces score display + progress bar + color-coded description - Implement ScoreBreakdownList: 3 sub-score rows (protein diversity, ingredient overlap, effort balance) - Implement VarietyWarningCards: yellow-tint warning cards derived from API tagRepeats/ingredientOverlaps - Implement EffortBar: proportional colored segments (Easy/Medium/Hard) with ×N labels - Desktop: protein grid (7 columns, repeat highlight with yellow ring) + effort bar in right panel - Client-side sub-score derivation from VarietyScoreResponse (tagged for TODO to move to API) - 26 new tests across 5 components + server load function; 455 tests total, 0 type errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
29 lines
786 B
TypeScript
29 lines
786 B
TypeScript
import type { PageServerLoad } from './$types';
|
|
import { apiClient } from '$lib/server/api';
|
|
import { getWeekStart } from '$lib/planner/week';
|
|
|
|
export const load: PageServerLoad = async ({ fetch, url }) => {
|
|
const weekParam = url.searchParams.get('week');
|
|
const weekStart = weekParam ?? getWeekStart(new Date());
|
|
|
|
const api = apiClient(fetch);
|
|
|
|
const { data: weekPlan, error: weekPlanError } = await api.GET('/v1/week-plans', {
|
|
params: { query: { weekStart } }
|
|
});
|
|
|
|
if (weekPlanError || !weekPlan?.id) {
|
|
return { weekPlan: null, varietyScore: null, weekStart };
|
|
}
|
|
|
|
const { data: varietyScore } = await api.GET('/v1/week-plans/{id}/variety-score', {
|
|
params: { path: { id: weekPlan.id } }
|
|
});
|
|
|
|
return {
|
|
weekPlan,
|
|
varietyScore: varietyScore ?? null,
|
|
weekStart
|
|
};
|
|
};
|