calorie-ai-android/web/src/MealForm.svelte
Daniel fcef0d48db
Some checks failed
Android CI / build (push) Successful in 1m34s
Web CI / test (push) Successful in 58s
Android Release / release-apk (push) Failing after 22s
Add personalized plans with Postgres storage
2026-05-20 23:43:03 +02:00

65 lines
4.2 KiB
Svelte

<script>
import Field from './Field.svelte';
export let mealTypes = [];
export let mealDate;
export let mealTime;
export let mealType;
export let description;
export let measure;
export let selectedImageDataUrl;
export let status;
export let statusError;
export let savingMeal;
export let editingEntryId;
export let estimateDraft;
export let chooseImage;
export let saveMeal;
export let saveMealEdits;
export let cancelEdit;
</script>
<section class="space-y-4">
<div>
<h2 class="text-xl font-bold">{editingEntryId ? 'Edit meal' : 'Log meal'}</h2>
</div>
<form class="card" on:submit|preventDefault={saveMeal}>
<h3 class="card-title">Meal details</h3>
<div class="grid gap-4 p-4 md:grid-cols-3">
<Field label="Date"><input id="mealDate" class="input" type="date" bind:value={mealDate} required></Field>
<Field label="Time of day"><input id="mealTime" class="input" type="time" bind:value={mealTime} required></Field>
<Field label="Meal type"><select id="mealType" class="input" bind:value={mealType} required>{#each mealTypes as type}<option>{type}</option>{/each}</select></Field>
<Field className="md:col-span-3" label="Description"><textarea id="description" class="input min-h-32" bind:value={description} placeholder="Example: grilled salmon, rice, broccoli, berries"></textarea></Field>
<Field label="Portion or measure"><input id="measure" class="input" bind:value={measure} placeholder="Example: one plate, 450g, 2 cups"></Field>
<div class="flex flex-col gap-2">
<span class="text-sm font-semibold text-slate-700">Photo</span>
<div class="flex gap-2">
<label class="btn-secondary flex cursor-pointer items-center gap-2">
<svg viewBox="0 0 20 20" fill="currentColor" width="16" height="16"><path d="M2 6a2 2 0 012-2h.5l1.207-1.207A1 1 0 016.414 2.5h7.172a1 1 0 01.707.293L15.5 4H16a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zm8 1a3 3 0 100 6 3 3 0 000-6z"/></svg>
Choose photo
<input id="image" type="file" accept="image/*" class="sr-only" on:change={chooseImage}>
</label>
</div>
</div>
</div>
{#if selectedImageDataUrl}<img id="preview" class="mx-4 mb-4 max-h-80 w-[calc(100%-2rem)] rounded-2xl object-cover" src={selectedImageDataUrl} alt="Selected meal preview">{/if}
{#if editingEntryId}
<div class="grid gap-3 border-t border-slate-200 p-4 md:grid-cols-4">
<Field className="md:col-span-2" label="Meal name"><input class="input" bind:value={estimateDraft.mealName}></Field>
<Field label="Calories"><input class="input" type="number" min="0" bind:value={estimateDraft.calories}></Field>
<Field label="Protein (g)"><input class="input" type="number" min="0" bind:value={estimateDraft.proteinGrams}></Field>
<Field label="Carbs (g)"><input class="input" type="number" min="0" bind:value={estimateDraft.carbsGrams}></Field>
<Field label="Fat (g)"><input class="input" type="number" min="0" bind:value={estimateDraft.fatGrams}></Field>
<Field label="Fruit servings"><input class="input" type="number" min="0" step="0.1" bind:value={estimateDraft.fruitServings}></Field>
<Field label="Vegetable servings"><input class="input" type="number" min="0" step="0.1" bind:value={estimateDraft.vegetableServings}></Field>
<Field className="md:col-span-2" label="Food groups"><input class="input" bind:value={estimateDraft.foodGroups}></Field>
<Field className="md:col-span-2" label="Notes"><input class="input" bind:value={estimateDraft.notes}></Field>
</div>
{/if}
<div class="flex flex-col gap-3 border-t border-slate-200 p-4 md:flex-row md:items-center">
<button class="btn-primary" type="submit" disabled={savingMeal}>{savingMeal ? 'Saving...' : editingEntryId ? 'Analyze again' : 'Analyze and save'}</button>
{#if editingEntryId}<button class="btn-secondary" type="button" on:click={saveMealEdits}>Save edits</button><button class="btn-secondary" type="button" on:click={cancelEdit}>Cancel</button>{/if}
{#if status}<p id="status" class:text-red-600={statusError} class="text-sm font-semibold text-green-700">{status}</p>{/if}
</div>
</form>
</section>