82 lines
3.2 KiB
HTML
82 lines
3.2 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>
|
|
<main class="shell">
|
|
<section class="hero">
|
|
<div>
|
|
<p class="eyebrow">AI food diary</p>
|
|
<h1>Calorie AI</h1>
|
|
<p>Upload a meal image, add a portion note, and track calories, macros, fruit, and vegetables per day.</p>
|
|
</div>
|
|
<div class="today-card">
|
|
<span>Today</span>
|
|
<strong id="todayCalories">0 kcal</strong>
|
|
<small id="todayMacroText">P 0g | C 0g | F 0g</small>
|
|
<small id="todayProduceText">Fruit 0.0 | Veg 0.0</small>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="grid two">
|
|
<form id="mealForm" class="panel">
|
|
<h2>Add meal</h2>
|
|
<label>
|
|
Description
|
|
<textarea id="description" rows="4" 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>
|
|
<img id="preview" class="preview" alt="Selected meal preview" hidden>
|
|
<button type="submit">Analyze and save</button>
|
|
<p id="status" class="status"></p>
|
|
</form>
|
|
|
|
<section class="panel settings">
|
|
<h2>Admin AI settings</h2>
|
|
<label>API base URL<input id="baseUrl" placeholder="https://api.openai.com/v1"></label>
|
|
<label>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>
|
|
<button id="saveSettings" type="button">Save settings</button>
|
|
<p class="muted">The vision model estimates food and calories from images. The tasking model normalizes the final nutrition JSON. They can be the same model.</p>
|
|
</section>
|
|
</section>
|
|
|
|
<section class="grid three">
|
|
<section class="panel chart-panel">
|
|
<h2>Macros today</h2>
|
|
<canvas id="macroChart" width="420" height="260"></canvas>
|
|
</section>
|
|
<section class="panel chart-panel wide">
|
|
<h2>Calories, last 7 days</h2>
|
|
<canvas id="calorieChart" width="720" height="260"></canvas>
|
|
</section>
|
|
<section class="panel chart-panel wide">
|
|
<h2>Fruit and vegetables</h2>
|
|
<canvas id="produceChart" width="720" height="240"></canvas>
|
|
</section>
|
|
</section>
|
|
|
|
<section class="panel">
|
|
<div class="row-title">
|
|
<h2>Food diary</h2>
|
|
<button id="clearData" class="secondary" type="button">Clear local diary</button>
|
|
</div>
|
|
<div id="entries" class="entries"></div>
|
|
</section>
|
|
</main>
|
|
<script src="/app.js"></script>
|
|
</body>
|
|
</html>
|