@mrck-labs/vanaheim-shared 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -27,14 +27,20 @@ __export(src_exports, {
27
27
  CURRENCIES: () => CURRENCIES,
28
28
  CURRENCY_NAMES: () => CURRENCY_NAMES,
29
29
  CURRENCY_SYMBOLS: () => CURRENCY_SYMBOLS,
30
+ DAY_OPTIONS: () => DAY_OPTIONS,
30
31
  DEFAULT_FOCUS_DURATIONS: () => DEFAULT_FOCUS_DURATIONS,
31
32
  FOCUS_STATUS: () => FOCUS_STATUS,
32
33
  FREQUENCIES: () => FREQUENCIES,
33
34
  FREQUENCY_LABELS: () => FREQUENCY_LABELS,
34
35
  FREQUENCY_MULTIPLIERS: () => FREQUENCY_MULTIPLIERS,
36
+ FREQUENCY_OPTIONS: () => FREQUENCY_OPTIONS,
37
+ HEALTH_FREQUENCY_LABELS: () => HEALTH_FREQUENCY_LABELS,
38
+ HEALTH_FREQUENCY_TYPES: () => HEALTH_FREQUENCY_TYPES,
35
39
  LINEAR_PRIORITIES: () => LINEAR_PRIORITIES,
36
40
  LINEAR_PRIORITY_COLORS: () => LINEAR_PRIORITY_COLORS,
37
41
  LINEAR_PRIORITY_LABELS: () => LINEAR_PRIORITY_LABELS,
42
+ PRESET_COLORS: () => PRESET_COLORS,
43
+ PRESET_ICONS: () => PRESET_ICONS,
38
44
  SETTING_KEYS: () => SETTING_KEYS,
39
45
  activeSessionAtom: () => activeSessionAtom,
40
46
  addDays: () => addDays,
@@ -44,6 +50,7 @@ __export(src_exports, {
44
50
  calculateMonthlyIncome: () => calculateMonthlyIncome,
45
51
  calculateMonthlySavings: () => calculateMonthlySavings,
46
52
  calculateSavingsRate: () => calculateSavingsRate,
53
+ calculateWeeklyProgress: () => calculateWeeklyProgress,
47
54
  elapsedSecondsAtom: () => elapsedSecondsAtom,
48
55
  formatCurrency: () => formatCurrency,
49
56
  formatDate: () => formatDate,
@@ -53,6 +60,7 @@ __export(src_exports, {
53
60
  formatDateString: () => formatDateString,
54
61
  formatDueDate: () => formatDueDate,
55
62
  formatDueDateString: () => formatDueDateString,
63
+ formatDuration: () => formatDuration,
56
64
  formatFullDate: () => formatFullDate,
57
65
  formatMonthYear: () => formatMonthYear,
58
66
  formatRelativeDueDate: () => formatRelativeDueDate,
@@ -71,6 +79,7 @@ __export(src_exports, {
71
79
  generateRandomColor: () => generateRandomColor,
72
80
  generateShortId: () => generateShortId,
73
81
  getEndOfDayISO: () => getEndOfDayISO,
82
+ getFrequencyDescription: () => getFrequencyDescription,
74
83
  getNextWeek: () => getNextWeek,
75
84
  getPreviousWeek: () => getPreviousWeek,
76
85
  getRepoName: () => getRepoName,
@@ -94,11 +103,15 @@ __export(src_exports, {
94
103
  isValidISODate: () => isValidISODate,
95
104
  isValidUrl: () => isValidUrl,
96
105
  normalizeToMidnight: () => normalizeToMidnight,
106
+ parseFrequencyConfig: () => parseFrequencyConfig,
97
107
  parseLocalDate: () => parseLocalDate,
98
108
  progressAtom: () => progressAtom,
99
109
  progressPercentAtom: () => progressPercentAtom,
100
110
  queryKeys: () => queryKeys,
101
111
  remainingSecondsAtom: () => remainingSecondsAtom,
112
+ shouldDoOnDate: () => shouldDoOnDate,
113
+ shouldDoToday: () => shouldDoToday,
114
+ stringifyFrequencyConfig: () => stringifyFrequencyConfig,
102
115
  subtractDays: () => subtractDays,
103
116
  targetSecondsAtom: () => targetSecondsAtom,
104
117
  timerStatusAtom: () => timerStatusAtom,
@@ -152,8 +165,98 @@ var FREQUENCY_MULTIPLIERS = {
152
165
  weekly: 52,
153
166
  "one-time": 1
154
167
  };
168
+ var FREQUENCY_OPTIONS = [
169
+ { value: "monthly", label: "Monthly" },
170
+ { value: "yearly", label: "Yearly" },
171
+ { value: "6-monthly", label: "Every 6 Months" },
172
+ { value: "weekly", label: "Weekly" },
173
+ { value: "one-time", label: "One Time" }
174
+ ];
155
175
  var DEFAULT_FOCUS_DURATIONS = [15, 25, 30, 45, 60, 90];
156
176
  var FOCUS_STATUS = ["active", "completed", "abandoned"];
177
+ var HEALTH_FREQUENCY_TYPES = [
178
+ "daily",
179
+ "specific_days",
180
+ "times_per_week",
181
+ "times_per_month"
182
+ ];
183
+ var HEALTH_FREQUENCY_LABELS = {
184
+ daily: "Daily",
185
+ specific_days: "Specific Days",
186
+ times_per_week: "Times per Week",
187
+ times_per_month: "Times per Month"
188
+ };
189
+ var DAY_OPTIONS = [
190
+ { value: 0, label: "Sun" },
191
+ { value: 1, label: "Mon" },
192
+ { value: 2, label: "Tue" },
193
+ { value: 3, label: "Wed" },
194
+ { value: 4, label: "Thu" },
195
+ { value: 5, label: "Fri" },
196
+ { value: 6, label: "Sat" }
197
+ ];
198
+ var PRESET_COLORS = [
199
+ "#10B981",
200
+ // Emerald
201
+ "#3B82F6",
202
+ // Blue
203
+ "#F59E0B",
204
+ // Amber
205
+ "#EF4444",
206
+ // Red
207
+ "#8B5CF6",
208
+ // Purple
209
+ "#EC4899",
210
+ // Pink
211
+ "#14B8A6",
212
+ // Teal
213
+ "#F97316",
214
+ // Orange
215
+ "#6366F1",
216
+ // Indigo
217
+ "#84CC16"
218
+ // Lime
219
+ ];
220
+ var PRESET_ICONS = [
221
+ "\u{1F4DD}",
222
+ // Writing/Notes
223
+ "\u{1F4BB}",
224
+ // Coding/Tech
225
+ "\u{1F3A8}",
226
+ // Design/Art
227
+ "\u{1F4CA}",
228
+ // Analytics/Data
229
+ "\u{1F527}",
230
+ // Tools/Settings
231
+ "\u{1F4DA}",
232
+ // Learning/Docs
233
+ "\u{1F4A1}",
234
+ // Ideas/Lightbulb
235
+ "\u{1F680}",
236
+ // Launch/Start
237
+ "\u26A1",
238
+ // Fast/Energy
239
+ "\u{1F3AF}",
240
+ // Target/Goal
241
+ "\u{1F48A}",
242
+ // Health/Medicine
243
+ "\u{1F957}",
244
+ // Food/Diet
245
+ "\u{1F4A7}",
246
+ // Water/Hydration
247
+ "\u{1F3C3}",
248
+ // Exercise/Running
249
+ "\u{1F634}",
250
+ // Sleep/Rest
251
+ "\u{1F9D8}",
252
+ // Meditation/Mindfulness
253
+ "\u{1F4AA}",
254
+ // Strength/Fitness
255
+ "\u{1F34E}",
256
+ // Health/Food
257
+ "\u{1F517}"
258
+ // Links/Connections
259
+ ];
157
260
  var LINEAR_PRIORITIES = [0, 1, 2, 3, 4];
158
261
  var LINEAR_PRIORITY_COLORS = {
159
262
  0: "#6b7280",
@@ -222,7 +325,19 @@ function formatTotalTime(seconds) {
222
325
  }
223
326
  return `${mins}m`;
224
327
  }
225
- function formatCurrency(amount, currency, locale = "de-CH") {
328
+ function formatDuration(seconds) {
329
+ const hours = Math.floor(seconds / 3600);
330
+ const minutes = Math.floor(seconds % 3600 / 60);
331
+ const secs = seconds % 60;
332
+ if (hours > 0) {
333
+ return `${hours}h ${minutes}m`;
334
+ } else if (minutes > 0) {
335
+ return `${minutes}m${secs > 0 ? ` ${secs}s` : ""}`;
336
+ } else {
337
+ return `${secs}s`;
338
+ }
339
+ }
340
+ function formatCurrency(amount, currency = "CHF", locale = "de-CH") {
226
341
  return new Intl.NumberFormat(locale, {
227
342
  style: "currency",
228
343
  currency,
@@ -407,6 +522,69 @@ function calculateFocusStats(sessions) {
407
522
  };
408
523
  }
409
524
 
525
+ // src/utils/health.ts
526
+ function parseFrequencyConfig(config) {
527
+ if (!config) return null;
528
+ try {
529
+ return JSON.parse(config);
530
+ } catch {
531
+ return null;
532
+ }
533
+ }
534
+ function stringifyFrequencyConfig(config) {
535
+ if (!config) return null;
536
+ return JSON.stringify(config);
537
+ }
538
+ function getFrequencyDescription(habit) {
539
+ const config = parseFrequencyConfig(habit.frequencyConfig);
540
+ switch (habit.frequencyType) {
541
+ case "daily":
542
+ return "Every day";
543
+ case "specific_days": {
544
+ if (!config?.days) return "Specific days";
545
+ const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
546
+ return config.days.map((d) => dayNames[d]).join(", ");
547
+ }
548
+ case "times_per_week":
549
+ return `${config?.target || 1}x per week`;
550
+ case "times_per_month":
551
+ return `${config?.target || 1}x per month`;
552
+ default:
553
+ return "Unknown";
554
+ }
555
+ }
556
+ function shouldDoOnDate(habit, date) {
557
+ const dayOfWeek = date.getDay();
558
+ switch (habit.frequencyType) {
559
+ case "daily":
560
+ return true;
561
+ case "specific_days": {
562
+ const config = parseFrequencyConfig(habit.frequencyConfig);
563
+ return config?.days?.includes(dayOfWeek) ?? false;
564
+ }
565
+ case "times_per_week":
566
+ case "times_per_month":
567
+ return true;
568
+ default:
569
+ return true;
570
+ }
571
+ }
572
+ function shouldDoToday(habit) {
573
+ return shouldDoOnDate(habit, /* @__PURE__ */ new Date());
574
+ }
575
+ function calculateWeeklyProgress(habit, weekCompletionCount) {
576
+ const config = parseFrequencyConfig(habit.frequencyConfig);
577
+ const target = config?.target ?? 1;
578
+ const completed = weekCompletionCount;
579
+ return {
580
+ habit,
581
+ target,
582
+ completed,
583
+ remaining: Math.max(0, target - completed),
584
+ isComplete: completed >= target
585
+ };
586
+ }
587
+
410
588
  // src/query/index.ts
411
589
  var queryKeys = {
412
590
  // -------------------------------------------------------------------------
@@ -926,14 +1104,20 @@ function formatTimeLocalized(date, format = "short") {
926
1104
  CURRENCIES,
927
1105
  CURRENCY_NAMES,
928
1106
  CURRENCY_SYMBOLS,
1107
+ DAY_OPTIONS,
929
1108
  DEFAULT_FOCUS_DURATIONS,
930
1109
  FOCUS_STATUS,
931
1110
  FREQUENCIES,
932
1111
  FREQUENCY_LABELS,
933
1112
  FREQUENCY_MULTIPLIERS,
1113
+ FREQUENCY_OPTIONS,
1114
+ HEALTH_FREQUENCY_LABELS,
1115
+ HEALTH_FREQUENCY_TYPES,
934
1116
  LINEAR_PRIORITIES,
935
1117
  LINEAR_PRIORITY_COLORS,
936
1118
  LINEAR_PRIORITY_LABELS,
1119
+ PRESET_COLORS,
1120
+ PRESET_ICONS,
937
1121
  SETTING_KEYS,
938
1122
  activeSessionAtom,
939
1123
  addDays,
@@ -943,6 +1127,7 @@ function formatTimeLocalized(date, format = "short") {
943
1127
  calculateMonthlyIncome,
944
1128
  calculateMonthlySavings,
945
1129
  calculateSavingsRate,
1130
+ calculateWeeklyProgress,
946
1131
  elapsedSecondsAtom,
947
1132
  formatCurrency,
948
1133
  formatDate,
@@ -952,6 +1137,7 @@ function formatTimeLocalized(date, format = "short") {
952
1137
  formatDateString,
953
1138
  formatDueDate,
954
1139
  formatDueDateString,
1140
+ formatDuration,
955
1141
  formatFullDate,
956
1142
  formatMonthYear,
957
1143
  formatRelativeDueDate,
@@ -970,6 +1156,7 @@ function formatTimeLocalized(date, format = "short") {
970
1156
  generateRandomColor,
971
1157
  generateShortId,
972
1158
  getEndOfDayISO,
1159
+ getFrequencyDescription,
973
1160
  getNextWeek,
974
1161
  getPreviousWeek,
975
1162
  getRepoName,
@@ -993,11 +1180,15 @@ function formatTimeLocalized(date, format = "short") {
993
1180
  isValidISODate,
994
1181
  isValidUrl,
995
1182
  normalizeToMidnight,
1183
+ parseFrequencyConfig,
996
1184
  parseLocalDate,
997
1185
  progressAtom,
998
1186
  progressPercentAtom,
999
1187
  queryKeys,
1000
1188
  remainingSecondsAtom,
1189
+ shouldDoOnDate,
1190
+ shouldDoToday,
1191
+ stringifyFrequencyConfig,
1001
1192
  subtractDays,
1002
1193
  targetSecondsAtom,
1003
1194
  timerStatusAtom,