162 lines
5.2 KiB
TypeScript
162 lines
5.2 KiB
TypeScript
|
|
import {
|
||
|
|
HELLTH_CLUB_KEY,
|
||
|
|
HELLTH_DATA_KEY,
|
||
|
|
defaultClubProfile,
|
||
|
|
defaultGoals,
|
||
|
|
defaultReminderSettings,
|
||
|
|
seedActivityTemplates,
|
||
|
|
seedFoods,
|
||
|
|
seedPlannedMeals,
|
||
|
|
seedRecipes,
|
||
|
|
seedStores,
|
||
|
|
} from "./constants";
|
||
|
|
import type { ClubData, HellthData } from "./types";
|
||
|
|
|
||
|
|
export function defaultHellthData(): HellthData {
|
||
|
|
return {
|
||
|
|
stores: seedStores,
|
||
|
|
foods: seedFoods,
|
||
|
|
recipes: seedRecipes,
|
||
|
|
recipeRatings: [],
|
||
|
|
plannedMeals: seedPlannedMeals,
|
||
|
|
shoppingItems: [],
|
||
|
|
goals: defaultGoals,
|
||
|
|
coachRecommendations: [],
|
||
|
|
reminders: defaultReminderSettings,
|
||
|
|
activityTemplates: seedActivityTemplates,
|
||
|
|
activityLogs: [],
|
||
|
|
weeklyCaloriePlans: [],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function scopedStorageKey(baseKey: string, userKey?: string | null) {
|
||
|
|
const normalized = userKey?.trim().toLowerCase();
|
||
|
|
return normalized ? `${baseKey}:${normalized}` : baseKey;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function hellthDataStorageKey(userKey?: string | null) {
|
||
|
|
return scopedStorageKey(HELLTH_DATA_KEY, userKey);
|
||
|
|
}
|
||
|
|
|
||
|
|
function migrateGlobalDataToUserKey(userKey: string) {
|
||
|
|
if (typeof window === "undefined") return;
|
||
|
|
const scopedKey = hellthDataStorageKey(userKey);
|
||
|
|
if (window.localStorage.getItem(scopedKey)) return;
|
||
|
|
const globalData = window.localStorage.getItem(HELLTH_DATA_KEY);
|
||
|
|
if (globalData) {
|
||
|
|
window.localStorage.setItem(scopedKey, globalData);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function loadHellthData(userKey?: string | null): HellthData {
|
||
|
|
if (typeof window === "undefined") return defaultHellthData();
|
||
|
|
try {
|
||
|
|
if (userKey) migrateGlobalDataToUserKey(userKey);
|
||
|
|
const raw = window.localStorage.getItem(hellthDataStorageKey(userKey));
|
||
|
|
if (!raw) return defaultHellthData();
|
||
|
|
const parsed = JSON.parse(raw) as Partial<HellthData>;
|
||
|
|
return {
|
||
|
|
stores: parsed.stores?.length ? parsed.stores : seedStores,
|
||
|
|
foods: parsed.foods?.length ? parsed.foods : seedFoods,
|
||
|
|
recipes: parsed.recipes?.length ? parsed.recipes : seedRecipes,
|
||
|
|
recipeRatings: parsed.recipeRatings ?? [],
|
||
|
|
plannedMeals: parsed.plannedMeals ?? seedPlannedMeals,
|
||
|
|
shoppingItems: parsed.shoppingItems ?? [],
|
||
|
|
goals: { ...defaultGoals, ...parsed.goals },
|
||
|
|
healthProfile: parsed.healthProfile,
|
||
|
|
coachRecommendations: parsed.coachRecommendations ?? [],
|
||
|
|
reminders: {
|
||
|
|
...defaultReminderSettings,
|
||
|
|
...parsed.reminders,
|
||
|
|
rules: {
|
||
|
|
water: { ...defaultReminderSettings.rules.water, ...parsed.reminders?.rules?.water },
|
||
|
|
snack: { ...defaultReminderSettings.rules.snack, ...parsed.reminders?.rules?.snack },
|
||
|
|
movement: { ...defaultReminderSettings.rules.movement, ...parsed.reminders?.rules?.movement },
|
||
|
|
},
|
||
|
|
},
|
||
|
|
activityTemplates: parsed.activityTemplates?.length ? parsed.activityTemplates : seedActivityTemplates,
|
||
|
|
activityLogs: parsed.activityLogs ?? [],
|
||
|
|
weeklyCaloriePlans: parsed.weeklyCaloriePlans ?? [],
|
||
|
|
};
|
||
|
|
} catch {
|
||
|
|
return defaultHellthData();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function saveHellthData(data: HellthData, userKey?: string | null) {
|
||
|
|
if (typeof window === "undefined") return;
|
||
|
|
window.localStorage.setItem(hellthDataStorageKey(userKey), JSON.stringify(data));
|
||
|
|
}
|
||
|
|
|
||
|
|
export function hasCompletedHealthProfile(userKey?: string | null) {
|
||
|
|
return Boolean(loadHellthData(userKey).healthProfile?.completedAt);
|
||
|
|
}
|
||
|
|
|
||
|
|
import { todayKey } from "./constants";
|
||
|
|
|
||
|
|
export function defaultClubData(): ClubData {
|
||
|
|
const today = todayKey();
|
||
|
|
return {
|
||
|
|
profile: defaultClubProfile,
|
||
|
|
activities: [
|
||
|
|
{
|
||
|
|
id: "club-sebastian-walk",
|
||
|
|
title: "Eine Stunde spazieren gehen",
|
||
|
|
hostUserKey: "seed-sebastian",
|
||
|
|
hostName: "Sebastian",
|
||
|
|
category: "walk",
|
||
|
|
scope: "state",
|
||
|
|
state: "Bayern",
|
||
|
|
city: "Augsburg",
|
||
|
|
locationLabel: "Bayern",
|
||
|
|
startsAt: `${today}T18:00:00`,
|
||
|
|
durationMinutes: 60,
|
||
|
|
points: 100,
|
||
|
|
note: "Lockerer Spaziergang nach Feierabend. Jeder geht für sich, aber wir starten gemeinsam.",
|
||
|
|
participants: [
|
||
|
|
{
|
||
|
|
userKey: "seed-sebastian",
|
||
|
|
displayName: "Sebastian",
|
||
|
|
joinedAt: `${today}T10:00:00`,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "club-mobility",
|
||
|
|
title: "5 Minuten Dehnübungen",
|
||
|
|
hostUserKey: "seed-hellth",
|
||
|
|
hostName: "Hellth Coach",
|
||
|
|
category: "mobility",
|
||
|
|
scope: "nationwide",
|
||
|
|
state: "Bayern",
|
||
|
|
locationLabel: "Deutschlandweit",
|
||
|
|
startsAt: `${today}T15:00:00`,
|
||
|
|
durationMinutes: 5,
|
||
|
|
points: 20,
|
||
|
|
note: "Kurze Schreibtischpause. Matte nicht nötig.",
|
||
|
|
participants: [],
|
||
|
|
},
|
||
|
|
],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export function loadClubData(): ClubData {
|
||
|
|
if (typeof window === "undefined") return defaultClubData();
|
||
|
|
try {
|
||
|
|
const raw = window.localStorage.getItem(HELLTH_CLUB_KEY);
|
||
|
|
if (!raw) return defaultClubData();
|
||
|
|
const parsed = JSON.parse(raw) as Partial<ClubData>;
|
||
|
|
return {
|
||
|
|
profile: { ...defaultClubProfile, ...parsed.profile },
|
||
|
|
activities: parsed.activities?.length ? parsed.activities : defaultClubData().activities,
|
||
|
|
};
|
||
|
|
} catch {
|
||
|
|
return defaultClubData();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function saveClubData(data: ClubData) {
|
||
|
|
if (typeof window === "undefined") return;
|
||
|
|
window.localStorage.setItem(HELLTH_CLUB_KEY, JSON.stringify(data));
|
||
|
|
}
|