diff --git a/apps/mana/apps/web/src/lib/app-registry/apps.ts b/apps/mana/apps/web/src/lib/app-registry/apps.ts index 5b057dad6..c7997074e 100644 --- a/apps/mana/apps/web/src/lib/app-registry/apps.ts +++ b/apps/mana/apps/web/src/lib/app-registry/apps.ts @@ -52,6 +52,10 @@ import { PersonSimpleTaiChi, Envelope, Flower, + SunDim, + Pulse, + Robot, + Target, } from '@mana/shared-icons'; // ── Apps with entity capabilities ─────────────────────────── @@ -920,3 +924,45 @@ registerApp({ list: { load: () => import('$lib/modules/sleep/ListView.svelte') }, }, }); + +// ── Companion Brain Pages ───────────────────────────── + +registerApp({ + id: 'myday', + name: 'Mein Tag', + color: '#F59E0B', + icon: SunDim, + views: { + list: { load: () => import('$lib/modules/myday/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'eventstream', + name: 'Events', + color: '#6366F1', + icon: Pulse, + views: { + list: { load: () => import('$lib/modules/eventstream/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'companion', + name: 'Companion', + color: '#8B5CF6', + icon: Robot, + views: { + list: { load: () => import('$lib/modules/companion/ListView.svelte') }, + }, +}); + +registerApp({ + id: 'goals', + name: 'Ziele', + color: '#10B981', + icon: Target, + views: { + list: { load: () => import('$lib/modules/goals/ListView.svelte') }, + }, +}); diff --git a/apps/mana/apps/web/src/lib/modules/companion/ListView.svelte b/apps/mana/apps/web/src/lib/modules/companion/ListView.svelte new file mode 100644 index 000000000..4aba7d1ba --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/companion/ListView.svelte @@ -0,0 +1,55 @@ + + + +
+ {#if activeConversation} + {#key activeConversation.id} + + {/key} + {:else} +
Lade Companion...
+ {/if} +
+ + diff --git a/apps/mana/apps/web/src/lib/modules/eventstream/ListView.svelte b/apps/mana/apps/web/src/lib/modules/eventstream/ListView.svelte new file mode 100644 index 000000000..8aa6fef2c --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/eventstream/ListView.svelte @@ -0,0 +1,174 @@ + + + +
+ {#if events.length === 0} +
+ Noch keine Events. Erstelle Daten in Todo, Kalender, Drink oder Nutriphi. +
+ {:else} + {#each events as event (event.meta.id)} + {@const iconDef = EVENT_ICONS[event.type] ?? { icon: Lightning, color: '#6B7280' }} + {@const IconComp = iconDef.icon} +
+
+ +
+
+ {getLabel(event)} + {event.meta.appId} · {formatTime(event.meta.timestamp)} +
+
+ {/each} + {/if} +
+ + diff --git a/apps/mana/apps/web/src/lib/modules/goals/ListView.svelte b/apps/mana/apps/web/src/lib/modules/goals/ListView.svelte new file mode 100644 index 000000000..fe980d91c --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/goals/ListView.svelte @@ -0,0 +1,243 @@ + + + +
+
+ +
+ + {#if showTemplates} +
+ {#each GOAL_TEMPLATES as tpl} + + {/each} +
+ {/if} + +
+ {#each goals.value.filter((g) => g.status === 'active') as goal (goal.id)} + {@const pct = progressPercent(goal)} +
+
+ + {goal.title} + +
+
+
+
= 100} style:width="{pct}%">
+
+ + {goal.currentValue} / {goal.target.value} + ({periodLabel(goal.target.period)}) + +
+
+ {/each} + + {#each goals.value.filter((g) => g.status === 'paused') as goal (goal.id)} +
+
+ {goal.title} + + +
+ Pausiert +
+ {/each} + + {#if goals.value.length === 0 && !showTemplates} +
Keine Ziele aktiv. Tippe + um ein Ziel zu setzen.
+ {/if} +
+
+ + diff --git a/apps/mana/apps/web/src/lib/modules/myday/ListView.svelte b/apps/mana/apps/web/src/lib/modules/myday/ListView.svelte new file mode 100644 index 000000000..4b4f9af0b --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/myday/ListView.svelte @@ -0,0 +1,230 @@ + + + +
+ +
+
+ + Tasks + {day.value.tasks.completed}/{day.value.tasks.total + day.value.tasks.completed} +
+ {#if day.value.tasks.overdue > 0} +
{day.value.tasks.overdue} ueberfaellig
+ {/if} + {#each day.value.tasks.dueToday.slice(0, 5) as t} +
• {t.title}
+ {/each} + {#if day.value.tasks.dueToday.length === 0 && day.value.tasks.total === 0} +
Keine Tasks heute
+ {/if} +
+ + +
+
+ + Termine + {day.value.events.total} +
+ {#each day.value.events.upcoming.slice(0, 4) as e} +
+ {e.startTime.slice(11, 16)} + {e.title} +
+ {/each} + {#if day.value.events.total === 0} +
Keine Termine
+ {/if} +
+ + +
+
+ + Wasser + {day.value.drinks.water.percent}% +
+
+
+
+
{day.value.drinks.water.ml} / {day.value.drinks.water.goal} ml
+ {#if day.value.drinks.coffee.count > 0} +
{day.value.drinks.coffee.count}x Kaffee
+ {/if} +
+ + +
+
+ + Ernaehrung + {day.value.nutrition.meals} Mahlz. +
+
+
+
+
+ {day.value.nutrition.calories.actual} / {day.value.nutrition.calories.goal} kcal +
+
+ + + {#if streaks.value.length > 0} +
+
+ + Streaks +
+ {#each streaks.value as s} +
+ {s.label} + + {s.currentStreak}d + +
+ {/each} +
+ {/if} +
+ + diff --git a/packages/shared-branding/src/app-icons.ts b/packages/shared-branding/src/app-icons.ts index aa0956936..61da02fa9 100644 --- a/packages/shared-branding/src/app-icons.ts +++ b/packages/shared-branding/src/app-icons.ts @@ -191,6 +191,19 @@ export const APP_ICONS = { // Indigo→purple gradient for the nighttime/rest theme. `` ), + // ── Companion Brain ───────────────────────────────── + myday: svgToDataUrl( + `` + ), + eventstream: svgToDataUrl( + `` + ), + companion: svgToDataUrl( + `` + ), + goals: svgToDataUrl( + `` + ), } as const; export type AppIconId = keyof typeof APP_ICONS; diff --git a/packages/shared-branding/src/mana-apps.ts b/packages/shared-branding/src/mana-apps.ts index 8adb659ec..c0c393692 100644 --- a/packages/shared-branding/src/mana-apps.ts +++ b/packages/shared-branding/src/mana-apps.ts @@ -858,6 +858,65 @@ export const MANA_APPS: ManaApp[] = [ status: 'development', requiredTier: 'guest', }, + + // ── Companion Brain ───────────────────────────────── + + { + id: 'myday', + name: 'Mein Tag', + description: { de: 'Tagesueberblick', en: 'Daily Overview' }, + longDescription: { + de: 'Alle wichtigen Daten auf einen Blick: Tasks, Termine, Wasser, Ernaehrung, Streaks.', + en: 'All key data at a glance: tasks, events, water, nutrition, streaks.', + }, + icon: APP_ICONS.myday ?? '☀️', + color: '#F59E0B', + comingSoon: false, + status: 'development', + requiredTier: 'guest', + }, + { + id: 'eventstream', + name: 'Events', + description: { de: 'Live Event-Stream', en: 'Live Event Stream' }, + longDescription: { + de: 'Echtzeit-Feed aller Aktionen ueber alle Module: Tasks, Drinks, Termine, Mahlzeiten.', + en: 'Real-time feed of all actions across modules: tasks, drinks, events, meals.', + }, + icon: APP_ICONS.eventstream ?? '⚡', + color: '#6366F1', + comingSoon: false, + status: 'development', + requiredTier: 'guest', + }, + { + id: 'companion', + name: 'Companion', + description: { de: 'AI Assistent', en: 'AI Assistant' }, + longDescription: { + de: 'Dein persoenlicher AI-Begleiter. Fragt nach deinem Tag, erstellt Tasks, loggt Getraenke — alles per Chat.', + en: 'Your personal AI companion. Ask about your day, create tasks, log drinks — all via chat.', + }, + icon: APP_ICONS.companion ?? '🤖', + color: '#8B5CF6', + comingSoon: false, + status: 'development', + requiredTier: 'guest', + }, + { + id: 'goals', + name: 'Ziele', + description: { de: 'Ziele & Fortschritt', en: 'Goals & Progress' }, + longDescription: { + de: 'Setze moduluebergreifende Ziele (Wasser, Tasks, Kalorien) und tracke deinen Fortschritt automatisch.', + en: 'Set cross-module goals (water, tasks, calories) and track progress automatically.', + }, + icon: APP_ICONS.goals ?? '🎯', + color: '#10B981', + comingSoon: false, + status: 'development', + requiredTier: 'guest', + }, ]; /**