-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagent.js
More file actions
245 lines (208 loc) · 11.4 KB
/
Copy pathagent.js
File metadata and controls
245 lines (208 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Element References
const emotionView = document.getElementById('emotion-view');
const loadingView = document.getElementById('loading-view');
const menuView = document.getElementById('menu-view');
const emotionBtns = document.querySelectorAll('.emotion-btn');
const root = document.documentElement;
// Elements for dynamic content injection
const loadingText = document.getElementById('loading-text');
const menuReasoningText = document.getElementById('menu-reasoning');
const mealsContainer = document.getElementById('meals-container');
const backBtn = document.getElementById('back-btn');
const aiToggle = document.getElementById('ai-mode-toggle');
const aiKeyContainer = document.getElementById('api-key-container');
const apiKeyInput = document.getElementById('api-key-input');
// User context inputs
const dietInput = document.getElementById('diet-input');
const sleepInput = document.getElementById('sleep-input');
const waterInput = document.getElementById('water-input');
// --- Simulated AI Database (Nutritional Logic Mapped to Emotions) ---
const emotionalDatabase = {
stress: {
reasoning: "Pentru a reduce nivelul de cortizol (hormonul stresului), am selectat alimente bogate în magneziu, vitamina C și acizi grași Omega-3, care calmează sistemul nervos.",
meals: [
{ type: "Mic dejun", name: "Ovăz Calmant cu Fructe de Pădure", desc: "Fulgi de ovăz (complex de carbohidrați pentru serotonină) cu afine (vitamina C) și nuci (magneziu).", icon: "🥣" },
{ type: "Prânz", name: "Somon Zen cu Quinoa", desc: "Somon la grătar (bogat în Omega-3) servit pe un pat de quinoa și sparanghel.", icon: "🐟" },
{ type: "Gustare", name: "Ceai de Mușețel și Migdale", desc: "Ceaiul relaxează mușchii, iar migdalele sunt pline de vitamine B anti-stres.", icon: "☕" },
{ type: "Cină", name: "Supă Cremă de Broccoli", desc: "Ușoară, caldă și plină de nutrienți foliari pentru relaxare înainte de culcare.", icon: "🍲" }
]
},
sadness: {
reasoning: "Pentru a-ți ridica moralul, am creat un meniu 'comfort food' reinventat: hrănitor, cald, care stimulează producția de serotonină (hormonul fericirii) fără a te îngreuna.",
meals: [
{ type: "Mic dejun", name: "Clătite Integrale cu Banane", desc: "Bananele conțin triptofan, precursorul serotoninei, completate cu un strop de miere.", icon: "🥞" },
{ type: "Prânz", name: "Mac & Cheese Sănătos din Conopidă", desc: "Un gust reconfortant (comfort food) obținut ușor, folosind sos de brânză fin și conopidă.", icon: "🧀" },
{ type: "Gustare", name: "Ciocolată Neagră (70%+)", desc: "Eliberează endorfine instant și oferă un mic boost de magie.", icon: "🍫" },
{ type: "Cină", name: "Pui la Cuptor cu Cartofi Dulci", desc: "Cartofii dulci sunt carbohidrați complecși excelenți pentru starea de bine.", icon: "🍗" }
]
},
tired: {
reasoning: "Ai nevoie de energie constantă! Am eliminat zahărul rapid (care dă crash) și am adus carbohidrați constanți, proteine ușoare și multă hidratare.",
meals: [
{ type: "Mic dejun", name: "Smoothie Verde Puternic", desc: "Spanac (fier), mere (energie verde), matcha (cofeină cu eliberare lentă) și chia.", icon: "🥤" },
{ type: "Prânz", name: "Salată Vibrantă cu Năut", desc: "O bombă de proteine și fibre vegetale care nu îți va provoca somnolența de după masă.", icon: "🥗" },
{ type: "Gustare", name: "Măr Tăiat cu Unt de Arahide", desc: "Combinația perfectă între carbohidrați (măr) și grăsimi sănătoase/proteine.", icon: "🍏" },
{ type: "Cină", name: "Curry Vegetarian de Linte", desc: "Nutritiv, ușor de digerat și perfect pentru a-ți reface depozitele de energie peste noapte.", icon: "🥘" }
]
},
angry: {
reasoning: "Pentru a reduce 'focul' intern, am ales un meniu răcoros, ușor, cu alimente care hidratează intens și stabilizează nivelul de zahăr din sânge.",
meals: [
{ type: "Mic dejun", name: "Iaurt Grecesc cu Mentă și Castravete", desc: "Un mic dejun proaspăt, foarte proteic și incredibil de răcoritor.", icon: "🍧" },
{ type: "Prânz", name: "Sushi Veggie Răcoros", desc: "Orez brun, avocado și castravete rulate subtil. Ușor și cu o textură calmată.", icon: "🍣" },
{ type: "Gustare", name: "Cuburi de Pepene sau Citrice", desc: "Apă pură sub formă solidă, combinată cu o explozie revigorantă de vitamine.", icon: "🍉" },
{ type: "Cină", name: "Salată rece de Tăiței Soba", desc: "Tăiței din hrișcă cu un dressing fin de susan, servită rece pentru a potoli irascibilitatea.", icon: "🍜" }
]
},
happy: {
reasoning: "Ești plin de viață, așa că meniul tău trebuie să fie la fel! Am ales ingrediente colorate, vibrante, perfecte pentru a-ți menține energia ridicată.",
meals: [
{ type: "Mic dejun", name: "Bol Acai Tropical", desc: "Culori vibrante din fructe de pădure, mango, kiwi și fulgi de cocos crocanți.", icon: "🥥" },
{ type: "Prânz", name: "Wrap Curcubeu Energetic", desc: "Turtițe integrale umplute cu legume multicolore, hummus și pui marinat.", icon: "🌯" },
{ type: "Gustare", name: "Mix Exotic de Fructe Uscate", desc: "Mango deshidratat, goji și caju pentru savoare și crocant.", icon: "🥭" },
{ type: "Cină", name: "Tacos Festiv", desc: "Un preparat distractiv, interactiv, cu sos salsa proaspăt și guacamole delicios.", icon: "🌮" }
]
}
};
// State
let selectedEmotion = null;
// Loading phrases to make the AI feel alive
const loadingPhrases = [
"Sintetizăm asocierile nutriționale...",
"Analizăm profilul tău emoțional...",
"Calculăm nivelurile de cortizol și serotonină...",
"Pregătim recomandările culinare..."
];
// Switch UI Toggle Logic
aiToggle.addEventListener('change', (e) => {
if (e.target.checked) {
aiKeyContainer.classList.remove('hidden');
} else {
aiKeyContainer.classList.add('hidden');
}
});
// Switch Views
function switchView(viewElement) {
document.querySelectorAll('.view').forEach(v => {
v.classList.remove('active-view');
setTimeout(() => v.classList.add('hidden'), 500); // Wait for fade out
});
setTimeout(() => {
viewElement.classList.remove('hidden');
// Force reflow
void viewElement.offsetWidth;
viewElement.classList.add('active-view');
}, 500);
}
// Change Theme Function
function applyEmotionTheme(emotion) {
// Reset classes on body
document.body.className = '';
if (emotion) {
// Find the variables for this specific emotion in CSS
const computedStyle = getComputedStyle(document.documentElement);
// Setup new primary colors based on custom props from CSS
const primaryVal = computedStyle.getPropertyValue(`--${emotion}-primary`);
const bg1Val = computedStyle.getPropertyValue(`--${emotion}-bg-1`);
const bg2Val = computedStyle.getPropertyValue(`--${emotion}-bg-2`);
// Dynamically override root variables
root.style.setProperty('--primary-color', primaryVal);
root.style.setProperty('--bg-gradient-1', bg1Val);
root.style.setProperty('--bg-gradient-2', bg2Val);
} else {
// Reset to default
root.style.removeProperty('--primary-color');
root.style.removeProperty('--bg-gradient-1');
root.style.removeProperty('--bg-gradient-2');
}
}
// Generate Menu UI from Data
function renderMenu(data) {
menuReasoningText.innerText = data.reasoning;
mealsContainer.innerHTML = '';
data.meals.forEach((meal, index) => {
const card = document.createElement('div');
card.className = 'meal-card';
// Stagger entrance animation
card.style.animationDelay = `${index * 0.15}s`;
card.innerHTML = `
<div class="meal-icon">${meal.icon}</div>
<div class="meal-info">
<h4>${meal.type}</h4>
<h3>${meal.name}</h3>
<p>${meal.desc}</p>
</div>
`;
mealsContainer.appendChild(card);
});
}
// Handle Agent (Local Simulation Logic)
async function generateMenuLocal(emotion, diet, sleep, water) {
let phraseIndex = 0;
// Cycle text while thinking
const intervalId = setInterval(() => {
phraseIndex = (phraseIndex + 1) % loadingPhrases.length;
loadingText.innerText = loadingPhrases[phraseIndex];
}, 1200);
// Simulate Network/Thinking Delay (3-4 seconds for dramatic effect)
await new Promise(resolve => setTimeout(resolve, 3500));
clearInterval(intervalId);
// Find right emotion data (deep copy to avoid mutating original DB)
const baseData = JSON.parse(JSON.stringify(emotionalDatabase[emotion]));
// --- Simulate Contextual Reasoning based on Biometrics ---
let contextualReasoning = "";
sleep = parseFloat(sleep);
water = parseFloat(water);
if (sleep < 6) {
contextualReasoning += "Observ că ai dormit sub 6 ore, deci vei avea nevoie de extra antioxidanți și carbohidrați lenți pentru a evita un crash energetic în timpul zilei. ";
} else if (sleep >= 8) {
contextualReasoning += "Ai avut un somn odihnitor excelent, așa că metabolismul tău e pregătit pentru o asimilare optimă a nutrienților. ";
}
if (water < 2) {
contextualReasoning += "De asemenea, nivelul de hidratare este scăzut. Am adăugat mental o sugestie de extra fibre hidratante și mese cu un conținut ridicat de apă pe lângă meniul de mai jos. ";
}
if (diet.trim() !== '') {
contextualReasoning += `Agentul tău a luat în calcul și restricțiile tale ("${diet}"), ajustând ingredientele. `;
// Very basic mock filtering for the simulation:
const dietTerms = diet.toLowerCase();
if (dietTerms.includes('lactate') || dietTerms.includes('vegan')) {
baseData.meals.forEach(m => m.name = m.name.replace('Brânză', 'Tofu').replace('Iaurt', 'Iaurt de Cocos').replace('Pui', 'Seitan'));
}
}
// Combine base reasoning with our dynamic context
if (contextualReasoning) {
baseData.reasoning = `${contextualReasoning}\n\n${baseData.reasoning}`;
}
renderMenu(baseData);
switchView(menuView);
}
// Event Listeners for Emotions
emotionBtns.forEach(btn => {
btn.addEventListener('click', () => {
const emotion = btn.getAttribute('data-emotion');
const diet = dietInput.value;
const sleep = sleepInput.value;
const water = waterInput.value;
selectedEmotion = emotion;
// UI Updates
applyEmotionTheme(emotion);
switchView(loadingView);
// Check if API Mode is selected implementation placeholder
const useApi = aiToggle.checked;
const apiKey = apiKeyInput.value;
if (useApi && apiKey !== '') {
// To be implemented in next phase
alert("API logic is mapped for V2. Curently falling back to local simulation.");
generateMenuLocal(emotion, diet, sleep, water);
} else {
// Local simulation variant
generateMenuLocal(emotion, diet, sleep, water);
}
});
});
// Back Button
backBtn.addEventListener('click', () => {
selectedEmotion = null;
applyEmotionTheme(null); // Reset theme
switchView(emotionView);
});