This commit is contained in:
Ionel Andrei Cataon
2026-02-18 17:32:07 +02:00
parent add9493e57
commit 1b08c99047

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>NutriAI Elite v24.0</title> <title>NutriAI Elite v26.0</title>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
@@ -22,7 +22,7 @@
.main-wrapper { display: flex; height: 100dvh; flex-direction: row; } .main-wrapper { display: flex; height: 100dvh; flex-direction: row; }
@media (max-width: 991px) { @media (max-width: 991px) {
.main-wrapper { flex-direction: column; overflow-y: auto; height: auto; } .main-wrapper { flex-direction: column; overflow-y: auto; height: auto; }
.sidebar { width: 100% !important; height: auto !important; border-right: none !important; border-bottom: 1px solid rgba(255,255,255,0.1); } .sidebar { width: 100% !important; height: auto !important; border-right: none !important; }
.chat-section { height: 600px !important; } .chat-section { height: 600px !important; }
body { overflow-y: auto; } body { overflow-y: auto; }
} }
@@ -38,7 +38,7 @@
.macro-hub { background: rgba(255,255,255,0.05); border-radius: 20px; padding: 15px; margin-top: 10px; } .macro-hub { background: rgba(255,255,255,0.05); border-radius: 20px; padding: 15px; margin-top: 10px; }
.chat-container { flex-grow: 1; overflow-y: auto; padding: 1.5rem; display: flex; flex-direction: column; } .chat-container { flex-grow: 1; overflow-y: auto; padding: 1.5rem; display: flex; flex-direction: column; }
.msg { padding: 1.2rem; border-radius: 1.2rem; margin-bottom: 1rem; font-size: 1rem; max-width: 90%; color: #fff !important; word-wrap: break-word; } .msg { padding: 1.2rem; border-radius: 1.2rem; margin-bottom: 1rem; font-size: 1rem; max-width: 95%; color: #fff !important; word-wrap: break-word; }
.ai { background: var(--card); border-left: 6px solid var(--primary); align-self: flex-start; } .ai { background: var(--card); border-left: 6px solid var(--primary); align-self: flex-start; }
.user { background: var(--primary); align-self: flex-end; } .user { background: var(--primary); align-self: flex-end; }
@@ -48,8 +48,9 @@
.btn-shop { background: #f59e0b; color: #000; font-weight: 800; border: none; border-radius: 12px; padding: 0 15px; white-space: nowrap; } .btn-shop { background: #f59e0b; color: #000; font-weight: 800; border: none; border-radius: 12px; padding: 0 15px; white-space: nowrap; }
.btn-reset { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border: 1px solid #ef4444; border-radius: 12px; padding: 8px; font-weight: 700; width: 100%; margin-top: 15px; } .btn-reset { background: rgba(239, 68, 68, 0.15); color: #fca5a5; border: 1px solid #ef4444; border-radius: 12px; padding: 8px; font-weight: 700; width: 100%; margin-top: 15px; }
table { width: 100%; display: block; overflow-x: auto; color: #fff; border-collapse: collapse; margin-top: 10px; } table { width: 100%; display: block; overflow-x: auto; color: #fff; border-collapse: collapse; margin: 10px 0; background: rgba(0,0,0,0.2); border-radius: 8px; }
th, td { border: 1px solid rgba(255,255,255,0.2); padding: 8px; text-align: left; } th, td { border: 1px solid rgba(255,255,255,0.1); padding: 8px; text-align: left; min-width: 80px; }
th { background: rgba(255,255,255,0.05); font-weight: 800; color: var(--accent); }
</style> </style>
</head> </head>
<body class="theme-dark"> <body class="theme-dark">
@@ -114,15 +115,15 @@
<div id="chat" class="chat-container"> <div id="chat" class="chat-container">
<div class="msg ai shadow"> <div class="msg ai shadow">
<h5 class="fw-bold text-primary">Intelligence Hub Updated.</h5> <h5 class="fw-bold text-primary">System Online.</h5>
Meal plans now include full macro breakdowns per ingredient. Shopping list recognition is fully active. Meal plans are structured by day and meal, featuring raw ingredient macros and comprehensive totals.
</div> </div>
</div> </div>
<div class="input-area"> <div class="input-area">
<div class="input-group input-group-lg flex-grow-1"> <div class="input-group input-group-lg flex-grow-1">
<input type="text" id="uIn" class="form-control bg-dark text-white border-primary" placeholder="Type and press ENTER..." onkeydown="if(event.key === 'Enter') talk()"> <input type="text" id="uIn" class="form-control bg-dark text-white border-primary" placeholder="Type and press ENTER..." onkeydown="if(event.key === 'Enter') talk()">
<button class="btn btn-primary" onclick="talk()"><button class="btn btn-primary" onclick="talk()"><i class="fas fa-paper-plane"></i></button></button> <button class="btn btn-primary" onclick="talk()"><i class="fas fa-paper-plane"></i></button>
</div> </div>
<button class="btn-shop shadow-sm" onclick="talk('GENERATE_SHOPPING_LIST')"> <button class="btn-shop shadow-sm" onclick="talk('GENERATE_SHOPPING_LIST')">
<i class="fas fa-shopping-basket me-1"></i> SHOPPING LIST <i class="fas fa-shopping-basket me-1"></i> SHOPPING LIST
@@ -178,7 +179,7 @@
document.getElementById('act').selectedIndex = 0; document.getElementById('act').selectedIndex = 0;
document.getElementById('kcal').innerText = "0"; document.getElementById('kcal').innerText = "0";
document.getElementById('h2o').innerText = isMetric ? "0.0L" : "0oz"; document.getElementById('h2o').innerText = isMetric ? "0.0L" : "0oz";
document.getElementById('chat').innerHTML = `<div class="msg ai shadow">System reset.</div>`; document.getElementById('chat').innerHTML = `<div class="msg ai shadow">System reset. Ready for input.</div>`;
conversationHistory = []; conversationHistory = [];
if(mChart) { mChart.data.datasets[0].data = [1,1,1]; mChart.update(); } if(mChart) { mChart.data.datasets[0].data = [1,1,1]; mChart.update(); }
} }
@@ -186,19 +187,22 @@
async function talk(custom) { async function talk(custom) {
const box = document.getElementById('chat'), input = document.getElementById('uIn'); const box = document.getElementById('chat'), input = document.getElementById('uIn');
const isShopReq = custom === 'GENERATE_SHOPPING_LIST'; const isShopReq = custom === 'GENERATE_SHOPPING_LIST';
const text = isShopReq ? "GENERATE_SHOPPING_LIST: Consolidate all raw ingredients from the previously provided meal plan into a list." : (custom || input.value); const text = isShopReq ? "GENERATE_SHOPPING_LIST: Provide a shopping list based on the active meal plan." : (custom || input.value);
if(!text) return; if(!text) return;
if(!custom) { box.innerHTML += `<div class="msg user shadow-sm">${text}</div>`; input.value=""; } if(!custom) { box.innerHTML += `<div class="msg user shadow-sm">${text}</div>`; input.value=""; }
const id = 'ai-'+Date.now(); box.innerHTML += `<div id="${id}" class="msg ai shadow">Processing macros...</div>`; const id = 'ai-'+Date.now(); box.innerHTML += `<div id="${id}" class="msg ai shadow">Analyzing nutrition data...</div>`;
box.scrollTop = box.scrollHeight; box.scrollTop = box.scrollHeight;
const sysPrompt = {role:"system", content: `Expert Dietitian. Target: ${document.getElementById('kcal').innerText} kcal. SYSTEM: ${isMetric ? 'METRIC' : 'IMPERIAL'}. const sysPrompt = {role:"system", content: `Expert Dietitian. Target: ${document.getElementById('kcal').innerText} kcal. SYSTEM: ${isMetric ? 'METRIC' : 'IMPERIAL'}.
CORE RULES: HIERARCHY RULES:
1. Meal Plans MUST include a table with: Ingredient, Weight (DRY/RAW), Calories, P (g), C (g), F (g). 1. Break down by DAY (e.g., ### Monday).
2. DRY/RAW weights are mandatory (e.g., 100g raw oats = 380kcal). 2. Break down each day by MEAL (e.g., #### Breakfast).
3. When user sends "GENERATE_SHOPPING_LIST", refer to the ingredients you just generated in the plan. Do NOT say there is no plan. 3. Every meal MUST have a table: | Ingredient | Weight (RAW) | Calories | P(g) | C(g) | F(g) |.
4. Shopping lists must use ${isMetric ? 'grams/kg' : 'oz/lbs'}.`}; 4. After each meal table, provide "Meal Total: [Kcal] | [P] | [C] | [F]".
5. At the end of each DAY, provide a bold "Daily Total: [Kcal] | [P] | [C] | [F]".
6. MANDATORY: Use DRY/RAW weights only.
7. Refer to previous messages for "GENERATE_SHOPPING_LIST" requests.`};
conversationHistory.push({role: "user", content: text}); conversationHistory.push({role: "user", content: text});
@@ -211,7 +215,7 @@
const aiMsg = d.choices[0].message.content; const aiMsg = d.choices[0].message.content;
conversationHistory.push({role: "assistant", content: aiMsg}); conversationHistory.push({role: "assistant", content: aiMsg});
document.getElementById(id).innerHTML = marked.parse(aiMsg); document.getElementById(id).innerHTML = marked.parse(aiMsg);
} catch(e) { document.getElementById(id).innerText = "Sync error."; } } catch(e) { document.getElementById(id).innerText = "Connection lost."; }
box.scrollTop = box.scrollHeight; box.scrollTop = box.scrollHeight;
} }