-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbot.js
More file actions
596 lines (504 loc) Β· 26.6 KB
/
bot.js
File metadata and controls
596 lines (504 loc) Β· 26.6 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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
// Mental Health Chatbot Logic
class MentalHealthBot {
constructor() {
this.context = [];
this.userName = null;
this.conversationCount = 0;
this.moodHistory = this.loadMoodHistory();
this.journalEntries = this.loadJournalEntries();
this.currentJournalId = null;
this.init();
}
init() {
this.setupEventListeners();
this.loadChatHistory();
}
setupEventListeners() {
// Navigation
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', (e) => this.switchView(e.target.closest('.nav-item')));
});
// Chat
document.getElementById('send-btn').addEventListener('click', () => this.sendMessage());
document.getElementById('user-input').addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
});
document.getElementById('clear-chat').addEventListener('click', () => this.clearChat());
// Quick starters
document.querySelectorAll('.quick-start-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const msg = e.target.dataset.msg;
document.getElementById('user-input').value = msg;
this.sendMessage();
});
});
// Mood tracker
document.querySelectorAll('.mood-btn').forEach(btn => {
btn.addEventListener('click', (e) => this.selectMood(e.target.closest('.mood-btn')));
});
document.getElementById('save-mood').addEventListener('click', () => this.saveMood());
// Journal
document.getElementById('save-journal').addEventListener('click', () => this.saveJournal());
document.getElementById('new-journal').addEventListener('click', () => this.newJournal());
// Auto-resize textarea
const textarea = document.getElementById('user-input');
textarea.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 150) + 'px';
});
}
switchView(navItem) {
document.querySelectorAll('.nav-item').forEach(item => item.classList.remove('active'));
document.querySelectorAll('.view').forEach(view => view.classList.remove('active'));
navItem.classList.add('active');
const viewName = navItem.dataset.view;
document.getElementById(`${viewName}-view`).classList.add('active');
if (viewName === 'mood') {
this.renderMoodHistory();
} else if (viewName === 'journal') {
this.renderJournalEntries();
}
}
async sendMessage() {
const input = document.getElementById('user-input');
const message = input.value.trim();
if (!message) return;
this.addMessage(message, 'user');
input.value = '';
input.style.height = 'auto';
this.removeWelcomeMessage();
this.showTypingIndicator();
// Simulate AI response delay
await this.sleep(1500);
const response = this.generateResponse(message);
this.hideTypingIndicator();
this.addMessage(response, 'bot');
this.saveChatHistory();
this.conversationCount++;
}
generateResponse(message) {
const lowerMessage = message.toLowerCase();
this.context.push(message);
// Anxiety responses
if (lowerMessage.includes('anxious') || lowerMessage.includes('anxiety') || lowerMessage.includes('worried')) {
return this.anxietyResponse();
}
// Depression/sadness responses
if (lowerMessage.includes('sad') || lowerMessage.includes('depressed') || lowerMessage.includes('down') || lowerMessage.includes('hopeless')) {
return this.depressionResponse();
}
// Stress responses
if (lowerMessage.includes('stress') || lowerMessage.includes('overwhelmed') || lowerMessage.includes('pressure')) {
return this.stressResponse();
}
// Loneliness responses
if (lowerMessage.includes('lonely') || lowerMessage.includes('alone') || lowerMessage.includes('isolated')) {
return this.lonelinessResponse();
}
// Motivation responses
if (lowerMessage.includes('motivat') || lowerMessage.includes('give up') || lowerMessage.includes('can\'t do')) {
return this.motivationResponse();
}
// Sleep issues
if (lowerMessage.includes('sleep') || lowerMessage.includes('insomnia') || lowerMessage.includes('tired')) {
return this.sleepResponse();
}
// Relationship issues
if (lowerMessage.includes('relationship') || lowerMessage.includes('friend') || lowerMessage.includes('family')) {
return this.relationshipResponse();
}
// Work/study stress
if (lowerMessage.includes('work') || lowerMessage.includes('job') || lowerMessage.includes('study') || lowerMessage.includes('exam')) {
return this.workStressResponse();
}
// Positive messages
if (lowerMessage.includes('good') || lowerMessage.includes('happy') || lowerMessage.includes('great') || lowerMessage.includes('better')) {
return this.positiveResponse();
}
// Gratitude
if (lowerMessage.includes('thank') || lowerMessage.includes('appreciate')) {
return "You're very welcome! I'm here whenever you need support. Remember, reaching out is a sign of strength, not weakness. Is there anything else on your mind?";
}
// Default empathetic response
return this.defaultResponse();
}
anxietyResponse() {
const responses = [
"I hear that you're feeling anxious. Anxiety can be overwhelming, but you're not alone in this. Would you like to try a breathing exercise? It can help calm your nervous system. Also, have you tried naming what specifically is making you anxious?",
"Anxiety is your mind trying to protect you, even when there's no immediate danger. Let's work through this together. Can you identify what's triggering these feelings? Sometimes just talking about it can help reduce its power over you.",
"Thank you for sharing that you're feeling anxious. One technique that many find helpful is the 5-4-3-2-1 grounding method: name 5 things you see, 4 you can touch, 3 you hear, 2 you smell, and 1 you taste. Would you like to try this?"
];
return this.getRandomResponse(responses);
}
depressionResponse() {
const responses = [
"I'm really glad you're opening up about feeling this way. Depression can make everything feel heavy and hopeless, but please know that these feelings are temporary, even when they don't feel that way. Have you been able to do any small self-care activities today, even something as simple as getting some sunlight or fresh air?",
"What you're experiencing sounds really difficult, and I want you to know that your feelings are valid. Depression isn't a sign of weaknessβit's a real health condition. Have you considered talking to a mental health professional? In the meantime, can you think of one tiny thing that usually brings you even a moment of comfort?",
"Thank you for trusting me with this. When you're feeling down, remember that you don't have to fix everything at once. Small steps count. Can you name one thing you accomplished today, no matter how small? Even getting out of bed counts."
];
return this.getRandomResponse(responses);
}
stressResponse() {
const responses = [
"Stress can feel like you're carrying the weight of the world. Let's try to break this down together. What's the most urgent thing causing you stress right now? Sometimes prioritizing can help make things feel more manageable.",
"Feeling overwhelmed is a sign that you're dealing with a lot. That takes strength. Have you been able to take any breaks today? Even 5 minutes of deep breathing or a short walk can help reset your stress response.",
"I understand you're under a lot of pressure. Remember, you can't pour from an empty cup. What's one thing you could delegate, postpone, or let go of to give yourself some breathing room?"
];
return this.getRandomResponse(responses);
}
lonelinessResponse() {
const responses = [
"Loneliness is one of the hardest feelings to sit with. I want you to know that feeling lonely doesn't mean there's something wrong with youβit's a universal human experience. Have you been able to reach out to anyone today, even with just a text message?",
"I'm here with you, and I hear that you're feeling isolated. Sometimes loneliness can feel overwhelming, especially in our hyper-connected world. Is there a community, club, or group activity you've been interested in? Sometimes shared interests can be a bridge to connection.",
"Thank you for sharing this with me. Loneliness can be really painful. Remember that quality of connection matters more than quantity. Is there someone from your past you've lost touch with that you might reconnect with? Sometimes reaching out can feel vulnerable, but it's also brave."
];
return this.getRandomResponse(responses);
}
motivationResponse() {
const responses = [
"It sounds like you're going through a really tough time with motivation. That's completely understandableβsometimes life feels like an uphill battle. Can you think of a time when you overcame something difficult? What helped you then? You've been strong before, and you can tap into that strength again.",
"Loss of motivation often comes when we're overwhelmed or exhausted. Instead of trying to do everything, what's ONE tiny thing you could do today that would make you feel even slightly accomplished? Start there. Small wins build momentum.",
"I believe in you, even when you're struggling to believe in yourself. Motivation often comes AFTER we start, not before. What's one small action you could take right now, even if you don't feel motivated? Sometimes we need to 'act as if' until the feeling follows."
];
return this.getRandomResponse(responses);
}
sleepResponse() {
const responses = [
"Sleep issues can really impact everything else in our lives. Have you tried establishing a wind-down routine before bed? Things like avoiding screens an hour before sleep, keeping your room cool and dark, and doing some light stretching can help signal to your body that it's time to rest.",
"Trouble sleeping is really frustrating. Are you finding that your mind is racing at night? Sometimes writing down your thoughts before bed can help clear your mind. Also, try to keep a consistent sleep schedule, even on weekends.",
"Sleep is so important for mental health. If you're having persistent sleep issues, it might be worth talking to a doctor. In the meantime, avoid caffeine after 2pm, try some calming tea, and consider meditation or gentle yoga before bed."
];
return this.getRandomResponse(responses);
}
relationshipResponse() {
const responses = [
"Relationships can be complex and challenging. What specifically is troubling you? Remember that healthy communication is keyβexpressing your needs clearly and listening actively to the other person. Sometimes conflicts arise from misunderstandings rather than fundamental incompatibility.",
"It sounds like you're dealing with some relationship challenges. That's really common, and it's good that you're thinking about it. Have you been able to communicate your feelings to the other person? Sometimes we expect others to read our minds, but clear communication is essential.",
"Relationships require work from all parties involved. Are you taking care of yourself in this relationship? Remember that you can't control others' actions, only your own responses. Setting healthy boundaries is an act of self-respect and can actually improve relationships."
];
return this.getRandomResponse(responses);
}
workStressResponse() {
const responses = [
"Work and academic stress are so common, especially in today's demanding environment. Are you able to set boundaries between work/study time and personal time? Remember that rest isn't lazinessβit's necessary for productivity and wellbeing. What's one boundary you could set this week?",
"It sounds like you're under a lot of pressure with work or studies. Have you tried breaking down your tasks into smaller, manageable chunks? The Pomodoro Technique (25 minutes of focused work, then a 5-minute break) can help. Also, remember that perfectionism can be the enemy of progress.",
"Academic and work stress can feel never-ending, but your worth isn't determined by your productivity or grades. Are you taking regular breaks? Can you talk to a supervisor, professor, or counselor about the workload? Sometimes asking for help or an extension is the most responsible thing you can do."
];
return this.getRandomResponse(responses);
}
positiveResponse() {
const responses = [
"That's wonderful to hear! I'm so glad things are looking up for you. What do you think contributed to this positive change? Recognizing what helps can be valuable for future challenges.",
"I'm really happy for you! It's important to celebrate the good moments, no matter how small. Keep nurturing whatever is bringing you joy. What else is going well for you?",
"That's great news! Remember this feelingβit can be an anchor during tougher times. You deserve to feel good. Keep taking care of yourself!"
];
return this.getRandomResponse(responses);
}
defaultResponse() {
const responses = [
"Thank you for sharing that with me. I'm here to listen without judgment. Can you tell me more about what you're experiencing? Sometimes talking things through can help clarify our feelings.",
"I appreciate you opening up. What you're feeling is valid. Would you like to explore this further, or is there something specific you'd like support with?",
"I hear you. It takes courage to express what's on your mind. How are you taking care of yourself right now? Remember, self-compassion is important, especially during difficult times.",
"Thank you for trusting me with your thoughts. Everyone's journey is unique, and there's no 'right' way to feel. What would be most helpful for you right nowβtalking through this, learning coping strategies, or something else?"
];
return this.getRandomResponse(responses);
}
getRandomResponse(responses) {
return responses[Math.floor(Math.random() * responses.length)];
}
addMessage(text, sender) {
const chatContainer = document.getElementById('chat-container');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${sender}`;
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = sender === 'user' ? 'π€' : 'π€';
const content = document.createElement('div');
content.className = 'message-content';
content.textContent = text;
messageDiv.appendChild(avatar);
messageDiv.appendChild(content);
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
showTypingIndicator() {
const chatContainer = document.getElementById('chat-container');
const typingDiv = document.createElement('div');
typingDiv.className = 'message bot typing';
typingDiv.id = 'typing-indicator';
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = 'π€';
const content = document.createElement('div');
content.className = 'message-content';
const indicator = document.createElement('div');
indicator.className = 'typing-indicator';
indicator.innerHTML = '<span></span><span></span><span></span>';
content.appendChild(indicator);
typingDiv.appendChild(avatar);
typingDiv.appendChild(content);
chatContainer.appendChild(typingDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
hideTypingIndicator() {
const indicator = document.getElementById('typing-indicator');
if (indicator) {
indicator.remove();
}
}
removeWelcomeMessage() {
const welcome = document.querySelector('.welcome-message');
if (welcome) {
welcome.style.display = 'none';
}
}
clearChat() {
if (confirm('Are you sure you want to clear the chat history?')) {
const chatContainer = document.getElementById('chat-container');
chatContainer.innerHTML = `
<div class="welcome-message">
<div class="welcome-icon">π</div>
<h3>Welcome to MindSpace</h3>
<p>I'm here to support you. Share what's on your mind, and let's work through it together.</p>
<div class="quick-starters">
<button class="quick-start-btn" data-msg="I'm feeling anxious">π° Feeling Anxious</button>
<button class="quick-start-btn" data-msg="I'm stressed about work/studies">π Work Stress</button>
<button class="quick-start-btn" data-msg="I'm feeling lonely">π Feeling Lonely</button>
<button class="quick-start-btn" data-msg="I need motivation">πͺ Need Motivation</button>
</div>
</div>
`;
document.querySelectorAll('.quick-start-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const msg = e.target.dataset.msg;
document.getElementById('user-input').value = msg;
this.sendMessage();
});
});
this.context = [];
localStorage.removeItem('chatHistory');
}
}
saveChatHistory() {
const messages = Array.from(document.querySelectorAll('.message:not(.typing)')).map(msg => ({
text: msg.querySelector('.message-content').textContent,
sender: msg.classList.contains('user') ? 'user' : 'bot'
}));
localStorage.setItem('chatHistory', JSON.stringify(messages));
}
loadChatHistory() {
const history = localStorage.getItem('chatHistory');
if (history) {
const messages = JSON.parse(history);
if (messages.length > 0) {
this.removeWelcomeMessage();
messages.forEach(msg => this.addMessage(msg.text, msg.sender));
}
}
}
// Mood Tracking
selectMood(btn) {
document.querySelectorAll('.mood-btn').forEach(b => b.classList.remove('selected'));
btn.classList.add('selected');
}
saveMood() {
const selectedMood = document.querySelector('.mood-btn.selected');
if (!selectedMood) {
alert('Please select a mood first');
return;
}
const mood = selectedMood.dataset.mood;
const note = document.getElementById('mood-note').value;
const entry = {
id: Date.now(),
mood: mood,
emoji: selectedMood.querySelector('.mood-emoji').textContent,
note: note,
date: new Date().toISOString()
};
this.moodHistory.push(entry);
this.saveMoodHistory();
document.querySelectorAll('.mood-btn').forEach(b => b.classList.remove('selected'));
document.getElementById('mood-note').value = '';
this.renderMoodHistory();
alert('Mood entry saved!');
}
renderMoodHistory() {
const entriesList = document.getElementById('mood-entries');
const chartContainer = document.getElementById('mood-chart');
if (this.moodHistory.length === 0) {
entriesList.innerHTML = '<p style="color: var(--text-secondary); text-align: center;">No mood entries yet. Start tracking your mood today!</p>';
chartContainer.innerHTML = '<p style="color: var(--text-secondary);">Your mood chart will appear here once you start tracking.</p>';
return;
}
// Render entries
entriesList.innerHTML = this.moodHistory
.slice()
.reverse()
.map(entry => `
<div class="mood-entry">
<div class="mood-entry-emoji">${entry.emoji}</div>
<div class="mood-entry-content">
<strong>${entry.mood.charAt(0).toUpperCase() + entry.mood.slice(1)}</strong>
<div class="mood-entry-date">${new Date(entry.date).toLocaleDateString()} at ${new Date(entry.date).toLocaleTimeString()}</div>
${entry.note ? `<div class="mood-entry-note">"${entry.note}"</div>` : ''}
</div>
</div>
`).join('');
// Simple mood chart
const moodCounts = this.moodHistory.reduce((acc, entry) => {
acc[entry.mood] = (acc[entry.mood] || 0) + 1;
return acc;
}, {});
chartContainer.innerHTML = `
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 1rem;">
${Object.entries(moodCounts).map(([mood, count]) => `
<div style="text-align: center;">
<div style="font-size: 2rem; margin-bottom: 0.5rem;">
${this.getMoodEmoji(mood)}
</div>
<div style="font-weight: bold;">${count}</div>
<div style="color: var(--text-secondary); font-size: 0.85rem;">${mood}</div>
</div>
`).join('')}
</div>
`;
}
getMoodEmoji(mood) {
const emojis = {
amazing: 'π€©',
good: 'π',
okay: 'π',
low: 'π',
struggling: 'π’'
};
return emojis[mood] || 'π';
}
saveMoodHistory() {
localStorage.setItem('moodHistory', JSON.stringify(this.moodHistory));
}
loadMoodHistory() {
const history = localStorage.getItem('moodHistory');
return history ? JSON.parse(history) : [];
}
// Journal Functions
saveJournal() {
const title = document.getElementById('journal-title').value || 'Untitled Entry';
const content = document.getElementById('journal-content').value.trim();
if (!content) {
alert('Please write something before saving');
return;
}
if (this.currentJournalId) {
// Update existing entry
const index = this.journalEntries.findIndex(e => e.id === this.currentJournalId);
if (index !== -1) {
this.journalEntries[index] = {
...this.journalEntries[index],
title: title,
content: content,
modified: new Date().toISOString()
};
}
} else {
// Create new entry
const entry = {
id: Date.now(),
title: title,
content: content,
date: new Date().toISOString()
};
this.journalEntries.push(entry);
}
this.saveJournalEntries();
this.renderJournalEntries();
alert('Journal entry saved!');
this.newJournal();
}
newJournal() {
document.getElementById('journal-title').value = '';
document.getElementById('journal-content').value = '';
this.currentJournalId = null;
}
loadJournalEntry(id) {
const entry = this.journalEntries.find(e => e.id === id);
if (entry) {
document.getElementById('journal-title').value = entry.title;
document.getElementById('journal-content').value = entry.content;
this.currentJournalId = id;
}
}
renderJournalEntries() {
const journalList = document.getElementById('journal-list');
if (this.journalEntries.length === 0) {
journalList.innerHTML = '<p style="color: var(--text-secondary); text-align: center;">No journal entries yet. Start writing your thoughts!</p>';
return;
}
journalList.innerHTML = this.journalEntries
.slice()
.reverse()
.map(entry => `
<div class="journal-item" onclick="bot.loadJournalEntry(${entry.id})">
<div class="journal-item-header">
<div class="journal-item-title">${entry.title}</div>
<div class="journal-item-date">${new Date(entry.date).toLocaleDateString()}</div>
</div>
<div class="journal-item-preview">${entry.content.substring(0, 150)}${entry.content.length > 150 ? '...' : ''}</div>
</div>
`).join('');
}
saveJournalEntries() {
localStorage.setItem('journalEntries', JSON.stringify(this.journalEntries));
}
loadJournalEntries() {
const entries = localStorage.getItem('journalEntries');
return entries ? JSON.parse(entries) : [];
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Breathing Exercise Functions
function showBreathingExercise() {
const modal = document.getElementById('breathing-modal');
modal.classList.add('active');
const instruction = document.getElementById('breathing-instruction');
const phases = ['Breathe In', 'Hold', 'Breathe Out', 'Hold'];
let phaseIndex = 0;
const interval = setInterval(() => {
instruction.textContent = phases[phaseIndex];
phaseIndex = (phaseIndex + 1) % phases.length;
}, 4000);
modal.dataset.interval = interval;
}
function closeBreathingExercise() {
const modal = document.getElementById('breathing-modal');
modal.classList.remove('active');
clearInterval(modal.dataset.interval);
}
function showCBTTechniques() {
alert('Cognitive Behavioral Techniques:\n\n' +
'1. Thought Record: Write down negative thoughts and challenge them with evidence\n' +
'2. Behavioral Activation: Schedule activities that bring joy or accomplishment\n' +
'3. Cognitive Restructuring: Identify and replace unhelpful thinking patterns\n' +
'4. Problem-Solving: Break down problems into manageable steps\n' +
'5. Exposure: Gradually face fears in a safe, controlled way');
}
function showSelfCareTips() {
alert('Daily Self-Care Practices:\n\n' +
'β’ Get 7-9 hours of sleep\n' +
'β’ Exercise for 30 minutes\n' +
'β’ Eat nutritious meals\n' +
'β’ Practice mindfulness or meditation\n' +
'β’ Connect with loved ones\n' +
'β’ Limit social media\n' +
'β’ Pursue hobbies you enjoy\n' +
'β’ Set healthy boundaries\n' +
'β’ Practice gratitude\n' +
'β’ Seek professional help when needed');
}
// Initialize the bot
const bot = new MentalHealthBot();