s
This commit is contained in:
@@ -1,61 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ro">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NutriAI Elite v4.0</title>
|
||||
<title>NutriAI Elite - Professional Coaching</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #3b82f6; --bg: #0f172a; --card: #1e293b; --text: #f8fafc;
|
||||
}
|
||||
|
||||
/* Teme de culoare */
|
||||
body.light-theme { --bg: #f1f5f9; --card: #ffffff; --text: #1e293b; }
|
||||
:root { --primary: #3b82f6; --bg: #0f172a; --card: #1e293b; --text: #f8fafc; }
|
||||
body.light-theme { --bg: #f8fafc; --card: #ffffff; --text: #0f172a; }
|
||||
body.blue-theme { --bg: #1e3a8a; --card: #1e40af; --text: #ffffff; }
|
||||
|
||||
body {
|
||||
background-color: var(--bg); color: var(--text);
|
||||
font-family: 'Outfit', sans-serif; transition: 0.4s;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: var(--card); border-right: 1px solid rgba(255,255,255,0.1);
|
||||
min-height: 100vh; padding: 2rem;
|
||||
}
|
||||
|
||||
.glass-input {
|
||||
background: rgba(0,0,0,0.2) !important; border: 1px solid rgba(255,255,255,0.1) !important;
|
||||
color: var(--text) !important; border-radius: 12px; padding: 10px;
|
||||
}
|
||||
|
||||
.kcal-hub {
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
border-radius: 20px; padding: 2rem; text-align: center; box-shadow: 0 10px 25px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.chat-area { height: 60vh; overflow-y: auto; padding: 20px; border-radius: 20px; background: rgba(0,0,0,0.1); }
|
||||
body { background-color: var(--bg); color: var(--text); font-family: 'Outfit', sans-serif; transition: 0.4s; overflow-x: hidden; }
|
||||
.sidebar { background: var(--card); border-right: 1px solid rgba(255,255,255,0.1); min-height: 100vh; padding: 2rem; position: relative; }
|
||||
.glass-input { background: rgba(0,0,0,0.2) !important; border: 1px solid rgba(255,255,255,0.1) !important; color: var(--text) !important; border-radius: 12px; }
|
||||
|
||||
.msg { padding: 1.5rem; border-radius: 1.5rem; margin-bottom: 1.5rem; max-width: 85%; font-size: 1.1rem; line-height: 1.6; }
|
||||
.ai { background: var(--card); border-left: 5px solid #3b82f6; }
|
||||
.user { background: #10b981; margin-left: auto; color: white; font-weight: 500; }
|
||||
.kcal-hub { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); border-radius: 20px; padding: 2rem; text-align: center; box-shadow: 0 10px 25px rgba(37, 99, 235, 0.4); }
|
||||
.chat-area { height: 60vh; overflow-y: auto; padding: 20px; border-radius: 20px; background: rgba(0,0,0,0.2); scroll-behavior: smooth; }
|
||||
|
||||
.msg { padding: 1.2rem; border-radius: 1.2rem; margin-bottom: 1.2rem; max-width: 85%; font-size: 1.05rem; line-height: 1.6; animation: fadeIn 0.3s ease; }
|
||||
.ai { background: var(--card); border-left: 5px solid var(--primary); }
|
||||
.user { background: #10b981; margin-left: auto; color: white; }
|
||||
|
||||
.theme-selector { position: fixed; top: 20px; right: 20px; z-index: 1000; }
|
||||
.input-bar {
|
||||
background: var(--card); border-radius: 50px; padding: 10px 25px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.1);
|
||||
}
|
||||
.top-controls { position: fixed; top: 20px; right: 20px; z-index: 1000; display: flex; gap: 10px; }
|
||||
.input-bar { background: var(--card); border-radius: 50px; padding: 8px 25px; border: 2px solid rgba(255,255,255,0.1); }
|
||||
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="theme-selector dropdown">
|
||||
<button class="btn btn-dark rounded-pill px-4 shadow dropdown-toggle" data-bs-toggle="dropdown">
|
||||
<i class="fas fa-palette me-2"></i>Aspect
|
||||
<div class="top-controls">
|
||||
<div class="btn-group shadow" role="group">
|
||||
<input type="radio" class="btn-check" name="units" id="metric" checked onchange="toggleUnits()">
|
||||
<label class="btn btn-outline-primary rounded-start-pill px-3" for="metric">Metric</label>
|
||||
<input type="radio" class="btn-check" name="units" id="imperial" onchange="toggleUnits()">
|
||||
<label class="btn btn-outline-primary rounded-end-pill px-3" for="imperial">Imperial</label>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-dark rounded-circle shadow p-3" data-bs-toggle="dropdown" style="width: 50px; height: 50px;">
|
||||
<i class="fas fa-palette"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="#" onclick="setTheme('dark')">Dark Mode</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="setTheme('light')">Light Mode</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="setTheme('blue')">Ocean Blue</a></li>
|
||||
@@ -64,73 +50,77 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-3 sidebar">
|
||||
<h3 class="fw-bold mb-4"><i class="fas fa-dna me-2 text-primary"></i>Profil Bio</h3>
|
||||
<div class="col-lg-3 sidebar shadow">
|
||||
<h3 class="fw-bold mb-4 text-primary"><i class="fas fa-bolt me-2"></i>NutriAI Elite</h3>
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-6">
|
||||
<label class="small opacity-75">Vârstă</label>
|
||||
<input type="number" id="varsta" class="form-control glass-input" value="30">
|
||||
<label class="small opacity-75">Age</label>
|
||||
<input type="number" id="age" class="form-control glass-input" value="30">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="small opacity-75">Sex</label>
|
||||
<select id="sex" class="form-select glass-input">
|
||||
<option value="masculin">Masculin</option>
|
||||
<option value="feminin">Feminin</option>
|
||||
<option value="male">Male</option>
|
||||
<option value="female">Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="small opacity-75">Înălțime (cm)</label>
|
||||
<input type="number" id="inaltime" class="form-control glass-input" value="180">
|
||||
<label class="small opacity-75" id="labelHeight">Height (cm)</label>
|
||||
<input type="number" id="height" class="form-control glass-input" value="180">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="small opacity-75">Greutate (kg)</label>
|
||||
<input type="number" id="greutate" class="form-control glass-input" value="85">
|
||||
<label class="small opacity-75" id="labelWeight">Weight (kg)</label>
|
||||
<input type="number" id="weight" class="form-control glass-input" value="85">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="small opacity-75">Nivel Activitate</label>
|
||||
<select id="activitate" class="form-select glass-input">
|
||||
<option value="1.2">Sedentar (Birou)</option>
|
||||
<option value="1.375">Ușor Activ (1-2 zile sport)</option>
|
||||
<option value="1.55">Moderat Activ (3-5 zile sport)</option>
|
||||
<option value="1.725">Foarte Activ (Zilnic/Fizic)</option>
|
||||
<label class="small opacity-75">Activity Level</label>
|
||||
<select id="activity" class="form-select glass-input">
|
||||
<option value="1.2">Sedentary (Office)</option>
|
||||
<option value="1.375">Lightly Active (1-2 days sport)</option>
|
||||
<option value="1.55">Moderately Active (3-5 days sport)</option>
|
||||
<option value="1.725">Very Active (Daily/Physical work)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="fw-bold d-flex justify-content-between">
|
||||
Obiectiv <span><span id="objLabel">0</span> kcal</span>
|
||||
Goal Offset <span><span id="objLabel">0</span> kcal</span>
|
||||
</label>
|
||||
<input type="range" class="form-range" id="kcalAdjust" min="-1000" max="1000" step="50" value="0">
|
||||
</div>
|
||||
|
||||
<div class="kcal-hub shadow-lg">
|
||||
<small class="text-uppercase opacity-75">Ținta ta calorică</small>
|
||||
<h1 class="fw-bold display-5 mb-0" id="totalKcal">2500</h1>
|
||||
<span class="small fw-bold">KCAL / ZI</span>
|
||||
<small class="text-uppercase opacity-75">Daily Target</small>
|
||||
<h1 class="fw-bold display-5 mb-0" id="totalKcal">0</h1>
|
||||
<span class="small fw-bold">CALORIES / DAY</span>
|
||||
</div>
|
||||
|
||||
<button onclick="updateProfile()" class="btn btn-primary w-100 mt-4 py-3 fw-bold rounded-pill">
|
||||
<i class="fas fa-sync-alt me-2"></i>ACTUALIZEAZĂ DATE
|
||||
<button onclick="updateProfile()" class="btn btn-primary w-100 mt-4 py-3 fw-bold rounded-pill shadow">
|
||||
<i class="fas fa-calculator me-2"></i>RECALCULATE
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-9 p-5">
|
||||
<h2 class="fw-bold mb-4">Asistent Personalizat AI</h2>
|
||||
<div id="chatBox" class="chat-area shadow-inner">
|
||||
<div class="msg ai shadow-sm">
|
||||
<h5 class="fw-bold">Sistem Gata.</h5>
|
||||
Salut! Sunt antrenorul tău digital. Am preluat toate detaliile tale biometrice. <br>
|
||||
<strong>Cu ce începem?</strong> Îmi poți cere un meniu saptamanal sau un plan de antrenament.
|
||||
<div class="mb-4">
|
||||
<h2 class="fw-bold mb-1">AI Nutrition Expert</h2>
|
||||
<p class="text-muted">High-precision meal plans powered by Llama 3.3</p>
|
||||
</div>
|
||||
|
||||
<div id="chatBox" class="chat-area shadow-sm">
|
||||
<div class="msg ai">
|
||||
<h5 class="fw-bold">System Online.</h5>
|
||||
Hello! I'm your elite AI nutrition coach. I've analyzed your biometrics. <br>
|
||||
<strong>What should we focus on?</strong> I can generate weekly meal plans, shopping lists, or specialized macros.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-bar d-flex align-items-center mt-4">
|
||||
<div class="input-bar d-flex align-items-center mt-4 shadow-lg">
|
||||
<input type="text" id="userInput" class="form-control bg-transparent border-0 text-white"
|
||||
placeholder="Scrie aici și apasă ENTER..." style="font-size: 1.2rem;">
|
||||
<button onclick="sendToGroq()" class="btn btn-primary rounded-circle p-3 ms-2" style="width: 55px; height: 55px;">
|
||||
<i class="fas fa-paper-plane"></i>
|
||||
placeholder="Message your AI coach (Press ENTER)..." style="font-size: 1.1rem;">
|
||||
<button onclick="sendToGroq()" class="btn btn-primary rounded-circle p-2 ms-2" style="width: 50px; height: 50px;">
|
||||
<i class="fas fa-arrow-up"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,22 +131,47 @@
|
||||
<script>
|
||||
const GROQ_API_KEY = "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";
|
||||
let currentKcal = 0;
|
||||
let isMetric = true;
|
||||
|
||||
function setTheme(theme) {
|
||||
document.body.className = theme + '-theme';
|
||||
function setTheme(theme) { document.body.className = theme + '-theme'; }
|
||||
|
||||
function toggleUnits() {
|
||||
isMetric = document.getElementById('metric').checked;
|
||||
const h = document.getElementById('height');
|
||||
const w = document.getElementById('weight');
|
||||
|
||||
if (isMetric) {
|
||||
h.value = Math.round(h.value * 2.54);
|
||||
w.value = Math.round(w.value / 2.205);
|
||||
document.getElementById('labelHeight').innerText = "Height (cm)";
|
||||
document.getElementById('labelWeight').innerText = "Weight (kg)";
|
||||
} else {
|
||||
h.value = Math.round(h.value / 2.54);
|
||||
w.value = Math.round(w.value * 2.205);
|
||||
document.getElementById('labelHeight').innerText = "Height (in)";
|
||||
document.getElementById('labelWeight').innerText = "Weight (lb)";
|
||||
}
|
||||
updateProfile();
|
||||
}
|
||||
|
||||
document.getElementById('userInput').addEventListener('keypress', (e) => { if(e.key === 'Enter') sendToGroq(); });
|
||||
|
||||
function updateProfile() {
|
||||
const v = parseFloat(document.getElementById('varsta').value);
|
||||
const s = document.getElementById('sex').value;
|
||||
const i = parseFloat(document.getElementById('inaltime').value);
|
||||
const g = parseFloat(document.getElementById('greutate').value);
|
||||
const act = parseFloat(document.getElementById('activitate').value);
|
||||
const age = parseFloat(document.getElementById('age').value);
|
||||
const sex = document.getElementById('sex').value;
|
||||
const act = parseFloat(document.getElementById('activity').value);
|
||||
const adj = parseInt(document.getElementById('kcalAdjust').value);
|
||||
|
||||
let h = parseFloat(document.getElementById('height').value);
|
||||
let w = parseFloat(document.getElementById('weight').value);
|
||||
|
||||
let bmr = (s === 'masculin') ? (10 * g) + (6.25 * i) - (5 * v) + 5 : (10 * g) + (6.25 * i) - (5 * v) - 161;
|
||||
// Convert to metric if needed for BMR formula
|
||||
if (!isMetric) {
|
||||
h = h * 2.54;
|
||||
w = w / 2.205;
|
||||
}
|
||||
|
||||
let bmr = (sex === 'male') ? (10 * w) + (6.25 * h) - (5 * age) + 5 : (10 * w) + (6.25 * h) - (5 * age) - 161;
|
||||
currentKcal = Math.round((bmr * act) + adj);
|
||||
|
||||
document.getElementById('totalKcal').innerText = currentKcal;
|
||||
@@ -171,26 +186,32 @@
|
||||
addMsg('user', text);
|
||||
input.value = "";
|
||||
const loadId = 'load-' + Date.now();
|
||||
addMsg('ai', '<div class="spinner-border spinner-border-sm text-primary"></div> Gândesc...', loadId);
|
||||
addMsg('ai', '<span class="spinner-grow spinner-grow-sm text-primary"></span> Computing...', loadId);
|
||||
|
||||
try {
|
||||
const unitSystem = isMetric ? "Metric (grams, cm, kg)" : "Imperial (ounces, lbs, inches)";
|
||||
const resp = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
||||
method: "POST", headers: { "Authorization": `Bearer ${GROQ_API_KEY}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
model: "llama-3.3-70b-versatile",
|
||||
messages: [{ role: "system", content: `Ești un nutriționist expert. Profil utilizator: ${currentKcal} kcal/zi. Răspunde în ROMÂNĂ cu meniuri și sfaturi saptamanale.` }, { role: "user", content: text }]
|
||||
messages: [{
|
||||
role: "system",
|
||||
content: `Elite Nutritionist AI. Profile: ${currentKcal} kcal. Unit System: ${unitSystem}.
|
||||
Respond strictly in ENGLISH. Use Markdown. Be precise with measurements.`
|
||||
}, { role: "user", content: text }]
|
||||
})
|
||||
});
|
||||
const data = await resp.json();
|
||||
document.getElementById(loadId).innerHTML = `<div style="white-space: pre-wrap">${data.choices[0].message.content}</div>`;
|
||||
} catch(e) { document.getElementById(loadId).innerText = "Eroare de conexiune!"; }
|
||||
} catch(e) { document.getElementById(loadId).innerText = "Connection error!"; }
|
||||
}
|
||||
|
||||
function addMsg(type, content, id = null) {
|
||||
const b = document.getElementById('chatBox');
|
||||
b.innerHTML += `<div class="msg ${type} shadow-sm" ${id ? `id="${id}"` : ''}>${content}</div>`;
|
||||
b.innerHTML += `<div class="msg ${type}" ${id ? `id="${id}"` : ''}>${content}</div>`;
|
||||
b.scrollTop = b.scrollHeight;
|
||||
}
|
||||
|
||||
updateProfile();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user