diff --git a/osinaweb/celerybeat-schedule.db b/osinaweb/celerybeat-schedule.db index 6507ddcc..931ef97d 100644 Binary files a/osinaweb/celerybeat-schedule.db and b/osinaweb/celerybeat-schedule.db differ diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 930ba711..602c0268 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc b/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc index 6ab9d0ee..1c47789b 100644 Binary files a/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc index 9bf61668..1d7b0e94 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc b/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc index 45facdba..bb1d3cc2 100644 Binary files a/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc index 11758da5..410b0423 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/osinacore/admin.py b/osinaweb/osinacore/admin.py index f5010357..70367cb4 100644 --- a/osinaweb/osinacore/admin.py +++ b/osinaweb/osinacore/admin.py @@ -45,4 +45,5 @@ admin.site.register(DailyReport) admin.site.register(BusinessType) admin.site.register(PointActivity) admin.site.register(Connection) +admin.site.register(Reaction) diff --git a/osinaweb/osinacore/migrations/0064_reaction.py b/osinaweb/osinacore/migrations/0064_reaction.py new file mode 100644 index 00000000..d751036c --- /dev/null +++ b/osinaweb/osinacore/migrations/0064_reaction.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.5 on 2024-03-22 17:00 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('osinacore', '0063_alter_connection_date'), + ] + + operations = [ + migrations.CreateModel( + name='Reaction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('emoji', models.CharField(max_length=15)), + ('status', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.status')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0064_reaction.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0064_reaction.cpython-310.pyc new file mode 100644 index 00000000..760d351a Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0064_reaction.cpython-310.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index a593b39d..f7115cf5 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -304,6 +304,12 @@ class Status(models.Model): staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='staff') +class Reaction(models.Model): + status = models.ForeignKey(Status, on_delete=models.CASCADE) + emoji = models.CharField(max_length=15) + user = models.ForeignKey(User, on_delete=models.CASCADE) + + class DailyReport(models.Model): diff --git a/osinaweb/osinacore/templates/main.html b/osinaweb/osinacore/templates/main.html index 0a3c9f4b..80b25c03 100644 --- a/osinaweb/osinacore/templates/main.html +++ b/osinaweb/osinacore/templates/main.html @@ -3,6 +3,7 @@ + {% block title %} Osina {% endblock %} diff --git a/osinaweb/osinacore/templates/recent-activities.html b/osinaweb/osinacore/templates/recent-activities.html index a41f2863..8574451b 100644 --- a/osinaweb/osinacore/templates/recent-activities.html +++ b/osinaweb/osinacore/templates/recent-activities.html @@ -15,7 +15,7 @@

Add Reaction

- + {% csrf_token %}
@@ -43,6 +43,31 @@
+ + +
@@ -150,9 +175,9 @@ {%endif%}
- +
-
+
@@ -177,11 +202,13 @@
+ {% if latest.status.reaction_set.all %}
-

😄

-

😅

-

🍀

+ {% for reaction in latest.status.reaction_set.all %} +

{{reaction.emoji}}

+ {% endfor %}
+ {% endif %} {% endfor %} diff --git a/osinaweb/osinacore/urls.py b/osinaweb/osinacore/urls.py index bf889493..baaa66f6 100644 --- a/osinaweb/osinacore/urls.py +++ b/osinaweb/osinacore/urls.py @@ -68,7 +68,7 @@ urlpatterns = [ path('fetch_epics/', views.fetch_epics, name='fetch_epics'), - + path('add_reaction///', views.add_reaction, name='add_reaction'), #CUSTOMER DASHBOARD path('customerdashboard/', views.customer_index, name='customerdashboard'), diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index cc031b27..98690d3c 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -456,6 +456,18 @@ def get_updated_last_status(request): # TO GET USER ACTIVITIES def get_latest_activities(request): + latest_connections = Connection.objects.filter( + user__staffprofile__isnull=False + ).values('user').annotate( + latest_connection=Max('date') + ) + online_staff_profiles = [] + for connection in latest_connections: + user_id = connection['user'] + latest_connection = connection['latest_connection'] + last_connection = Connection.objects.filter(user_id=user_id, date=latest_connection).first() + if last_connection.status == 'Online': + online_staff_profiles.append(last_connection.user.staffprofile) if request.user.is_authenticated and request.user.is_superuser: open_task_count = Task.objects.filter(status='Open').count() working_on_task_count = Task.objects.filter(status='Working On').count() @@ -482,7 +494,8 @@ def get_latest_activities(request): response_data = { 'total_tasks': total_tasks, - 'latest_statuses_time_ago': latest_statuses_time_ago, # Include latest_statuses_time_ago in the context + 'latest_statuses_time_ago': latest_statuses_time_ago, + 'online_staff_profiles' : online_staff_profiles, } recent_activities = render_to_string('recent-activities.html', response_data) @@ -520,3 +533,17 @@ def customer_invoices(request, *args, **kwargs): return render(request, 'customer_dashboard/listing_pages/customer-invoices.html', context) + +def add_reaction(request, status_id, emoji): + status = get_object_or_404(Status, pk=status_id) + user = request.user + existing_reaction = Reaction.objects.filter(status=status, user=user).first() + if existing_reaction: + # If the user has already reacted, update the reaction + existing_reaction.emoji = emoji + existing_reaction.save() + return JsonResponse({'message': 'Reaction updated successfully.'}) + else: + # If the user hasn't reacted yet, create a new reaction + new_reaction = Reaction.objects.create(status=status, emoji=emoji, user=user) + return JsonResponse({'message': 'Reaction added successfully.'}) diff --git a/osinaweb/static/js/emoji-picker.js b/osinaweb/static/js/emoji-picker.js index 2fd3cab5..9292019f 100644 --- a/osinaweb/static/js/emoji-picker.js +++ b/osinaweb/static/js/emoji-picker.js @@ -4,16 +4,18 @@ document.addEventListener('DOMContentLoaded', function () { const emojiPicker = document.getElementById('emojiPicker'); const closeEmojiPicker = document.getElementById('closeEmojiPicker'); const emojiPickerContainer = document.getElementById('emojiPickerContainer'); + let statusId; emojiPicker.addEventListener('click', function () { + statusId = emojiPicker.dataset.statusId; emojiPickerContainer.classList.remove('hidden'); + console.log(statusId); }); closeEmojiPicker.addEventListener('click', function () { emojiPickerContainer.classList.add('hidden'); }); - // To navigate between categories const categories = document.querySelectorAll('.emoji-category'); const categoryContainers = document.querySelectorAll('.emoji-category-container');