mh4
This commit is contained in:
parent
8a19b38bb7
commit
0443b0e2cb
BIN
ai/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
ai/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ai/__pycache__/local_ai_api.cpython-311.pyc
Normal file
BIN
ai/__pycache__/local_ai_api.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -17,6 +17,7 @@ class Activity(models.Model):
|
||||
return self.name
|
||||
|
||||
class Mission(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
trigger_mood_score = models.IntegerField()
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
{% load static %}
|
||||
<link href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
@ -44,6 +45,12 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'core:dashboard' %}">Dashboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'core:note_list' %}">My Notes</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'core:mission_list' %}">Missions</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
|
||||
@ -21,6 +21,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if ai_insight %}
|
||||
<div class="card shadow-sm mb-4 bg-primary-soft">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title fw-bold mb-3"><i class="fas fa-robot me-2"></i>AI-Powered Insights</h5>
|
||||
<blockquote class="blockquote mb-0">
|
||||
<p>{{ ai_insight }}</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title fw-bold mb-3">Filter by Date</h5>
|
||||
@ -53,6 +64,18 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card p-4 shadow-sm mt-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title fw-bold mb-3">Activity-Mood Correlation</h5>
|
||||
{% if activity_mood_data != '[]' %}
|
||||
<canvas id="activityMoodChart"></canvas>
|
||||
{% else %}
|
||||
<div class="text-center p-5">
|
||||
<p class="lead">No activity data found for the selected period.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -108,6 +131,35 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const activityMoodData = JSON.parse('{{ activity_mood_data|safe }}');
|
||||
if (activityMoodData.length > 0) {
|
||||
const ctxActivity = document.getElementById('activityMoodChart').getContext('2d');
|
||||
const activityNames = activityMoodData.map(d => d.activity);
|
||||
const avgMoods = activityMoodData.map(d => d.avg_mood);
|
||||
|
||||
const activityMoodChart = new Chart(ctxActivity, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: activityNames,
|
||||
datasets: [{
|
||||
label: 'Average Mood Score',
|
||||
data: avgMoods,
|
||||
backgroundColor: '#8884d8'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@ -9,6 +9,22 @@
|
||||
</div>
|
||||
|
||||
{% include 'core/mood_modal.html' %}
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2 class="text-center mb-4">Mood History</h2>
|
||||
<div class="row">
|
||||
{% for entry in mood_entries %}
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ entry.date_time|date:"F d, Y" }}</h5>
|
||||
<p class="card-text">Mood Score: {{ entry.mood_score }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
|
||||
28
core/templates/core/mission_confirm_delete.html
Normal file
28
core/templates/core/mission_confirm_delete.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Confirm Delete - PixelMinds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6">
|
||||
<div class="card shadow-sm border-danger">
|
||||
<div class="card-body text-center p-5">
|
||||
<h1 class="card-title text-danger mb-4">Delete Mission</h1>
|
||||
<p>Are you sure you want to delete the mission: <strong>"{{ object.title }}"</strong>?</p>
|
||||
<p class="text-muted">This action cannot be undone.</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-center mt-4">
|
||||
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
||||
<a href="{% url 'core:mission_list' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
16
core/templates/core/mission_detail.html
Normal file
16
core/templates/core/mission_detail.html
Normal file
@ -0,0 +1,16 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{{ mission.title }} - Missions{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<h1 class="mb-4">{{ mission.title }}</h1>
|
||||
<hr>
|
||||
<div class="mt-4">
|
||||
{{ mission.description|linebreaksbr }}
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<a href="{% url 'core:mission_list' %}" class="btn btn-secondary">Back to Missions</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
38
core/templates/core/mission_form.html
Normal file
38
core/templates/core/mission_form.html
Normal file
@ -0,0 +1,38 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{% if object %}Edit Mission{% else %}New Mission{% endif %} - PixelMinds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-5">
|
||||
<h1 class="card-title text-center mb-4">{% if object %}Edit Mission{% else %}Create a New Mission{% endif %}</h1>
|
||||
<form method="post" novalidate>
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
<div class="mb-3">
|
||||
<label for="{{ field.id_for_label }}" class="form-label">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.help_text %}
|
||||
<div class="form-text">{{ field.help_text }}</div>
|
||||
{% endif %}
|
||||
{% for error in field.errors %}
|
||||
<div class="invalid-feedback d-block">{{ error }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
|
||||
<button type="submit" class="btn btn-primary">{% if object %}Save Changes{% else %}Create Mission{% endif %}</button>
|
||||
<a href="{% url 'core:mission_list' %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
44
core/templates/core/mission_list.html
Normal file
44
core/templates/core/mission_list.html
Normal file
@ -0,0 +1,44 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}My Missions - PixelMinds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row mb-4 align-items-center">
|
||||
<div class="col-md-8">
|
||||
<h1 class="section-title mb-0">My Missions</h1>
|
||||
<p class="lead">Create and manage your personal missions.</p>
|
||||
</div>
|
||||
<div class="col-md-4 text-md-end">
|
||||
<a href="{% url 'core:mission_create' %}" class="btn btn-primary">+ Create a New Mission</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if missions %}
|
||||
<div class="list-group">
|
||||
{% for mission in missions %}
|
||||
<div class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">
|
||||
<a href="{% url 'core:mission_detail' mission.pk %}">{{ mission.title }}</a>
|
||||
</h5>
|
||||
<small>{{ mission.created_at|date:"d M Y" }}</small>
|
||||
</div>
|
||||
<p class="mb-1">{{ mission.description|truncatechars:150 }}</p>
|
||||
<div class="mt-3">
|
||||
<a href="{% url 'core:mission_update' mission.pk %}" class="btn btn-sm btn-outline-primary me-2">Edit</a>
|
||||
<a href="{% url 'core:mission_delete' mission.pk %}" class="btn btn-sm btn-outline-danger">Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center p-5">
|
||||
<p class="lead">You haven't created any missions yet.</p>
|
||||
<p class="text-muted">Get started by creating your first mission.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
15
core/templates/core/note_confirm_delete.html
Normal file
15
core/templates/core/note_confirm_delete.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Confirm Delete - My Notes{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<h1>Confirm Delete</h1>
|
||||
<p>Are you sure you want to delete the note "<strong>{{ note.title }}</strong>"?</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
||||
<a href="{% url 'core:note_detail' note.pk %}" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
23
core/templates/core/note_detail.html
Normal file
23
core/templates/core/note_detail.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{{ note.title }} - My Notes{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>{{ note.title }}</h1>
|
||||
<div>
|
||||
<a href="{% url 'core:note_update' note.pk %}" class="btn btn-outline-secondary">Edit</a>
|
||||
<a href="{% url 'core:note_delete' note.pk %}" class="btn btn-outline-danger">Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
<p><small class="text-muted">Last updated: {{ note.updated_at|date:"F d, Y H:i" }}</small></p>
|
||||
<hr>
|
||||
<div class="mt-4">
|
||||
{{ note.content|linebreaksbr }}
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<a href="{% url 'core:note_list' %}" class="btn btn-secondary">Back to Notes</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
22
core/templates/core/note_form.html
Normal file
22
core/templates/core/note_form.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{% if form.instance.pk %}Edit Note{% else %}New Note{% endif %} - PixelMinds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<h1>{% if form.instance.pk %}Edit Note{% else %}New Note{% endif %}</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label for="id_title" class="form-label">Title</label>
|
||||
<input type="text" name="title" id="id_title" class="form-control" value="{{ form.title.value|default:'' }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="id_content" class="form-label">Content</label>
|
||||
<textarea name="content" id="id_content" class="form-control" rows="10" required>{{ form.content.value|default:'' }}</textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<a href="{% if form.instance.pk %}{% url 'core:note_detail' form.instance.pk %}{% else %}{% url 'core:note_list' %}{% endif %}" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
31
core/templates/core/note_list.html
Normal file
31
core/templates/core/note_list.html
Normal file
@ -0,0 +1,31 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}My Notes - PixelMinds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>My Notes</h1>
|
||||
<a href="{% url 'core:note_create' %}" class="btn btn-primary">New Note</a>
|
||||
</div>
|
||||
<div class="row">
|
||||
{% for note in notes %}
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><a href="{% url 'core:note_detail' note.pk %}">{{ note.title }}</a></h5>
|
||||
<p class="card-text">{{ note.content|truncatechars:100 }}</p>
|
||||
<p class="card-text"><small class="text-muted">Last updated: {{ note.updated_at|date:"F d, Y" }}</small></p>
|
||||
<a href="{% url 'core:note_update' note.pk %}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<a href="{% url 'core:note_delete' note.pk %}" class="btn btn-sm btn-outline-danger">Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="col">
|
||||
<p>You don't have any notes yet. <a href="{% url 'core:note_create' %}">Create your first note!</a></p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
16
core/urls.py
16
core/urls.py
@ -1,6 +1,10 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import home, create_mood_entry, dashboard, AboutView, ContactView, PrivacyPolicyView, SignUpView, save_mood_entry
|
||||
from .views import (
|
||||
home, create_mood_entry, dashboard, AboutView, ContactView, PrivacyPolicyView, SignUpView, save_mood_entry,
|
||||
NoteListView, NoteDetailView, NoteCreateView, NoteUpdateView, NoteDeleteView,
|
||||
MissionListView, MissionDetailView, MissionCreateView, MissionUpdateView, MissionDeleteView
|
||||
)
|
||||
|
||||
app_name = 'core'
|
||||
|
||||
@ -13,4 +17,14 @@ urlpatterns = [
|
||||
path('about/', AboutView.as_view(), name='about'),
|
||||
path('contact/', ContactView.as_view(), name='contact'),
|
||||
path('privacy-policy/', PrivacyPolicyView.as_view(), name='privacy_policy'),
|
||||
path('notes/', NoteListView.as_view(), name='note_list'),
|
||||
path('note/<int:pk>/', NoteDetailView.as_view(), name='note_detail'),
|
||||
path('note/new/', NoteCreateView.as_view(), name='note_create'),
|
||||
path('note/<int:pk>/edit/', NoteUpdateView.as_view(), name='note_update'),
|
||||
path('note/<int:pk>/delete/', NoteDeleteView.as_view(), name='note_delete'),
|
||||
path('missions/', MissionListView.as_view(), name='mission_list'),
|
||||
path('mission/new/', MissionCreateView.as_view(), name='mission_create'),
|
||||
path('mission/<int:pk>/', MissionDetailView.as_view(), name='mission_detail'),
|
||||
path('mission/<int:pk>/edit/', MissionUpdateView.as_view(), name='mission_update'),
|
||||
path('mission/<int:pk>/delete/', MissionDeleteView.as_view(), name='mission_delete'),
|
||||
]
|
||||
129
core/views.py
129
core/views.py
@ -7,14 +7,101 @@ from django.shortcuts import render, redirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import JsonResponse
|
||||
from django.views.generic import TemplateView, FormView, CreateView
|
||||
from django_pandas.io import read_frame
|
||||
from django.contrib import messages
|
||||
from django.views.generic import TemplateView, FormView, CreateView, ListView, DetailView, UpdateView, DeleteView
|
||||
from django.db import models
|
||||
|
||||
from .forms import MoodEntryForm, ContactForm, SignUpForm, DateRangeFilterForm
|
||||
from .models import MoodEntry, Activity
|
||||
from .models import MoodEntry, Activity, Note, Mission
|
||||
from .mail import send_contact_message
|
||||
from ai.local_ai_api import LocalAIApi
|
||||
|
||||
|
||||
class MissionListView(LoginRequiredMixin, ListView):
|
||||
model = Mission
|
||||
template_name = 'core/mission_list.html'
|
||||
context_object_name = 'missions'
|
||||
|
||||
def get_queryset(self):
|
||||
return Mission.objects.filter(user=self.request.user).order_by('-is_active', '-created_at')
|
||||
|
||||
|
||||
class MissionDetailView(LoginRequiredMixin, DetailView):
|
||||
model = Mission
|
||||
template_name = 'core/mission_detail.html'
|
||||
context_object_name = 'mission'
|
||||
|
||||
def get_queryset(self):
|
||||
return Mission.objects.filter(user=self.request.user)
|
||||
|
||||
|
||||
class MissionCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Mission
|
||||
template_name = 'core/mission_form.html'
|
||||
fields = ['title', 'description', 'is_active']
|
||||
success_url = reverse_lazy('core:mission_list')
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.user = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class MissionUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Mission
|
||||
template_name = 'core/mission_form.html'
|
||||
fields = ['title', 'description', 'is_active']
|
||||
success_url = reverse_lazy('core:mission_list')
|
||||
|
||||
def get_queryset(self):
|
||||
return Mission.objects.filter(user=self.request.user)
|
||||
|
||||
|
||||
class MissionDeleteView(LoginRequiredMixin, DeleteView):
|
||||
model = Mission
|
||||
template_name = 'core/mission_confirm_delete.html'
|
||||
success_url = reverse_lazy('core:mission_list')
|
||||
|
||||
def get_queryset(self):
|
||||
return Mission.objects.filter(user=self.request.user)
|
||||
|
||||
|
||||
class NoteListView(LoginRequiredMixin, ListView):
|
||||
model = Note
|
||||
template_name = 'core/note_list.html'
|
||||
context_object_name = 'notes'
|
||||
|
||||
def get_queryset(self):
|
||||
return Note.objects.filter(user=self.request.user).order_by('-updated_at')
|
||||
|
||||
class NoteDetailView(LoginRequiredMixin, DetailView):
|
||||
model = Note
|
||||
template_name = 'core/note_detail.html'
|
||||
context_object_name = 'note'
|
||||
|
||||
class NoteCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Note
|
||||
template_name = 'core/note_form.html'
|
||||
fields = ['title', 'content']
|
||||
success_url = reverse_lazy('core:note_list')
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.user = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
||||
class NoteUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Note
|
||||
template_name = 'core/note_form.html'
|
||||
fields = ['title', 'content']
|
||||
success_url = reverse_lazy('core:note_list')
|
||||
|
||||
class NoteDeleteView(LoginRequiredMixin, DeleteView):
|
||||
model = Note
|
||||
template_name = 'core/note_confirm_delete.html'
|
||||
success_url = reverse_lazy('core:note_list')
|
||||
|
||||
from django_pandas.io import read_frame
|
||||
from django.contrib import messages
|
||||
|
||||
|
||||
class SignUpView(CreateView):
|
||||
@ -82,7 +169,39 @@ def dashboard(request):
|
||||
if not df.empty:
|
||||
df['date_time'] = df['date_time'].dt.strftime('%Y-%m-%d')
|
||||
chart_data = df.to_json(orient='records')
|
||||
return render(request, 'core/dashboard.html', {'chart_data': chart_data, 'form': form})
|
||||
|
||||
# Activity-Mood Correlation
|
||||
activity_mood_data = []
|
||||
activities = Activity.objects.all()
|
||||
for activity in activities:
|
||||
entries_with_activity = mood_entries.filter(activities=activity)
|
||||
if entries_with_activity.exists():
|
||||
avg_mood = entries_with_activity.aggregate(avg_mood=models.Avg('mood_score'))['avg_mood']
|
||||
activity_mood_data.append({
|
||||
'activity': activity.name,
|
||||
'avg_mood': round(avg_mood, 2)
|
||||
})
|
||||
|
||||
# AI-powered insights
|
||||
ai_insight = ''
|
||||
if mood_entries.exists():
|
||||
latest_mood_data = list(mood_entries.order_by('-date_time')[:7].values('date_time', 'mood_score'))
|
||||
prompt = f"Based on the following recent mood entries, provide a brief summary and one actionable recommendation. Mood data: {json.dumps(latest_mood_data, default=str)}"
|
||||
ai_response = LocalAIApi.create_response({
|
||||
"input": [
|
||||
{"role": "system", "content": "You are a mental wellness assistant. Provide concise, actionable advice."},
|
||||
{"role": "user", "content": prompt},
|
||||
]
|
||||
})
|
||||
if ai_response.get("success"):
|
||||
ai_insight = LocalAIApi.extract_text(ai_response)
|
||||
|
||||
return render(request, 'core/dashboard.html', {
|
||||
'chart_data': chart_data,
|
||||
'form': form,
|
||||
'activity_mood_data': json.dumps(activity_mood_data),
|
||||
'ai_insight': ai_insight,
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user