8718311876
- Extract App.tsx from 764 lines to ~404 lines - Create reusable components: MedDetailModal, MobileEditModal, ShareDialog, etc. - Add AppContext for global state management - Split pages: DashboardPage, MedicationsPage, SchedulePage, SettingsPage, PlannerPage - Create custom hooks: useAuth, useMedications, useSettings, useDoses, useSchedule - Add utility functions in separate modules - Fix stock status logic (>30 days = green/normal) - Fix reminder threshold calculation (use reminderDaysBefore not lowStockDays) - Fix takenBy validation (send [] instead of null) - Fix datetime format for blister start times (add Z suffix) - Style 'All OK' status as green/bold BREAKING: None - all existing functionality preserved
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
// =============================================================================
|
|
// Local Storage Utilities
|
|
// =============================================================================
|
|
|
|
import { pad2 } from "./formatters";
|
|
|
|
/**
|
|
* Generate a user-specific storage key
|
|
* @param userId - The user ID
|
|
* @param key - The storage key name
|
|
*/
|
|
export function userStorageKey(userId: number | string, key: string): string {
|
|
return `${key}_user_${userId}`;
|
|
}
|
|
|
|
/**
|
|
* Get today's date as ISO string (YYYY-MM-DD)
|
|
*/
|
|
export function todayIso(): string {
|
|
const d = new Date();
|
|
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
|
|
}
|
|
|
|
/**
|
|
* Get a date N days from today as ISO string (YYYY-MM-DD)
|
|
*/
|
|
export function plusDaysIso(days: number): string {
|
|
const d = new Date();
|
|
d.setDate(d.getDate() + days);
|
|
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
|
|
}
|
|
|
|
/**
|
|
* Load collapsed days state from localStorage
|
|
*/
|
|
export function loadCollapsedDaysFromStorage(
|
|
collapsedKey: string,
|
|
expandedKey: string
|
|
): { collapsed: Set<string>; expanded: Set<string> } {
|
|
const collapsed = new Set<string>();
|
|
const expanded = new Set<string>();
|
|
try {
|
|
const storedCollapsed = localStorage.getItem(collapsedKey);
|
|
if (storedCollapsed) {
|
|
const arr = JSON.parse(storedCollapsed);
|
|
if (Array.isArray(arr)) arr.forEach((s: string) => collapsed.add(s));
|
|
}
|
|
const storedExpanded = localStorage.getItem(expandedKey);
|
|
if (storedExpanded) {
|
|
const arr = JSON.parse(storedExpanded);
|
|
if (Array.isArray(arr)) arr.forEach((s: string) => expanded.add(s));
|
|
}
|
|
} catch {
|
|
// Ignore parse errors
|
|
}
|
|
return { collapsed, expanded };
|
|
}
|
|
|
|
/**
|
|
* Save collapsed days state to localStorage
|
|
*/
|
|
export function saveCollapsedDaysToStorage(storageKey: string, state: Record<string, boolean>): void {
|
|
try {
|
|
localStorage.setItem(storageKey, JSON.stringify(state));
|
|
} catch {
|
|
// Ignore storage errors
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get theme from localStorage or default
|
|
*/
|
|
export function getStoredTheme(): "light" | "dark" {
|
|
if (typeof window !== "undefined") {
|
|
return (localStorage.getItem("theme") as "light" | "dark") || "dark";
|
|
}
|
|
return "dark";
|
|
}
|
|
|
|
/**
|
|
* Save theme to localStorage
|
|
*/
|
|
export function saveTheme(theme: "light" | "dark"): void {
|
|
localStorage.setItem("theme", theme);
|
|
}
|