calorie-ai-android/web/public/index.html
Daniel f57c04c989
All checks were successful
Android CI / build (push) Successful in 31s
Web CI / test (push) Successful in 46s
Add web auth and app navigation
2026-05-19 17:59:02 +02:00

162 lines
7 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calorie AI</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="app-frame">
<aside class="sidebar" id="sidebar">
<div class="brand-block">
<span class="brand-mark">CA</span>
<div>
<strong>Calorie AI</strong>
<small>Private food diary</small>
</div>
</div>
<nav class="main-nav" aria-label="Main menu">
<button class="nav-item active" type="button" data-nav="dashboard">Dashboard</button>
<button class="nav-item" type="button" data-nav="log">Log meal</button>
<button class="nav-item" type="button" data-nav="analytics">Analytics</button>
<button class="nav-item" type="button" data-nav="diary">Diary</button>
<button class="nav-item" type="button" data-nav="settings">AI settings</button>
</nav>
<div class="sidebar-footer">
<small>Protected by local web auth</small>
<button id="logout" class="ghost" type="button">Sign out</button>
</div>
</aside>
<div class="content-shell">
<header class="topbar">
<button id="menuToggle" class="menu-toggle" type="button" aria-label="Open menu">Menu</button>
<div>
<p class="eyebrow">AI nutrition cockpit</p>
<h1>Private food tracking with image-backed nutrition estimates</h1>
</div>
<button class="primary-action" type="button" data-nav="log">Add meal</button>
</header>
<main class="content">
<section class="section-page" data-section="dashboard">
<div class="hero-grid">
<article class="hero-card">
<p class="eyebrow">Today</p>
<strong id="todayCalories">0 kcal</strong>
<span id="todayMacroText">P 0g | C 0g | F 0g</span>
<span id="todayProduceText">Fruit 0.0 | Veg 0.0</span>
</article>
<article class="metric-card">
<small>Meals logged</small>
<strong id="mealCountText">0</strong>
<span>Entries saved locally</span>
</article>
<article class="metric-card warm">
<small>7-day average</small>
<strong id="weekAverageText">0 kcal</strong>
<span>Calories per day</span>
</article>
<article class="metric-card cool">
<small>Produce today</small>
<strong id="produceGoalText">0.0 / 5</strong>
<span>Fruit + vegetable servings</span>
</article>
</div>
<section class="panel split-panel">
<div>
<p class="eyebrow">Quick log</p>
<h2>Capture the meal while it is still in front of you.</h2>
<p>Upload a plate photo, add a portion note, and let the vision model hand context to the tasking model for clean nutrition JSON.</p>
<button type="button" data-nav="log">Open meal logger</button>
</div>
<canvas id="macroChart" width="420" height="260"></canvas>
</section>
</section>
<section class="section-page" data-section="log" hidden>
<form id="mealForm" class="panel meal-panel">
<div class="panel-heading">
<p class="eyebrow">Meal intake</p>
<h2>Add meal</h2>
<p>Text-only works, but images give the vision model more evidence for portion and produce estimates.</p>
</div>
<div class="form-grid">
<label class="span-2">
Description
<textarea id="description" rows="5" placeholder="Example: grilled salmon, rice, broccoli, berries"></textarea>
</label>
<label>
Portion or measure
<input id="measure" placeholder="Example: one plate, 450g, 2 cups">
</label>
<label>
Meal image
<input id="image" type="file" accept="image/*">
</label>
</div>
<img id="preview" class="preview" alt="Selected meal preview" hidden>
<div class="form-actions">
<button type="submit">Analyze and save</button>
<p id="status" class="status"></p>
</div>
</form>
</section>
<section class="section-page" data-section="analytics" hidden>
<div class="grid two analytics-grid">
<section class="panel chart-panel wide">
<div class="panel-heading compact">
<p class="eyebrow">Trend</p>
<h2>Calories, last 7 days</h2>
</div>
<canvas id="calorieChart" width="720" height="260"></canvas>
</section>
<section class="panel chart-panel wide">
<div class="panel-heading compact">
<p class="eyebrow">Produce</p>
<h2>Fruit and vegetables</h2>
</div>
<canvas id="produceChart" width="720" height="240"></canvas>
</section>
</div>
</section>
<section class="section-page" data-section="diary" hidden>
<section class="panel">
<div class="row-title">
<div>
<p class="eyebrow">Local history</p>
<h2>Food diary</h2>
</div>
<button id="clearData" class="secondary" type="button">Clear local diary</button>
</div>
<div id="entries" class="entries"></div>
</section>
</section>
<section class="section-page" data-section="settings" hidden>
<section class="panel settings-panel">
<div class="panel-heading">
<p class="eyebrow">Admin</p>
<h2>AI settings</h2>
<p>These settings stay in browser local storage. The API key is sent only to this server-side proxy, not directly to the model endpoint from the browser.</p>
</div>
<div class="form-grid">
<label class="span-2">API base URL<input id="baseUrl" placeholder="https://api.openai.com/v1"></label>
<label class="span-2">API key<input id="apiKey" type="password" placeholder="Optional for local endpoints"></label>
<label>Vision model<input id="visionModel" placeholder="gpt-4o-mini"></label>
<label>Tasking model<input id="taskModel" placeholder="gpt-4o-mini"></label>
</div>
<button id="saveSettings" type="button">Save settings</button>
</section>
</section>
</main>
</div>
</div>
<script src="/app.js"></script>
</body>
</html>