diff --git a/README.md b/README.md index 803f355..a583ea1 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,6 @@ TurTask is a task and project management tool that incorporates gamification elements. -[Wiki Repository](https://github.com/TurTaskProject/TurTaskWiki) +[Wiki Page](https://github.com/TurTaskProject/TurTaskWeb/wiki) + +[Project Board](https://github.com/orgs/TurTaskProject/projects/1) diff --git a/backend/tasks/api.py b/backend/tasks/api.py index 4736582..7669d76 100644 --- a/backend/tasks/api.py +++ b/backend/tasks/api.py @@ -7,8 +7,8 @@ from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from tasks.utils import get_service -from tasks.models import Task -from tasks.serializers import TaskUpdateSerializer +from tasks.models import Todo, RecurrenceTask +from tasks.serializers import TodoUpdateSerializer, RecurrenceTaskUpdateSerializer class GoogleCalendarEventViewset(viewsets.ViewSet): @@ -17,28 +17,34 @@ class GoogleCalendarEventViewset(viewsets.ViewSet): def __init__(self, *args, **kwargs): super().__init__() self.current_time = datetime.now(tz=timezone.utc).isoformat() - self.event_fields = 'items(id,summary,description,created,updated,start,end)' + self.event_fields = 'items(id,summary,description,created,recurringEventId,updated,start,end)' def _validate_serializer(self, serializer): if serializer.is_valid(): serializer.save() - return Response("Task Sync Successfully", status=200) + return Response("Validate Successfully", status=200) return Response(serializer.errors, status=400) def post(self, request): service = get_service(request) events = service.events().list(calendarId='primary', fields=self.event_fields).execute() for event in events.get('items', []): + if event.get('recurringEventId'): + continue + event['start_datetime'] = event.get('start').get('dateTime') + event['end_datetime'] = event.get('end').get('dateTime') + event.pop('start') + event.pop('end') try: - task = Task.objects.get(google_calendar_id=event['id']) - serializer = TaskUpdateSerializer(instance=task, data=event) + task = Todo.objects.get(google_calendar_id=event['id']) + serializer = TodoUpdateSerializer(instance=task, data=event) return self._validate_serializer(serializer) - except Task.DoesNotExist: - serializer = TaskUpdateSerializer(data=event, user=request.user) + except Todo.DoesNotExist: + serializer = TodoUpdateSerializer(data=event, user=request.user) return self._validate_serializer(serializer) def list(self, request, days=7): - max_time = (datetime.now(tz=timezone.utc) + timedelta(days=3)).isoformat() + max_time = (datetime.now(tz=timezone.utc) + timedelta(days=days)).isoformat() service = get_service(request) events = [] @@ -49,11 +55,11 @@ class GoogleCalendarEventViewset(viewsets.ViewSet): calendarId='primary', timeMin=self.current_time, timeMax=max_time, - maxResults=20, + maxResults=200, singleEvents=True, orderBy='startTime', pageToken=next_page_token, - fields='items(id,summary,description,created,updated,start,end)', + fields='items(id,summary,description,created,recurringEventId,updated,start,end)', ) page_results = query.execute() diff --git a/backend/tasks/apps.py b/backend/tasks/apps.py index 3ff3ab3..0d81307 100644 --- a/backend/tasks/apps.py +++ b/backend/tasks/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class TasksConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'tasks' + + def ready(self): + import tasks.signals \ No newline at end of file diff --git a/backend/tasks/migrations/0010_todo_alter_subtask_parent_task_delete_task.py b/backend/tasks/migrations/0010_todo_alter_subtask_parent_task_delete_task.py new file mode 100644 index 0000000..2e6b65d --- /dev/null +++ b/backend/tasks/migrations/0010_todo_alter_subtask_parent_task_delete_task.py @@ -0,0 +1,47 @@ +# Generated by Django 4.2.6 on 2023-11-06 15:01 + +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), + ('tasks', '0009_alter_task_options_task_importance_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Todo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('notes', models.TextField(default='')), + ('importance', models.PositiveSmallIntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')], default=1)), + ('difficulty', models.PositiveSmallIntegerField(choices=[(1, 'Easy'), (2, 'Normal'), (3, 'Hard'), (4, 'Very Hard'), (5, 'Devil')], default=1)), + ('challenge', models.BooleanField(default=False)), + ('fromSystem', models.BooleanField(default=False)), + ('creation_date', models.DateTimeField(auto_now_add=True)), + ('last_update', models.DateTimeField(auto_now=True)), + ('google_calendar_id', models.CharField(blank=True, max_length=255, null=True)), + ('start_event', models.DateTimeField(null=True)), + ('end_event', models.DateTimeField(null=True)), + ('priority', models.PositiveSmallIntegerField(choices=[(1, 'Important & Urgent'), (2, 'Important & Not Urgent'), (3, 'Not Important & Urgent'), (4, 'Not Important & Not Urgent')], default=4)), + ('tags', models.ManyToManyField(blank=True, to='tasks.tag')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + migrations.AlterField( + model_name='subtask', + name='parent_task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tasks.todo'), + ), + migrations.DeleteModel( + name='Task', + ), + ] diff --git a/backend/tasks/migrations/0011_recurrencetask.py b/backend/tasks/migrations/0011_recurrencetask.py new file mode 100644 index 0000000..cc7225a --- /dev/null +++ b/backend/tasks/migrations/0011_recurrencetask.py @@ -0,0 +1,39 @@ +# Generated by Django 4.2.6 on 2023-11-06 16:14 + +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), + ('tasks', '0010_todo_alter_subtask_parent_task_delete_task'), + ] + + operations = [ + migrations.CreateModel( + name='RecurrenceTask', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.TextField()), + ('notes', models.TextField(default='')), + ('importance', models.PositiveSmallIntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')], default=1)), + ('difficulty', models.PositiveSmallIntegerField(choices=[(1, 'Easy'), (2, 'Normal'), (3, 'Hard'), (4, 'Very Hard'), (5, 'Devil')], default=1)), + ('challenge', models.BooleanField(default=False)), + ('fromSystem', models.BooleanField(default=False)), + ('creation_date', models.DateTimeField(auto_now_add=True)), + ('last_update', models.DateTimeField(auto_now=True)), + ('google_calendar_id', models.CharField(blank=True, max_length=255, null=True)), + ('start_event', models.DateTimeField(null=True)), + ('end_event', models.DateTimeField(null=True)), + ('recurrence_rule', models.TextField()), + ('tags', models.ManyToManyField(blank=True, to='tasks.tag')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/backend/tasks/models.py b/backend/tasks/models.py index 7677acb..5da815e 100644 --- a/backend/tasks/models.py +++ b/backend/tasks/models.py @@ -1,9 +1,5 @@ -from datetime import datetime - from django.db import models from django.conf import settings -from django.core import validators -from django.utils import timezone class Tag(models.Model): """ @@ -16,21 +12,16 @@ class Tag(models.Model): class Task(models.Model): """ - Represents a task, such as Habit, Daily, Todo, or Reward. - - :param type: The type of the tasks + Represents a Abstract of task, such as Habit, Daily, Todo, or Reward. + + :param user: The user who owns the task. :param title: Title of the task. :param notes: Optional additional notes for the task. :param tags: Associated tags for the task. :param completed: A boolean field indicating whether the task is completed. - :param exp: The experience values user will get from the task. - :param priority: The priority of the task (1, 2, .., 4), using Eisenhower Matrix Idea. :param importance: The importance of the task (range: 1 to 5) :param difficulty: The difficulty of the task (range: 1 to 5). - :param attribute: The attribute linked to the task - :param user: The user who owns the task. :param challenge: Associated challenge (optional). - :param reminders: A Many-to-Many relationship with Reminder. :param fromSystem: A boolean field indicating if the task is from System. :param creation_date: Creation date of the task. :param last_update: Last updated date of the task. @@ -38,87 +29,49 @@ class Task(models.Model): :param start_event: Start event of the task. :param end_event: End event(Due Date) of the task. """ - TASK_TYPES = [ - ('daily', 'Daily'), - ('habit', 'Habit'), - ('todo', 'Todo'), - ('Long Term Goal', 'Long Term Goal'), - ] + class Difficulty(models.IntegerChoices): + EASY = 1, 'Easy' + NORMAL = 2, 'Normal' + HARD = 3, 'Hard' + VERY_HARD = 4, 'Very Hard' + DEVIL = 5, 'Devil' - DIFFICULTY_CHOICES = [ - (1, 'Easy'), - (2, 'Normal'), - (3, 'Hard'), - (4, 'Very Hard'), - (5, 'Devil'), - ] - - ATTRIBUTE = [ - ('str', 'Strength'), - ('int', 'Intelligence'), - ('end', 'Endurance'), - ('per', 'Perception'), - ('luck', 'Luck'), - ] - - EISENHOWER_MATRIX = [ - (1, 'Important & Urgent'), - (2, 'Important & Not Urgent'), - (3, 'Not Important & Urgent'), - (4, 'Not Important & Not Urgent'), - ] - - type = models.CharField(max_length=15, choices=TASK_TYPES, default='habit') + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.TextField() notes = models.TextField(default='') tags = models.ManyToManyField(Tag, blank=True) - completed = models.BooleanField(default=False) - exp = models.FloatField(default=0) - priority = models.PositiveSmallIntegerField(choices=EISENHOWER_MATRIX, default=4) importance = models.PositiveSmallIntegerField(choices=[(i, str(i)) for i in range(1, 6)], default=1) - difficulty = models.PositiveSmallIntegerField(choices=DIFFICULTY_CHOICES, default=1) - attribute = models.CharField(max_length=15, choices=ATTRIBUTE, default='str') - user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + difficulty = models.PositiveSmallIntegerField(choices=Difficulty.choices, default=Difficulty.EASY) challenge = models.BooleanField(default=False) fromSystem = models.BooleanField(default=False) creation_date = models.DateTimeField(auto_now_add=True) last_update = models.DateTimeField(auto_now=True) - google_calendar_id = models.CharField(blank=True, null=True, max_length=255) + google_calendar_id = models.CharField(max_length=255, null=True, blank=True) start_event = models.DateTimeField(null=True) end_event = models.DateTimeField(null=True) - def calculate_eisenhower_matrix_category(self): - """ - Classify the task into one of the four categories in the Eisenhower Matrix. - - :return: The category of the task (1, 2, 3, or 4). - """ - if self.end_event: - time_until_due = (self.end_event - datetime.now(timezone.utc)).days - else: - time_until_due = float('inf') - - urgency_threshold = 3 - importance_threshold = 3 - - if time_until_due <= urgency_threshold and self.importance >= importance_threshold: - return 1 - elif time_until_due > urgency_threshold and self.importance >= importance_threshold: - return 2 - elif time_until_due <= urgency_threshold and self.importance < importance_threshold: - return 3 - else: - return 4 - - def save(self, *args, **kwargs): - self.priority = self.calculate_eisenhower_matrix_category() - super(Task, self).save(*args, **kwargs) - class Meta: - verbose_name = 'Task' - verbose_name_plural = 'Tasks' + abstract = True +class Todo(Task): + + class EisenhowerMatrix(models.IntegerChoices): + IMPORTANT_URGENT = 1, 'Important & Urgent' + IMPORTANT_NOT_URGENT = 2, 'Important & Not Urgent' + NOT_IMPORTANT_URGENT = 3, 'Not Important & Urgent' + NOT_IMPORTANT_NOT_URGENT = 4, 'Not Important & Not Urgent' + + priority = models.PositiveSmallIntegerField(choices=EisenhowerMatrix.choices, default=EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT) + + def __str__(self): + return self.title + +class RecurrenceTask(Task): + recurrence_rule = models.TextField() + + def __str__(self) -> str: + return f"{self.title} ({self.recurrence_rule})" class Subtask(models.Model): """ @@ -127,9 +80,9 @@ class Subtask(models.Model): :param completed: A boolean field indicating whether the subtask is completed. :param parent_task: The parent task of the subtask. """ + parent_task = models.ForeignKey(Todo, on_delete=models.CASCADE) description = models.TextField() completed = models.BooleanField(default=False) - parent_task = models.ForeignKey(Task, on_delete=models.CASCADE) class UserNotification(models.Model): diff --git a/backend/tasks/serializers.py b/backend/tasks/serializers.py index 494920f..ed02300 100644 --- a/backend/tasks/serializers.py +++ b/backend/tasks/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers from django.utils.dateparse import parse_datetime -from .models import Task +from .models import Todo, RecurrenceTask class GoogleCalendarEventSerializer(serializers.Serializer): @@ -10,7 +10,7 @@ class GoogleCalendarEventSerializer(serializers.Serializer): description = serializers.CharField(required=False) -class TaskUpdateSerializer(serializers.ModelSerializer): +class TodoUpdateSerializer(serializers.ModelSerializer): id = serializers.CharField(source="google_calendar_id") summary = serializers.CharField(source="title") description = serializers.CharField(source="notes", required=False) @@ -21,15 +21,41 @@ class TaskUpdateSerializer(serializers.ModelSerializer): class Meta: - model = Task + model = Todo fields = ('id', 'summary', 'description', 'created', 'updated', 'start_datetime', 'end_datetime') def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) - super(TaskUpdateSerializer, self).__init__(*args, **kwargs) + super(TodoUpdateSerializer, self).__init__(*args, **kwargs) def create(self, validated_data): validated_data['user'] = self.user - task = Task.objects.create(**validated_data) + task = Todo.objects.create(**validated_data) + + return task + + +class RecurrenceTaskUpdateSerializer(serializers.ModelSerializer): + id = serializers.CharField(source="google_calendar_id") + summary = serializers.CharField(source="title") + description = serializers.CharField(source="notes", required=False) + created = serializers.DateTimeField(source="creation_date") + updated = serializers.DateTimeField(source="last_update") + recurrence = serializers.DateTimeField(source="recurrence_rule") + start_datetime = serializers.DateTimeField(source="start_event", required=False) + end_datetime = serializers.DateTimeField(source="end_event", required=False) + + + class Meta: + model = RecurrenceTask + fields = ('id', 'summary', 'description', 'created', 'updated', 'recurrence', 'start_datetime', 'end_datetime') + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user', None) + super(RecurrenceTaskUpdateSerializer, self).__init__(*args, **kwargs) + + def create(self, validated_data): + validated_data['user'] = self.user + task = RecurrenceTask.objects.create(**validated_data) return task \ No newline at end of file diff --git a/backend/tasks/signals.py b/backend/tasks/signals.py new file mode 100644 index 0000000..af17e57 --- /dev/null +++ b/backend/tasks/signals.py @@ -0,0 +1,25 @@ +from django.db.models.signals import pre_save +from django.dispatch import receiver +from django.utils import timezone + +from tasks.models import Todo + + +@receiver(pre_save, sender=Todo) +def update_priority(sender, instance, **kwargs): + if instance.end_event: + time_until_due = (instance.end_event - timezone.now()).days + else: + time_until_due = float('inf') + + urgency_threshold = 3 + importance_threshold = 3 + + if time_until_due <= urgency_threshold and instance.importance >= importance_threshold: + instance.priority = Todo.EisenhowerMatrix.IMPORTANT_URGENT + elif time_until_due > urgency_threshold and instance.importance >= importance_threshold: + instance.priority = Todo.EisenhowerMatrix.IMPORTANT_NOT_URGENT + elif time_until_due <= urgency_threshold and instance.importance < importance_threshold: + instance.priority = Todo.EisenhowerMatrix.NOT_IMPORTANT_URGENT + else: + instance.priority = Todo.EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT \ No newline at end of file diff --git a/backend/tasks/tasks/serializers.py b/backend/tasks/tasks/serializers.py index 7876263..85f0281 100644 --- a/backend/tasks/tasks/serializers.py +++ b/backend/tasks/tasks/serializers.py @@ -1,21 +1,21 @@ from rest_framework import serializers -from ..models import Task +from ..models import Todo class TaskCreateSerializer(serializers.ModelSerializer): class Meta: - model = Task + model = Todo # fields = '__all__' exclude = ('tags',) def create(self, validated_data): # Create a new task with validated data - return Task.objects.create(**validated_data) + return Todo.objects.create(**validated_data) class TaskGeneralSerializer(serializers.ModelSerializer): class Meta: - model = Task + model = Todo fields = '__all__' def create(self, validated_data): # Create a new task with validated data - return Task.objects.create(**validated_data) \ No newline at end of file + return Todo.objects.create(**validated_data) \ No newline at end of file diff --git a/backend/tasks/tasks/views.py b/backend/tasks/tasks/views.py index 0f75ced..d884bbe 100644 --- a/backend/tasks/tasks/views.py +++ b/backend/tasks/tasks/views.py @@ -1,37 +1,16 @@ -from rest_framework import status -from rest_framework.response import Response -from rest_framework.generics import CreateAPIView, RetrieveAPIView, RetrieveUpdateAPIView, DestroyAPIView +from rest_framework import viewsets from rest_framework.permissions import IsAuthenticated -from ..models import Task +from tasks.models import Todo from .serializers import TaskCreateSerializer, TaskGeneralSerializer -class TaskCreateView(CreateAPIView): - queryset = Task.objects.all() - serializer_class = TaskCreateSerializer - permission_classes = [IsAuthenticated] - def create(self, request, *args, **kwargs): - serializer = self.get_serializer(data=request.data) - - if serializer.is_valid(): - self.perform_create(serializer) - return Response(serializer.data, status=status.HTTP_201_CREATED) - - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - -class TaskRetrieveView(RetrieveAPIView): - queryset = Task.objects.all() +class TodoViewSet(viewsets.ModelViewSet): + queryset = Todo.objects.all() serializer_class = TaskGeneralSerializer permission_classes = [IsAuthenticated] - -class TaskUpdateView(RetrieveUpdateAPIView): - queryset = Task.objects.all() - serializer_class = TaskGeneralSerializer - permission_classes = [IsAuthenticated] - - -class TaskDeleteView(DestroyAPIView): - queryset = Task.objects.all() - permission_classes = [IsAuthenticated] \ No newline at end of file + def get_serializer_class(self): + # Can't add ManytoMany at creation time (Tags) + if self.action == 'create': + return TaskCreateSerializer + return TaskGeneralSerializer \ No newline at end of file diff --git a/backend/tasks/tests/test_deserializer.py b/backend/tasks/tests/test_deserializer.py index aa07480..306185c 100644 --- a/backend/tasks/tests/test_deserializer.py +++ b/backend/tasks/tests/test_deserializer.py @@ -5,8 +5,8 @@ from django.test import TestCase from django.utils import timezone from tasks.tests.utils import create_test_user, login_user -from tasks.serializers import TaskUpdateSerializer -from tasks.models import Task +from tasks.serializers import TodoUpdateSerializer +from tasks.models import Todo class TaskUpdateSerializerTest(TestCase): def setUp(self): @@ -25,14 +25,14 @@ class TaskUpdateSerializerTest(TestCase): 'end_datetie': self.end_time, } - serializer = TaskUpdateSerializer(data=data, user=self.user) + serializer = TodoUpdateSerializer(data=data, user=self.user) self.assertTrue(serializer.is_valid()) serializer.is_valid() task = serializer.save() - self.assertIsInstance(task, Task) + self.assertIsInstance(task, Todo) def test_serializer_update(self): - task = Task.objects.create(title='Original Task', notes='Original description', user=self.user) + task = Todo.objects.create(title='Original Task', notes='Original description', user=self.user) data = { 'id': '32141cwaNcapufh8jq2conw', @@ -44,7 +44,7 @@ class TaskUpdateSerializerTest(TestCase): 'end_datetie': self.end_time, } - serializer = TaskUpdateSerializer(instance=task, data=data) + serializer = TodoUpdateSerializer(instance=task, data=data) self.assertTrue(serializer.is_valid()) updated_task = serializer.save() diff --git a/backend/tasks/tests/test_task_eisenhower.py b/backend/tasks/tests/test_task_eisenhower.py deleted file mode 100644 index b8b3c22..0000000 --- a/backend/tasks/tests/test_task_eisenhower.py +++ /dev/null @@ -1,38 +0,0 @@ -from datetime import datetime, timedelta, timezone - -from django.test import TestCase - -from tasks.models import Task -from tasks.tests.utils import create_test_user - -class TaskModelTest(TestCase): - def setUp(self): - self.user = create_test_user() - - def test_eisenhower_matrix_category(self): - task = Task(importance=2, end_event=None, user=self.user) - task.save() - - # 'Not Important & Not Urgent' category (category 4) - self.assertEqual(task.calculate_eisenhower_matrix_category(), 4) - - due_date = datetime.now(timezone.utc) + timedelta(days=1) - task = Task(importance=4, end_event=due_date, user=self.user) - task.save() - - # 'Important & Urgent' category (category 1) - self.assertEqual(task.calculate_eisenhower_matrix_category(), 1) - - due_date = datetime.now(timezone.utc) + timedelta(days=10) - task = Task(importance=3, end_event=due_date, user=self.user) - task.save() - - # 'Important & Not Urgent' category (category 2) - self.assertEqual(task.calculate_eisenhower_matrix_category(), 2) - - due_date = datetime.now(timezone.utc) + timedelta(days=4) - task = Task(importance=1, end_event=due_date, user=self.user) - task.save() - - # 'Not Important & Urgent' category (category 3) - self.assertEqual(task.calculate_eisenhower_matrix_category(), 3) \ No newline at end of file diff --git a/backend/tasks/tests/test_task_creation.py b/backend/tasks/tests/test_todo_creation.py similarity index 76% rename from backend/tasks/tests/test_task_creation.py rename to backend/tasks/tests/test_todo_creation.py index af7986f..9912126 100644 --- a/backend/tasks/tests/test_task_creation.py +++ b/backend/tasks/tests/test_todo_creation.py @@ -1,22 +1,19 @@ from datetime import datetime, timedelta - from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase - from tasks.tests.utils import create_test_user, login_user -from ..models import Task +from tasks.models import Todo -class TaskCreateViewTests(APITestCase): + +class TodoViewSetTests(APITestCase): def setUp(self): - self.user = create_test_user() self.client = login_user(self.user) - self.url = reverse("add-task") + self.url = reverse("todo-list") self.due_date = datetime.now() + timedelta(days=5) - - def test_create_valid_task(self): + def test_create_valid_todo(self): """ Test creating a valid task using the API. """ @@ -28,24 +25,23 @@ class TaskCreateViewTests(APITestCase): 'priority': 1, 'difficulty': 1, 'user': self.user.id, - 'end_event': self.due_date, + 'end_event': self.due_date.strftime('%Y-%m-%dT%H:%M:%S'), } response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(Task.objects.count(), 1) - self.assertEqual(Task.objects.get().title, 'Test Task') + self.assertEqual(Todo.objects.count(), 1) + self.assertEqual(Todo.objects.get().title, 'Test Task') - def test_create_invalid_task(self): + def test_create_invalid_todo(self): """ Test creating an invalid task using the API. """ data = { 'type': 'invalid', # Invalid task type } - response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(Task.objects.count(), 0) # No task should be created + self.assertEqual(Todo.objects.count(), 0) # No task should be created def test_missing_required_fields(self): """ @@ -55,10 +51,9 @@ class TaskCreateViewTests(APITestCase): 'title': 'Incomplete Task', 'type': 'habit', } - response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(Task.objects.count(), 0) # No task should be created + self.assertEqual(Todo.objects.count(), 0) # No task should be created def test_invalid_user_id(self): """ @@ -71,9 +66,8 @@ class TaskCreateViewTests(APITestCase): 'priority': 1, 'difficulty': 1, 'user': 999, # Invalid user ID - 'end_event': self.due_date, + 'end_event': self.due_date.strftime('%Y-%m-%dT%H:%M:%S'), } - response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(Task.objects.count(), 0) # No task should be created + self.assertEqual(Todo.objects.count(), 0) # No task should be created diff --git a/backend/tasks/tests/test_todo_eisenhower.py b/backend/tasks/tests/test_todo_eisenhower.py new file mode 100644 index 0000000..41ee078 --- /dev/null +++ b/backend/tasks/tests/test_todo_eisenhower.py @@ -0,0 +1,36 @@ +from datetime import datetime, timedelta, timezone +from django.test import TestCase +from tasks.models import Todo +from tasks.tests.utils import create_test_user + +class TodoPriorityTest(TestCase): + def setUp(self): + self.user = create_test_user() + + def test_priority_calculation(self): + # Important = 2, Till Due = none + todo = Todo(importance=2, end_event=None, user=self.user) + todo.save() + # 'Not Important & Not Urgent' + self.assertEqual(todo.priority, Todo.EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT) + + due_date = datetime.now(timezone.utc) + timedelta(days=1) + # Important = 4, Till Due = 1 + todo = Todo(importance=4, end_event=due_date, user=self.user) + todo.save() + # 'Important & Urgent' + self.assertEqual(todo.priority, Todo.EisenhowerMatrix.IMPORTANT_URGENT) + + due_date = datetime.now(timezone.utc) + timedelta(days=10) + # Important = 3, Till Due = 10 + todo = Todo(importance=3, end_event=due_date, user=self.user) + todo.save() + # 'Important & Not Urgent' + self.assertEqual(todo.priority, Todo.EisenhowerMatrix.IMPORTANT_NOT_URGENT) + + due_date = datetime.now(timezone.utc) + timedelta(days=2) + # Important = 1, Till Due = 2 + todo = Todo(importance=1, end_event=due_date, user=self.user) + todo.save() + # 'Not Important & Urgent' + self.assertEqual(todo.priority, Todo.EisenhowerMatrix.NOT_IMPORTANT_URGENT) diff --git a/backend/tasks/tests/utils.py b/backend/tasks/tests/utils.py index f33b828..b1bef0b 100644 --- a/backend/tasks/tests/utils.py +++ b/backend/tasks/tests/utils.py @@ -1,7 +1,7 @@ from rest_framework.test import APIClient from users.models import CustomUser -from ..models import Task +from ..models import Todo def create_test_user(email="testusertestuser@example.com", username="testusertestuser", @@ -61,4 +61,4 @@ def create_test_task(user, **kwargs): task_attributes = {**defaults, **kwargs} - return Task.objects.create(user=user, **task_attributes) \ No newline at end of file + return Todo.objects.create(user=user, **task_attributes) \ No newline at end of file diff --git a/backend/tasks/urls.py b/backend/tasks/urls.py index c04bd68..b44ddd9 100644 --- a/backend/tasks/urls.py +++ b/backend/tasks/urls.py @@ -1,17 +1,17 @@ from django.urls import path, include + from rest_framework.routers import DefaultRouter -from .api import GoogleCalendarEventViewset -from .tasks.views import TaskCreateView, TaskRetrieveView, TaskUpdateView, TaskDeleteView -from .misc.views import TagViewSet + +from tasks.api import GoogleCalendarEventViewset +from tasks.tasks.views import TodoViewSet +from tasks.misc.views import TagViewSet + router = DefaultRouter() +router.register(r'todo', TodoViewSet) router.register(r'tags', TagViewSet) router.register(r'calendar-events', GoogleCalendarEventViewset, basename='calendar-events') urlpatterns = [ path('', include(router.urls)), - path('tasks/create/', TaskCreateView.as_view(), name="add-task"), - path('tasks//', TaskRetrieveView.as_view(), name='retrieve-task'), - path('tasks//update/', TaskUpdateView.as_view(), name='update-task'), - path('tasks//delete/', TaskDeleteView.as_view(), name='delete-task'), ] \ No newline at end of file diff --git a/backend/users/apps.py b/backend/users/apps.py index 72b1401..434524e 100644 --- a/backend/users/apps.py +++ b/backend/users/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class UsersConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'users' + + def ready(self): + import users.signals \ No newline at end of file diff --git a/backend/users/migrations/0004_userstats.py b/backend/users/migrations/0004_userstats.py new file mode 100644 index 0000000..2780aae --- /dev/null +++ b/backend/users/migrations/0004_userstats.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.6 on 2023-11-06 05:30 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_customuser_profile_pic'), + ] + + operations = [ + migrations.CreateModel( + name='UserStats', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('health', models.IntegerField(default=100)), + ('gold', models.FloatField(default=0.0)), + ('experience', models.FloatField(default=0)), + ('strength', models.IntegerField(default=1)), + ('intelligence', models.IntegerField(default=1)), + ('endurance', models.IntegerField(default=1)), + ('perception', models.IntegerField(default=1)), + ('luck', models.IntegerField(default=1)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/backend/users/models.py b/backend/users/models.py index 5b5b176..c2eb9fd 100644 --- a/backend/users/models.py +++ b/backend/users/models.py @@ -1,7 +1,11 @@ +import random +import math + from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin +from django.core.validators import MinValueValidator, MaxValueValidator from .managers import CustomAccountManager @@ -32,15 +36,33 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): return self.username -# class UserStats(models.Model): -# """ -# Represents User Profiles and Attributes. -# Fields: -# - health: health points of the user. -# - gold: gold points of the user. -# - experience: experience points of the user. -# """ -# user = models.OneToOneField(CustomUser, on_delete=models.CASCADE) -# health = models.IntegerField(default=100) -# gold = models.IntegerField(default=0) -# experience = models.FloatField(default=0) \ No newline at end of file +def random_luck(): + return random.randint(1, 50) + +class UserStats(models.Model): + """ + Represents User Profiles and Attributes. + Fields: + - health: health points of the user. + - gold: gold points of the user. + - experience: experience points of the user. + """ + user = models.OneToOneField(CustomUser, on_delete=models.CASCADE) + health = models.IntegerField(default=100) + gold = models.FloatField(default=0.0) + experience = models.FloatField(default=0) + strength = models.IntegerField(default=1, + validators=[MinValueValidator(1), + MaxValueValidator(100)]) + intelligence = models.IntegerField(default=1, validators=[MinValueValidator(1), + MaxValueValidator(100)]) + endurance = models.IntegerField(default=1, validators=[MinValueValidator(1), + MaxValueValidator(100)]) + perception = models.IntegerField(default=1, validators=[MinValueValidator(1), + MaxValueValidator(100)]) + luck = models.IntegerField(default=random_luck, validators=[MinValueValidator(1), + MaxValueValidator(50)],) + + @property + def level(self): + return (math.pow(self.experience, 2) // 225) + 1 \ No newline at end of file diff --git a/backend/users/signals.py b/backend/users/signals.py new file mode 100644 index 0000000..817986b --- /dev/null +++ b/backend/users/signals.py @@ -0,0 +1,9 @@ +from django.db.models.signals import post_save +from django.dispatch import receiver + +from users.models import CustomUser, UserStats + +@receiver(post_save, sender=CustomUser) +def create_user_stats(sender, instance, created, **kwargs): + if created: + UserStats.objects.create(user=instance) \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 793cfe0..ab93583 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,12 +10,23 @@ "preview": "vite preview" }, "dependencies": { + "@asseinfo/react-kanban": "^2.2.0", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", + "@fullcalendar/core": "^6.1.9", + "@fullcalendar/daygrid": "^6.1.9", + "@fullcalendar/interaction": "^6.1.9", + "@fullcalendar/react": "^6.1.9", + "@fullcalendar/timegrid": "^6.1.9", "@mui/icons-material": "^5.14.15", "@mui/material": "^5.14.15", "@mui/system": "^5.14.15", "@react-oauth/google": "^0.11.1", + "@syncfusion/ej2-base": "^23.1.41", + "@syncfusion/ej2-kanban": "^23.1.36", "axios": "^1.5.1", "bootstrap": "^5.3.2", "dotenv": "^16.3.1", @@ -23,6 +34,7 @@ "gapi-script": "^1.2.0", "jwt-decode": "^4.0.0", "react": "^18.2.0", + "react-beautiful-dnd": "^13.1.1", "react-bootstrap": "^2.9.1", "react-dom": "^18.2.0", "react-icons": "^4.11.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 67325cd..18dfd97 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,28 +1,57 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - dependencies: + '@asseinfo/react-kanban': + specifier: ^2.2.0 + version: 2.2.0(react-dom@18.2.0)(react@18.2.0) + '@dnd-kit/core': + specifier: ^6.1.0 + version: 6.1.0(react-dom@18.2.0)(react@18.2.0) + '@dnd-kit/sortable': + specifier: ^8.0.0 + version: 8.0.0(@dnd-kit/core@6.1.0)(react@18.2.0) + '@dnd-kit/utilities': + specifier: ^3.2.2 + version: 3.2.2(react@18.2.0) '@emotion/react': specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.33)(react@18.2.0) + version: 11.11.1(@types/react@18.2.15)(react@18.2.0) '@emotion/styled': specifier: ^11.11.0 - version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) + version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) + '@fullcalendar/core': + specifier: ^6.1.9 + version: 6.1.9 + '@fullcalendar/daygrid': + specifier: ^6.1.9 + version: 6.1.9(@fullcalendar/core@6.1.9) + '@fullcalendar/interaction': + specifier: ^6.1.9 + version: 6.1.9(@fullcalendar/core@6.1.9) + '@fullcalendar/react': + specifier: ^6.1.9 + version: 6.1.9(@fullcalendar/core@6.1.9)(react-dom@18.2.0)(react@18.2.0) + '@fullcalendar/timegrid': + specifier: ^6.1.9 + version: 6.1.9(@fullcalendar/core@6.1.9) '@mui/icons-material': specifier: ^5.14.15 - version: 5.14.15(@mui/material@5.14.15)(@types/react@18.2.33)(react@18.2.0) + version: 5.14.15(@mui/material@5.14.15)(@types/react@18.2.15)(react@18.2.0) '@mui/material': specifier: ^5.14.15 - version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) + version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) '@mui/system': specifier: ^5.14.15 - version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react@18.2.0) + version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react@18.2.0) '@react-oauth/google': specifier: ^0.11.1 version: 0.11.1(react-dom@18.2.0)(react@18.2.0) + '@syncfusion/ej2-base': + specifier: ^23.1.41 + version: 23.1.41 + '@syncfusion/ej2-kanban': + specifier: ^23.1.36 + version: 23.1.36 axios: specifier: ^1.5.1 version: 1.5.1 @@ -44,9 +73,12 @@ dependencies: react: specifier: ^18.2.0 version: 18.2.0 + react-beautiful-dnd: + specifier: ^13.1.1 + version: 13.1.1(react-dom@18.2.0)(react@18.2.0) react-bootstrap: specifier: ^2.9.1 - version: 2.9.1(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) + version: 2.9.1(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) @@ -63,13 +95,13 @@ devDependencies: version: 0.5.10(tailwindcss@3.3.5) '@types/react': specifier: ^18.2.15 - version: 18.2.33 + version: 18.2.15 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.14 + version: 18.2.7 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.1.0(vite@4.5.0) + version: 4.0.3(vite@4.4.5) autoprefixer: specifier: ^10.4.16 version: 10.4.16(postcss@8.4.31) @@ -78,16 +110,16 @@ devDependencies: version: 3.9.4 eslint: specifier: ^8.45.0 - version: 8.52.0 + version: 8.45.0 eslint-plugin-react: specifier: ^7.32.2 - version: 7.33.2(eslint@8.52.0) + version: 7.32.2(eslint@8.45.0) eslint-plugin-react-hooks: specifier: ^4.6.0 - version: 4.6.0(eslint@8.52.0) + version: 4.6.0(eslint@8.45.0) eslint-plugin-react-refresh: specifier: ^0.4.3 - version: 0.4.3(eslint@8.52.0) + version: 0.4.3(eslint@8.45.0) postcss: specifier: ^8.4.31 version: 8.4.31 @@ -96,7 +128,7 @@ devDependencies: version: 3.3.5 vite: specifier: ^4.4.5 - version: 4.5.0 + version: 4.4.5 packages: @@ -118,6 +150,19 @@ packages: '@jridgewell/trace-mapping': 0.3.20 dev: true + /@asseinfo/react-kanban@2.2.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-/gCigrNXRHeP9VCo8RipTOrA0vAPRIOThJhR4ibVxe6BLkaWFUEuJ1RMT4fODpRRsE3XsdrfVGKkfpRBKgvxXg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + dependencies: + react: 18.2.0 + react-beautiful-dnd: 13.1.1(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - react-native + dev: false + /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} @@ -125,25 +170,25 @@ packages: '@babel/highlight': 7.22.20 chalk: 2.4.2 - /@babel/compat-data@7.23.2: - resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} + /@babel/compat-data@7.23.3: + resolution: {integrity: sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.23.2: - resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} + /@babel/core@7.23.3: + resolution: {integrity: sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/generator': 7.23.3 '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3) '@babel/helpers': 7.23.2 - '@babel/parser': 7.23.0 + '@babel/parser': 7.23.3 '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -153,11 +198,11 @@ packages: - supports-color dev: true - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + /@babel/generator@7.23.3: + resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 @@ -167,7 +212,7 @@ packages: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.2 + '@babel/compat-data': 7.23.3 '@babel/helper-validator-option': 7.22.15 browserslist: 4.22.1 lru-cache: 5.1.1 @@ -184,29 +229,29 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 - /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): - resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -223,14 +268,14 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: true /@babel/helper-string-parser@7.22.5: @@ -251,8 +296,8 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 transitivePeerDependencies: - supports-color dev: true @@ -265,31 +310,31 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.23.0: - resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + /@babel/parser@7.23.3: + resolution: {integrity: sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.3 dev: true - /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: true @@ -305,36 +350,79 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 dev: true - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + /@babel/traverse@7.23.3: + resolution: {integrity: sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/generator': 7.23.3 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.23.0: - resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + /@babel/types@7.23.3: + resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@dnd-kit/accessibility@3.1.0(react@18.2.0): + resolution: {integrity: sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /@dnd-kit/core@6.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@dnd-kit/accessibility': 3.1.0(react@18.2.0) + '@dnd-kit/utilities': 3.2.2(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.6.2 + dev: false + + /@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0)(react@18.2.0): + resolution: {integrity: sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==} + peerDependencies: + '@dnd-kit/core': ^6.1.0 + react: '>=16.8.0' + dependencies: + '@dnd-kit/core': 6.1.0(react-dom@18.2.0)(react@18.2.0) + '@dnd-kit/utilities': 3.2.2(react@18.2.0) + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /@dnd-kit/utilities@3.2.2(react@18.2.0): + resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + tslib: 2.6.2 + dev: false + /@emotion/babel-plugin@11.11.0: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: @@ -381,7 +469,6 @@ packages: /@emotion/memoize@0.7.4: resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} - requiresBuild: true dev: false optional: true @@ -389,7 +476,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.1(@types/react@18.2.33)(react@18.2.0): + /@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' @@ -405,7 +492,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.33 + '@types/react': 18.2.15 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -424,7 +511,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0): + /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -437,11 +524,11 @@ packages: '@babel/runtime': 7.23.2 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) '@emotion/serialize': 1.1.2 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.33 + '@types/react': 18.2.15 react: 18.2.0 dev: false @@ -663,13 +750,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.45.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.52.0 + eslint: 8.45.0 eslint-visitor-keys: 3.4.3 dev: true @@ -678,8 +765,8 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -695,8 +782,8 @@ packages: - supports-color dev: true - /@eslint/js@8.52.0: - resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} + /@eslint/js@8.44.0: + resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -713,8 +800,8 @@ packages: '@floating-ui/utils': 0.1.6 dev: false - /@floating-ui/react-dom@2.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==} + /@floating-ui/react-dom@2.0.4(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -728,6 +815,49 @@ packages: resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} dev: false + /@fullcalendar/core@6.1.9: + resolution: {integrity: sha512-eeG+z9BWerdsU9Ac6j16rpYpPnE0wxtnEHiHrh/u/ADbGTR3hCOjCD9PxQOfhOTHbWOVs7JQunGcksSPu5WZBQ==} + dependencies: + preact: 10.12.1 + dev: false + + /@fullcalendar/daygrid@6.1.9(@fullcalendar/core@6.1.9): + resolution: {integrity: sha512-o/6joH/7lmVHXAkbaa/tUbzWYnGp/LgfdiFyYPkqQbjKEeivNZWF1WhHqFbhx0zbFONSHtrvkjY2bjr+Ef2quQ==} + peerDependencies: + '@fullcalendar/core': ~6.1.9 + dependencies: + '@fullcalendar/core': 6.1.9 + dev: false + + /@fullcalendar/interaction@6.1.9(@fullcalendar/core@6.1.9): + resolution: {integrity: sha512-I3FGnv0kKZpIwujg3HllbKrciNjTqeTYy3oJG226oAn7lV6wnrrDYMmuGmA0jPJAGN46HKrQqKN7ItxQRDec4Q==} + peerDependencies: + '@fullcalendar/core': ~6.1.9 + dependencies: + '@fullcalendar/core': 6.1.9 + dev: false + + /@fullcalendar/react@6.1.9(@fullcalendar/core@6.1.9)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ioxu0V++pYz2u/N1LL1V8DkMyiKGRun0gMAll2tQz3Kzi3r9pTwncGKRb1zO8h0e+TrInU08ywk/l5lBwp7eog==} + peerDependencies: + '@fullcalendar/core': ~6.1.9 + react: ^16.7.0 || ^17 || ^18 + react-dom: ^16.7.0 || ^17 || ^18 + dependencies: + '@fullcalendar/core': 6.1.9 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@fullcalendar/timegrid@6.1.9(@fullcalendar/core@6.1.9): + resolution: {integrity: sha512-le7UV05wVE1Trdr054kgJXTwa+A1pEI8nlCBnPWdcyrL+dTLoPvQ4AWEVCnV7So+4zRYaCqnqGXfCJsj0RQa0g==} + peerDependencies: + '@fullcalendar/core': ~6.1.9 + dependencies: + '@fullcalendar/core': 6.1.9 + '@fullcalendar/daygrid': 6.1.9(@fullcalendar/core@6.1.9) + dev: false + /@humanwhocodes/config-array@0.11.13: resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} @@ -778,7 +908,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@mui/base@5.0.0-beta.21(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): + /@mui/base@5.0.0-beta.21(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-eTKWx3WV/nwmRUK4z4K1MzlMyWCsi3WJ3RtV4DiXZeRh4qd4JCyp1Zzzi8Wv9xM4dEBmqQntFoei716PzwmFfA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -790,22 +920,22 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@floating-ui/react-dom': 2.0.2(react-dom@18.2.0)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) + '@floating-ui/react-dom': 2.0.4(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.8(@types/react@18.2.15) + '@mui/utils': 5.14.17(@types/react@18.2.15)(react@18.2.0) '@popperjs/core': 2.11.8 - '@types/react': 18.2.33 + '@types/react': 18.2.15 clsx: 2.0.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/core-downloads-tracker@5.14.15: - resolution: {integrity: sha512-ZCDzBWtCKjAYAlKKM3PA/jG/3uVIDT9ZitOtVixIVmTCQyc5jSV1qhJX8+qIGz4RQZ9KLzPWO2tXd0O5hvzouQ==} + /@mui/core-downloads-tracker@5.14.17: + resolution: {integrity: sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ==} dev: false - /@mui/icons-material@5.14.15(@mui/material@5.14.15)(@types/react@18.2.33)(react@18.2.0): + /@mui/icons-material@5.14.15(@mui/material@5.14.15)(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-Dqu21vN/mVNzebJ+ofnKG+CeJYIhHuDs5+0fMEpdpzRt6UojelzdrEkNv+XkO0e1JMclzeXIRx404FirK/CFRw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -817,12 +947,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@mui/material': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.33 + '@mui/material': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.15 react: 18.2.0 dev: false - /@mui/material@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): + /@mui/material@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Gq65rHjvLzkxmhG8bvag851Oqsmru7qkUb/cCI2xu7dQzmY345f9xJRJi72sRGjhaqHXWeRKw/yIwp/7oQoeXg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -840,15 +970,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) - '@mui/base': 5.0.0-beta.21(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) - '@mui/core-downloads-tracker': 5.14.15 - '@mui/system': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 - '@types/react-transition-group': 4.4.8 + '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) + '@mui/base': 5.0.0-beta.21(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.14.17 + '@mui/system': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react@18.2.0) + '@mui/types': 7.2.8(@types/react@18.2.15) + '@mui/utils': 5.14.17(@types/react@18.2.15)(react@18.2.0) + '@types/react': 18.2.15 + '@types/react-transition-group': 4.4.9 clsx: 2.0.0 csstype: 3.1.2 prop-types: 15.8.1 @@ -858,8 +988,8 @@ packages: react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@mui/private-theming@5.14.15(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-V2Xh+Tu6A07NoSpup0P9m29GwvNMYl5DegsGWqlOTJyAV7cuuVjmVPqxgvL8xBng4R85xqIQJRMjtYYktoPNuQ==} + /@mui/private-theming@5.14.17(@types/react@18.2.15)(react@18.2.0): + resolution: {integrity: sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -869,14 +999,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 + '@mui/utils': 5.14.17(@types/react@18.2.15)(react@18.2.0) + '@types/react': 18.2.15 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): - resolution: {integrity: sha512-mbOjRf867BysNpexe5Z/P8s3bWzDPNowmKhi7gtNDP/LPEeqAfiDSuC4WPTXmtvse1dCl30Nl755OLUYuoi7Mw==} + /@mui/styled-engine@5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): + resolution: {integrity: sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -890,14 +1020,14 @@ packages: dependencies: '@babel/runtime': 7.23.2 '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react@18.2.0): + /@mui/system@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-zr0Gdk1RgKiEk+tCMB900LaOpEC8NaGvxtkmMdL/CXgkqQZSVZOt2PQsxJWaw7kE4YVkIe4VukFVc43qcq9u3w==} engines: {node: '>=12.0.0'} peerDependencies: @@ -914,32 +1044,32 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) - '@mui/private-theming': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@mui/styled-engine': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 + '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.15)(react@18.2.0) + '@mui/private-theming': 5.14.17(@types/react@18.2.15)(react@18.2.0) + '@mui/styled-engine': 5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) + '@mui/types': 7.2.8(@types/react@18.2.15) + '@mui/utils': 5.14.17(@types/react@18.2.15)(react@18.2.0) + '@types/react': 18.2.15 clsx: 2.0.0 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.7(@types/react@18.2.33): - resolution: {integrity: sha512-sofpWmcBqOlTzRbr1cLQuUDKaUYVZTw8ENQrtL39TECRNENEzwgnNPh6WMfqMZlMvf1Aj9DLg74XPjnLr0izUQ==} + /@mui/types@7.2.8(@types/react@18.2.15): + resolution: {integrity: sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.15 dev: false - /@mui/utils@5.14.15(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-QBfHovAvTa0J1jXuYDaXGk+Yyp7+Fm8GSqx6nK2JbezGqzCFfirNdop/+bL9Flh/OQ/64PeXcW4HGDdOge+n3A==} + /@mui/utils@5.14.17(@types/react@18.2.15)(react@18.2.0): + resolution: {integrity: sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -949,8 +1079,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.9 - '@types/react': 18.2.33 + '@types/prop-types': 15.7.10 + '@types/react': 18.2.15 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 @@ -981,8 +1111,8 @@ packages: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} dev: false - /@react-aria/ssr@3.8.0(react@18.2.0): - resolution: {integrity: sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A==} + /@react-aria/ssr@3.9.0(react@18.2.0): + resolution: {integrity: sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg==} engines: {node: '>= 12'} peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 @@ -1023,9 +1153,9 @@ packages: dependencies: '@babel/runtime': 7.23.2 '@popperjs/core': 2.11.8 - '@react-aria/ssr': 3.8.0(react@18.2.0) + '@react-aria/ssr': 3.9.0(react@18.2.0) '@restart/hooks': 0.4.11(react@18.2.0) - '@types/warning': 3.0.2 + '@types/warning': 3.0.3 dequal: 2.0.3 dom-helpers: 5.2.1 react: 18.2.0 @@ -1040,6 +1170,111 @@ packages: tslib: 2.6.2 dev: false + /@syncfusion/ej2-base@23.1.41: + resolution: {integrity: sha512-ROtvuLIVkKl4eL+ubQjQQLleRMY98nYlxlBaFw4axtiDLoBbzOYtiFXmdP/KE+uNrMquZAwl+aduPX0loG3EAw==} + hasBin: true + dependencies: + '@syncfusion/ej2-icons': 23.1.36 + dev: false + + /@syncfusion/ej2-buttons@23.1.43: + resolution: {integrity: sha512-Jg1cC/2o6ds+xDwQSlAF7cEYP4O4C9wojKFllcVvZTwTKWVxZ2KfYeAFM1kV1GR/WuJd+TmvNhwkvmkWz8UgQw==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + dev: false + + /@syncfusion/ej2-data@23.1.44: + resolution: {integrity: sha512-ZtWVsKcmCLPxFTMkvddre8/hMJaX6A6moR9NAsX332JanefWYs0GdyhE8tTRtzSZV8QcItVq/u4B77W5kNxQDg==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + dev: false + + /@syncfusion/ej2-dropdowns@23.1.44: + resolution: {integrity: sha512-sauj4akvZm6odnKJqcOdKcfoCiCBB/S6byyBJhLxjeK/MRun2c6oYiG+/SwYfWkF4HSaOiO1+S0sBn6/ISagXA==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-data': 23.1.44 + '@syncfusion/ej2-inputs': 23.1.43 + '@syncfusion/ej2-lists': 23.1.43 + '@syncfusion/ej2-navigations': 23.1.44 + '@syncfusion/ej2-notifications': 23.1.40 + '@syncfusion/ej2-popups': 23.1.44 + dev: false + + /@syncfusion/ej2-icons@23.1.36: + resolution: {integrity: sha512-Q7S50bOzXL9X46doNIGSGr61RCY/1RW9iz1U7yyARr2XBQhWnijk+t/FVBk1piR0nioRXbKQcPZOLiEo6zf1xw==} + dev: false + + /@syncfusion/ej2-inputs@23.1.43: + resolution: {integrity: sha512-G4HhneF2HXe6Tcig5pDlTaEgR46vQJgshcEym6WEVm0G39xiUSR5NIvyvS54IldGRyWwoyWEucbpM1kWGJC+7g==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + '@syncfusion/ej2-popups': 23.1.44 + '@syncfusion/ej2-splitbuttons': 23.1.43 + dev: false + + /@syncfusion/ej2-kanban@23.1.36: + resolution: {integrity: sha512-qkp7ZS+o40I9oWj/lDJ4D20ygsOuDmjJ1CEkpz2xQgzXuHcA+/89OGeKS8WGFtK2uPSl+U2ub2PdopXF4OqL+w==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + '@syncfusion/ej2-data': 23.1.44 + '@syncfusion/ej2-dropdowns': 23.1.44 + '@syncfusion/ej2-inputs': 23.1.43 + '@syncfusion/ej2-layouts': 23.1.36 + '@syncfusion/ej2-navigations': 23.1.44 + '@syncfusion/ej2-notifications': 23.1.40 + '@syncfusion/ej2-popups': 23.1.44 + dev: false + + /@syncfusion/ej2-layouts@23.1.36: + resolution: {integrity: sha512-vS1KpUxLcrFNjRgkaotWWMmja9x1XjY06r70P/1JbxT66oJZwv5YRfBBqT1rFeYEWUGm0ciMEMehyTsPE3Pefw==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + dev: false + + /@syncfusion/ej2-lists@23.1.43: + resolution: {integrity: sha512-AoEpXn7F8AmXq74PmGCqQjURHnriyhimVreenDWrB1HlMUPcAw7Lkep4gYQdJXYyfWlT+GE+lr6lfS7hgAFT+A==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + '@syncfusion/ej2-data': 23.1.44 + dev: false + + /@syncfusion/ej2-navigations@23.1.44: + resolution: {integrity: sha512-tozVXbGc18oJjUbJS6CWKSuSGELGHAp6hWtVwUSNJjAAwxEsb7MitU5V5gSHW5x5dfJrx2d6W1nO4XM5YH30pw==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + '@syncfusion/ej2-data': 23.1.44 + '@syncfusion/ej2-inputs': 23.1.43 + '@syncfusion/ej2-lists': 23.1.43 + '@syncfusion/ej2-popups': 23.1.44 + dev: false + + /@syncfusion/ej2-notifications@23.1.40: + resolution: {integrity: sha512-xB0U/THNVQN09AK+5DV6f9e7YbvWi5UqhdObCdpZarAMOFUEZBtAIVQRxc1LrINRmRapGU7NMFQj1F1xU7DVyw==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + '@syncfusion/ej2-popups': 23.1.44 + dev: false + + /@syncfusion/ej2-popups@23.1.44: + resolution: {integrity: sha512-iMALjAv02515xD5fdLAb2SPs5q1KbQ5Q1QPrE066Hqwo/ynoCIfzw9unTFK+TKvldonGOMCIWxVcjJ+USn/TGw==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-buttons': 23.1.43 + dev: false + + /@syncfusion/ej2-splitbuttons@23.1.43: + resolution: {integrity: sha512-NbT5XMCU87QPRr4svcEn/zEwIFAmwZiAYYLz2WjiuKVOnFw6htAKT81FF7X4CLl4HN0o1S7w09N9r5HQxv3mgQ==} + dependencies: + '@syncfusion/ej2-base': 23.1.41 + '@syncfusion/ej2-popups': 23.1.44 + dev: false + /@tailwindcss/typography@0.5.10(tailwindcss@3.3.5): resolution: {integrity: sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==} peerDependencies: @@ -1052,98 +1287,80 @@ packages: tailwindcss: 3.3.5 dev: true - /@types/babel__core@7.20.3: - resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==} + /@types/hoist-non-react-statics@3.3.5: + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} dependencies: - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - '@types/babel__generator': 7.6.6 - '@types/babel__template': 7.4.3 - '@types/babel__traverse': 7.20.3 - dev: true - - /@types/babel__generator@7.6.6: - resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==} - dependencies: - '@babel/types': 7.23.0 - dev: true - - /@types/babel__template@7.4.3: - resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==} - dependencies: - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - dev: true - - /@types/babel__traverse@7.20.3: - resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==} - dependencies: - '@babel/types': 7.23.0 - dev: true - - /@types/parse-json@4.0.1: - resolution: {integrity: sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng==} + '@types/react': 18.2.15 + hoist-non-react-statics: 3.3.2 dev: false - /@types/prop-types@15.7.9: - resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} - - /@types/react-dom@18.2.14: - resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} - dependencies: - '@types/react': 18.2.33 - dev: true - - /@types/react-transition-group@4.4.8: - resolution: {integrity: sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==} - dependencies: - '@types/react': 18.2.33 + /@types/parse-json@4.0.2: + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} dev: false - /@types/react@18.2.33: - resolution: {integrity: sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==} + /@types/prop-types@15.7.10: + resolution: {integrity: sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==} + + /@types/react-dom@18.2.7: + resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} dependencies: - '@types/prop-types': 15.7.9 - '@types/scheduler': 0.16.5 + '@types/react': 18.2.15 + dev: true + + /@types/react-redux@7.1.30: + resolution: {integrity: sha512-i2kqM6YaUwFKduamV6QM/uHbb0eCP8f8ZQ/0yWf+BsAVVsZPRYJ9eeGWZ3uxLfWwwA0SrPRMTPTqsPFkY3HZdA==} + dependencies: + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.2.15 + hoist-non-react-statics: 3.3.2 + redux: 4.2.1 + dev: false + + /@types/react-transition-group@4.4.9: + resolution: {integrity: sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==} + dependencies: + '@types/react': 18.2.15 + dev: false + + /@types/react@18.2.15: + resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} + dependencies: + '@types/prop-types': 15.7.10 + '@types/scheduler': 0.16.6 csstype: 3.1.2 - /@types/scheduler@0.16.5: - resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} + /@types/scheduler@0.16.6: + resolution: {integrity: sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==} - /@types/warning@3.0.2: - resolution: {integrity: sha512-S/2+OjBIcBl8Kur23YLe0hG1e7J5m2bHfB4UuMNoLZjIFhQWhTf1FeS+WFoXHUC6QsCEfk4pftj4J1KIKC1glA==} + /@types/warning@3.0.3: + resolution: {integrity: sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==} dev: false - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true - - /@vitejs/plugin-react@4.1.0(vite@4.5.0): - resolution: {integrity: sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==} + /@vitejs/plugin-react@4.0.3(vite@4.4.5): + resolution: {integrity: sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 dependencies: - '@babel/core': 7.23.2 - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.2) - '@types/babel__core': 7.20.3 + '@babel/core': 7.23.3 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.3) react-refresh: 0.14.0 - vite: 4.5.0 + vite: 4.4.5 transitivePeerDependencies: - supports-color dev: true - /acorn-jsx@5.3.2(acorn@8.10.0): + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.10.0 + acorn: 8.11.2 dev: true - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -1256,12 +1473,6 @@ packages: is-shared-array-buffer: 1.0.2 dev: true - /asynciterator.prototype@1.0.0: - resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} - dependencies: - has-symbols: 1.0.3 - dev: true - /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false @@ -1274,7 +1485,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.22.1 - caniuse-lite: 1.0.30001554 + caniuse-lite: 1.0.30001561 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1342,8 +1553,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001554 - electron-to-chromium: 1.4.567 + caniuse-lite: 1.0.30001561 + electron-to-chromium: 1.4.580 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) dev: true @@ -1365,8 +1576,8 @@ packages: engines: {node: '>= 6'} dev: true - /caniuse-lite@1.0.30001554: - resolution: {integrity: sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==} + /caniuse-lite@1.0.30001561: + resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} dev: true /chalk@2.4.2: @@ -1460,7 +1671,7 @@ packages: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} dependencies: - '@types/parse-json': 4.0.1 + '@types/parse-json': 4.0.2 import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 @@ -1476,6 +1687,12 @@ packages: which: 2.0.2 dev: true + /css-box-model@1.2.1: + resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} + dependencies: + tiny-invariant: 1.3.1 + dev: false + /css-selector-tokenizer@0.8.0: resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==} dependencies: @@ -1583,8 +1800,8 @@ packages: engines: {node: '>=12'} dev: false - /electron-to-chromium@1.4.567: - resolution: {integrity: sha512-8KR114CAYQ4/r5EIEsOmOMqQ9j0MRbJZR3aXD/KFA8RuKzyoUB4XrUCg+l8RUGqTVQgKNIgTpjaG8YHRPAbX2w==} + /electron-to-chromium@1.4.580: + resolution: {integrity: sha512-T5q3pjQon853xxxHUq3ZP68ZpvJHuSMY2+BZaW3QzjS4HvNuvsMmZ/+lU+nCrftre1jFZ+OSlExynXWBihnXzw==} dev: true /error-ex@1.3.2: @@ -1638,25 +1855,6 @@ packages: which-typed-array: 1.1.13 dev: true - /es-iterator-helpers@1.0.15: - resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} - dependencies: - asynciterator.prototype: 1.0.0 - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - es-set-tostringtag: 2.0.2 - function-bind: 1.1.2 - get-intrinsic: 1.2.2 - globalthis: 1.0.3 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.6 - iterator.prototype: 1.1.2 - safe-array-concat: 1.0.1 - dev: true - /es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} @@ -1724,25 +1922,25 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-plugin-react-hooks@4.6.0(eslint@8.52.0): + /eslint-plugin-react-hooks@4.6.0(eslint@8.45.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.52.0 + eslint: 8.45.0 dev: true - /eslint-plugin-react-refresh@0.4.3(eslint@8.52.0): + /eslint-plugin-react-refresh@0.4.3(eslint@8.45.0): resolution: {integrity: sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==} peerDependencies: eslint: '>=7' dependencies: - eslint: 8.52.0 + eslint: 8.45.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.52.0): - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + /eslint-plugin-react@7.32.2(eslint@8.45.0): + resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 @@ -1751,8 +1949,7 @@ packages: array.prototype.flatmap: 1.3.2 array.prototype.tosorted: 1.1.2 doctrine: 2.1.0 - es-iterator-helpers: 1.0.15 - eslint: 8.52.0 + eslint: 8.45.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -1779,19 +1976,18 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.52.0: - resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + /eslint@8.45.0: + resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.52.0 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.44.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 @@ -1830,8 +2026,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) eslint-visitor-keys: 3.4.3 dev: true @@ -1863,8 +2059,8 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2201,13 +2397,6 @@ packages: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: false - /is-async-function@2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -2251,19 +2440,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-finalizationregistry@1.0.2: - resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} - dependencies: - call-bind: 1.0.5 - dev: true - - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2271,10 +2447,6 @@ packages: is-extglob: 2.1.1 dev: true - /is-map@2.0.2: - resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} - dev: true - /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -2305,10 +2477,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-set@2.0.2: - resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} - dev: true - /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: @@ -2336,23 +2504,12 @@ packages: which-typed-array: 1.1.13 dev: true - /is-weakmap@2.0.1: - resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} - dev: true - /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.5 dev: true - /is-weakset@2.0.2: - resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - dev: true - /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} dev: true @@ -2361,18 +2518,8 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} - dependencies: - define-properties: 1.2.1 - get-intrinsic: 1.2.2 - has-symbols: 1.0.3 - reflect.getprototypeof: 1.0.4 - set-function-name: 2.0.1 - dev: true - - /jiti@1.20.0: - resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true dev: true @@ -2482,6 +2629,10 @@ packages: yallist: 3.1.1 dev: true + /memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + dev: false + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2525,8 +2676,8 @@ packages: thenify-all: 1.6.0 dev: true - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true @@ -2737,7 +2888,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.31 - yaml: 2.3.3 + yaml: 2.3.4 dev: true /postcss-nested@6.0.1(postcss@8.4.31): @@ -2774,11 +2925,15 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true + /preact@10.12.1: + resolution: {integrity: sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==} + dev: false + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2805,8 +2960,8 @@ packages: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true @@ -2814,7 +2969,30 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true - /react-bootstrap@2.9.1(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): + /raf-schd@4.0.3: + resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} + dev: false + + /react-beautiful-dnd@13.1.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==} + peerDependencies: + react: ^16.8.5 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.23.2 + css-box-model: 1.2.1 + memoize-one: 5.2.1 + raf-schd: 4.0.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-redux: 7.2.9(react-dom@18.2.0)(react@18.2.0) + redux: 4.2.1 + use-memo-one: 1.1.3(react@18.2.0) + transitivePeerDependencies: + - react-native + dev: false + + /react-bootstrap@2.9.1(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==} peerDependencies: '@types/react': '>=16.14.8' @@ -2827,8 +3005,8 @@ packages: '@babel/runtime': 7.23.2 '@restart/hooks': 0.4.11(react@18.2.0) '@restart/ui': 1.6.6(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.33 - '@types/react-transition-group': 4.4.8 + '@types/react': 18.2.15 + '@types/react-transition-group': 4.4.9 classnames: 2.3.2 dom-helpers: 5.2.1 invariant: 2.2.4 @@ -2862,6 +3040,10 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: false + /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false @@ -2870,6 +3052,28 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: false + /react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} + peerDependencies: + react: ^16.8.3 || ^17 || ^18 + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.23.2 + '@types/react-redux': 7.1.30 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 17.0.2 + dev: false + /react-refresh@0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} @@ -2932,17 +3136,11 @@ packages: picomatch: 2.3.1 dev: true - /reflect.getprototypeof@1.0.4: - resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} - engines: {node: '>= 0.4'} + /redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - globalthis: 1.0.3 - which-builtin-type: 1.1.3 - dev: true + '@babel/runtime': 7.23.2 + dev: false /regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} @@ -3178,10 +3376,10 @@ packages: chokidar: 3.5.3 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 glob-parent: 6.0.2 is-glob: 4.0.3 - jiti: 1.20.0 + jiti: 1.21.0 lilconfig: 2.1.0 micromatch: 4.0.5 normalize-path: 3.0.0 @@ -3216,6 +3414,10 @@ packages: any-promise: 1.3.0 dev: true + /tiny-invariant@1.3.1: + resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + dev: false + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -3300,7 +3502,7 @@ packages: react: '>=15.0.0' dependencies: '@babel/runtime': 7.23.2 - '@types/react': 18.2.33 + '@types/react': 18.2.15 invariant: 2.2.4 react: 18.2.0 react-lifecycles-compat: 3.0.4 @@ -3328,15 +3530,23 @@ packages: /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true + /use-memo-one@1.1.3(react@18.2.0): + resolution: {integrity: sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true - /vite@4.5.0: - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} + /vite@4.4.5: + resolution: {integrity: sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -3386,33 +3596,6 @@ packages: is-symbol: 1.0.4 dev: true - /which-builtin-type@1.1.3: - resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} - engines: {node: '>= 0.4'} - dependencies: - function.prototype.name: 1.1.6 - has-tostringtag: 1.0.0 - is-async-function: 2.0.0 - is-date-object: 1.0.5 - is-finalizationregistry: 1.0.2 - is-generator-function: 1.0.10 - is-regex: 1.1.4 - is-weakref: 1.0.2 - isarray: 2.0.5 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.13 - dev: true - - /which-collection@1.0.1: - resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} - dependencies: - is-map: 2.0.2 - is-set: 2.0.2 - is-weakmap: 2.0.1 - is-weakset: 2.0.2 - dev: true - /which-typed-array@1.1.13: resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} @@ -3445,8 +3628,8 @@ packages: engines: {node: '>= 6'} dev: false - /yaml@2.3.3: - resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} engines: {node: '>= 14'} dev: true diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e9bb13b..e3b7829 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,28 +1,38 @@ import './App.css'; -import { BrowserRouter, Route, Routes, Link } from 'react-router-dom'; +import { BrowserRouter, Route, Routes } from 'react-router-dom'; import TestAuth from './components/testAuth'; import LoginPage from './components/authentication/LoginPage'; import SignUpPage from './components/authentication/SignUpPage'; -import NavBar from './components/Nav/Navbar'; +import NavBar from './components/nav/Navbar'; import Home from './components/Home'; -import ProfileUpdate from './components/ProfileUpdatePage' +import ProfileUpdate from './components/ProfileUpdatePage'; +import Calendar from './components/calendar/calendar'; +import KanbanBoard from './components/kanbanBoard/kanbanBoard'; +import IconSideNav from './components/IconSideNav'; // Import IconSideNav const App = () => { return ( -
- +
+ +
+ +
- }/> - }/> - }/> - }/> - }/> + } /> + } /> + } /> + } /> + } /> + } /> + } /> -
+
+
+
); } -export default App; \ No newline at end of file +export default App; diff --git a/frontend/src/api/axiosapi.jsx b/frontend/src/api/AuthenticationApi.jsx similarity index 100% rename from frontend/src/api/axiosapi.jsx rename to frontend/src/api/AuthenticationApi.jsx diff --git a/frontend/src/api/TaskApi.jsx b/frontend/src/api/TaskApi.jsx new file mode 100644 index 0000000..e56662b --- /dev/null +++ b/frontend/src/api/TaskApi.jsx @@ -0,0 +1,23 @@ +import axios from 'axios'; + +// Create an Axios instance with common configurations +const axiosInstance = axios.create({ + baseURL: 'http://127.0.0.1:8000/api/', + timeout: 5000, + headers: { + 'Authorization': "Bearer " + localStorage.getItem('access_token'), + 'Content-Type': 'application/json', + 'accept': 'application/json', + } +}); + +export const fetchTodoTasks = () => { + return axiosInstance + .get('todo/') + .then((response) => { + return response.data; + }) + .catch(error => { + throw error; + }); +}; \ No newline at end of file diff --git a/frontend/src/components/IconSideNav.jsx b/frontend/src/components/IconSideNav.jsx index 4ed357c..c87219c 100644 --- a/frontend/src/components/IconSideNav.jsx +++ b/frontend/src/components/IconSideNav.jsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { AnimatePresence, motion } from "framer-motion"; -import { SiFramer, SiTailwindcss, SiReact, SiJavascript, SiCss3 } from "react-icons/si"; +import { Link, useNavigate } from "react-router-dom"; import homeLogo from "../assets/home.png"; import calendarLogo from "../assets/calendar.png"; import planLogo from "../assets/planning.png"; @@ -8,18 +8,17 @@ import pieLogo from "../assets/pie-chart.png"; import plusLogo from "../assets/plus.png"; const menuItems = [ - { id: 0, icon: , logo: homeLogo }, - { id: 1, icon: , logo: calendarLogo }, - { id: 2, icon: , logo: planLogo }, - { id: 3, icon: , logo: pieLogo }, - { id: 4, icon: , logo: plusLogo }, + { id: 0, path: "/", icon: , logo: homeLogo }, + { id: 1, path: "/tasks", icon: , logo: planLogo }, + { id: 2, path: "/calendar", icon: , logo: calendarLogo }, + { id: 3, path: "/pie", icon: , logo: pieLogo }, + { id: 4, path: "/plus", icon: , logo: plusLogo }, ]; const IconSideNav = () => { return (
-
); }; @@ -28,7 +27,7 @@ const SideNav = () => { const [selected, setSelected] = useState(0); return ( -