diff --git a/apps/mana/apps/web/src/routes/(app)/nutriphi/+page.svelte b/apps/mana/apps/web/src/routes/(app)/nutriphi/+page.svelte index 9c56c5061..ad2a3f327 100644 --- a/apps/mana/apps/web/src/routes/(app)/nutriphi/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/nutriphi/+page.svelte @@ -196,13 +196,14 @@ {:else}
{#each todaysMeals as meal (meal.id)} -
- {#if meal.photoUrl} + {#if meal.photoThumbnailUrl || meal.photoUrl} {meal.description} {/if}
-
+ {/each}
{/if} diff --git a/apps/mana/apps/web/src/routes/(app)/nutriphi/[id]/+page.svelte b/apps/mana/apps/web/src/routes/(app)/nutriphi/[id]/+page.svelte new file mode 100644 index 000000000..0c8572541 --- /dev/null +++ b/apps/mana/apps/web/src/routes/(app)/nutriphi/[id]/+page.svelte @@ -0,0 +1,518 @@ + + + + {meal?.description ?? 'Mahlzeit'} - NutriPhi - Mana + + +
+ + + Zurueck + + + {#if !meal} +
+

Mahlzeit nicht gefunden.

+
+ {:else} + {#if error} +
+ {error} +
+ {/if} + + + {#if meal.photoUrl} + + {/if} + + +
+
+ + {getMealTypeLabel(meal.mealType)} + + + {formatDateTime(meal.createdAt)} + + {#if meal.inputType === 'photo'} + 📷 + {/if} + {#if meal.confidence > 0 && meal.confidence < 1} + + KI {Math.round(meal.confidence * 100)}% + + {/if} +
+ + {#if !editing} +

{meal.description}

+ {#if meal.nutrition} +
+
+
+
+ Kalorien +
+

+ {meal.nutrition.calories} + kcal +

+
+
+
+
+ Protein +
+

+ {meal.nutrition.protein}g +

+
+
+
+
+ Kohlenhydrate +
+

+ {meal.nutrition.carbohydrates}g +

+
+
+
+
+ Fett +
+

+ {meal.nutrition.fat}g +

+
+
+
+
Ballaststoffe: {meal.nutrition.fiber}g
+
Zucker: {meal.nutrition.sugar}g
+
+ {/if} + +
+ + {#if meal.inputType === 'photo' && meal.photoUrl} + + {/if} + {#if !confirmDelete} + + {:else} +
+ Sicher? + + +
+ {/if} +
+ {:else} + +
+
+ +
+ {#each mealTypes as type} + + {/each} +
+
+ +
+ + +
+ +
+

Naehrwerte

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ {/if} +
+ + + {#if !editing && meal.foods && meal.foods.length > 0} +
+

+ Erkannte Bestandteile +

+ +
+ {/if} + {/if} +
+ + +{#if lightboxOpen && meal?.photoUrl} + +{/if} diff --git a/apps/mana/apps/web/src/routes/(app)/nutriphi/add/+page.svelte b/apps/mana/apps/web/src/routes/(app)/nutriphi/add/+page.svelte index f43b8d138..836b2c6fe 100644 --- a/apps/mana/apps/web/src/routes/(app)/nutriphi/add/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/nutriphi/add/+page.svelte @@ -8,7 +8,7 @@ textAnalysisMutations, } from '$lib/modules/nutriphi/mutations'; import { MEAL_TYPE_LABELS, suggestMealType } from '$lib/modules/nutriphi/constants'; - import type { MealType, NutritionData } from '$lib/modules/nutriphi/types'; + import type { AnalyzedFood, MealType, NutritionData } from '$lib/modules/nutriphi/types'; import { ArrowLeft } from '@mana/shared-icons'; const allFavorites = useAllFavorites(); @@ -32,7 +32,9 @@ let photoPreviewUrl = $state(null); let photoMediaId = $state(null); let photoUploadedUrl = $state(null); + let photoUploadedThumbnailUrl = $state(null); let aiConfidence = $state(null); + let aiFoods = $state(null); let analyzing = $state(false); let analyzed = $state(false); @@ -67,7 +69,9 @@ photoPreviewUrl = null; photoMediaId = null; photoUploadedUrl = null; + photoUploadedThumbnailUrl = null; aiConfidence = null; + aiFoods = null; analyzed = false; } @@ -93,7 +97,9 @@ photoPreviewUrl = URL.createObjectURL(file); photoMediaId = null; photoUploadedUrl = null; + photoUploadedThumbnailUrl = null; aiConfidence = null; + aiFoods = null; analyzed = false; error = ''; } @@ -106,6 +112,7 @@ const { upload, analysis } = await photoMutations.uploadAndAnalyze(photoFile); photoMediaId = upload.mediaId; photoUploadedUrl = upload.publicUrl; + photoUploadedThumbnailUrl = upload.thumbnailUrl; // Prefill the same fields the text mode uses, so the user can review/edit. if (analysis.description) description = analysis.description; @@ -118,6 +125,7 @@ sugar = analysis.totalNutrition.sugar ?? null; } aiConfidence = analysis.confidence ?? null; + aiFoods = analysis.foods?.length ? analysis.foods : null; analyzed = true; } catch (err) { console.error('photo analysis failed:', err); @@ -189,7 +197,9 @@ nutrition, photoMediaId, photoUrl: photoUploadedUrl, + photoThumbnailUrl: photoUploadedThumbnailUrl, confidence: aiConfidence ?? 0.8, + foods: aiFoods, }); } else { await mealMutations.create({ @@ -348,6 +358,33 @@ {/if} {/if} + + {#if analyzed && aiFoods && aiFoods.length > 0} +
+

+ Erkannte Bestandteile +

+
    + {#each aiFoods as food} +
  • + + {food.name} + {#if food.quantity} + · {food.quantity} + {/if} + + {#if food.calories != null} + + {food.calories} kcal + + {/if} +
  • + {/each} +
+
+ {/if} {/if} diff --git a/apps/mana/apps/web/src/routes/(app)/nutriphi/history/+page.svelte b/apps/mana/apps/web/src/routes/(app)/nutriphi/history/+page.svelte index 328c9853f..d2aad7914 100644 --- a/apps/mana/apps/web/src/routes/(app)/nutriphi/history/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/nutriphi/history/+page.svelte @@ -164,38 +164,42 @@