diff --git a/accounts/__pycache__/admin.cpython-313.pyc b/accounts/__pycache__/admin.cpython-313.pyc index 2cf9cb3..181458b 100644 Binary files a/accounts/__pycache__/admin.cpython-313.pyc and b/accounts/__pycache__/admin.cpython-313.pyc differ diff --git a/accounts/admin.py b/accounts/admin.py index 9d87a67..d70a4f6 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -4,10 +4,15 @@ from .models import CustomUser, AbsencePeriod class CustomUserAdmin(UserAdmin): model = CustomUser - list_display = ['email', 'username', 'team', 'is_staff'] + list_display = ['email', 'username', 'team', 'display_parents', 'is_staff'] fieldsets = UserAdmin.fieldsets + ( - (None, {'fields': ('team',)}), + (None, {'fields': ('team', 'parents')}), ) + filter_horizontal = ('parents',) + + def display_parents(self, obj): + return ", ".join([parent.username for parent in obj.parents.all()]) + display_parents.short_description = 'Parents' admin.site.register(CustomUser, CustomUserAdmin) admin.site.register(AbsencePeriod) \ No newline at end of file diff --git a/calendars/__pycache__/urls.cpython-313.pyc b/calendars/__pycache__/urls.cpython-313.pyc index 1ea891a..149e62e 100644 Binary files a/calendars/__pycache__/urls.cpython-313.pyc and b/calendars/__pycache__/urls.cpython-313.pyc differ diff --git a/calendars/__pycache__/views.cpython-313.pyc b/calendars/__pycache__/views.cpython-313.pyc index 4831890..7bacaaa 100644 Binary files a/calendars/__pycache__/views.cpython-313.pyc and b/calendars/__pycache__/views.cpython-313.pyc differ diff --git a/calendars/urls.py b/calendars/urls.py index 61df0de..873c0cb 100644 --- a/calendars/urls.py +++ b/calendars/urls.py @@ -8,4 +8,5 @@ urlpatterns = [ path('game/add/', views.GameCreateView.as_view(), name='game-add'), path('event//', views.EventUpdateView.as_view(), name='event-update'), path('event//delete/', views.EventDeleteView.as_view(), name='event-delete'), + path('participation////', views.manage_participation, name='manage-participation'), ] diff --git a/calendars/views.py b/calendars/views.py index b8f61ee..c6e113f 100644 --- a/calendars/views.py +++ b/calendars/views.py @@ -1,9 +1,11 @@ -from django.shortcuts import render +from django.shortcuts import render, get_object_or_404, redirect from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin +from django.contrib.auth.decorators import login_required from django.urls import reverse_lazy -from .models import Event, Training, Game +from .models import Event, Training, Game, EventParticipation from .forms import EventForm, TrainingForm, GameForm +from accounts.models import CustomUser # Import CustomUser for manage_participation view def select_event_type(request): return render(request, 'calendars/select_event_type.html') @@ -73,4 +75,20 @@ class EventUpdateView(LoginRequiredMixin, CoachCheckMixin, UpdateView): class EventDeleteView(LoginRequiredMixin, CoachCheckMixin, DeleteView): model = Event template_name = 'calendars/event_confirm_delete.html' - success_url = reverse_lazy('dashboard') \ No newline at end of file + success_url = reverse_lazy('dashboard') + +@login_required +def manage_participation(request, child_id, event_id, status): + child = get_object_or_404(CustomUser, id=child_id) + event = get_object_or_404(Event, id=event_id) + + # Check if the logged-in user is a parent of the child + if request.user not in child.parents.all(): + # Handle unauthorized access + return redirect('dashboard') + + participation, created = EventParticipation.objects.get_or_create(user=child, event=event) + participation.status = status + participation.save() + + return redirect('dashboard') \ No newline at end of file diff --git a/dashboard/__pycache__/views.cpython-313.pyc b/dashboard/__pycache__/views.cpython-313.pyc index dc2c99a..3470ac5 100644 Binary files a/dashboard/__pycache__/views.cpython-313.pyc and b/dashboard/__pycache__/views.cpython-313.pyc differ diff --git a/dashboard/templates/dashboard/dashboard.html b/dashboard/templates/dashboard/dashboard.html index add31ac..6956b2e 100644 --- a/dashboard/templates/dashboard/dashboard.html +++ b/dashboard/templates/dashboard/dashboard.html @@ -11,7 +11,7 @@ -

Your Team's Events

+

Your Events

{% if events %}
{% for event in events %} @@ -39,6 +39,44 @@ {% endfor %}
{% else %} -

No events found for your team.

+

No events found for you.

{% endif %} -{% endblock %} \ No newline at end of file + + {% if children_events %} +
+

Your Children's Events

+ {% for child_data in children_events %} +

{{ child_data.child.first_name }}'s Events

+ {% if child_data.events %} +
+ {% for item in child_data.events %} +
+
+
{{ item.event.title }}
+ {{ item.event.start_time|localize }} +
+

{{ item.event.description }}

+ Location: {{ item.event.location_address }} + View on Map +
+ Participation: {{ item.participation.get_status_display }} + Accept + Reject +
+
+ {% endfor %} +
+ {% else %} +

No events found for {{ child_data.child.first_name }}.

+ {% endif %} + {% endfor %} + {% endif %} +{% endblock %} diff --git a/dashboard/views.py b/dashboard/views.py index cb74037..b32cb94 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -1,30 +1,38 @@ from django.shortcuts import render from django.contrib.auth.decorators import login_required -from calendars.models import Event +from calendars.models import Event, EventParticipation from clubs.models import Team @login_required def dashboard(request): user = request.user events = [] - - # Get teams for players + children_events = [] + + # Get user's own events player_teams = [] if hasattr(user, 'team') and user.team: player_teams = [user.team] - - # Get teams for coaches coached_teams = user.coached_teams.all() assisted_teams = user.assisted_teams.all() - - # Combine all teams and remove duplicates from itertools import chain all_teams = list(set(chain(player_teams, coached_teams, assisted_teams))) - if all_teams: events = Event.objects.filter(team__in=all_teams).select_related('game', 'training').order_by('start_time') - + + # Get children's events + if hasattr(user, 'children'): + for child in user.children.all(): + child_events_list = [] + if child.team: + child_events = Event.objects.filter(team=child.team).select_related('game', 'training').order_by('start_time') + for event in child_events: + participation, created = EventParticipation.objects.get_or_create(user=child, event=event) + child_events_list.append({'event': event, 'participation': participation}) + children_events.append({'child': child, 'events': child_events_list}) + context = { 'events': events, + 'children_events': children_events, } - return render(request, 'dashboard/dashboard.html', context) \ No newline at end of file + return render(request, 'dashboard/dashboard.html', context) diff --git a/db.sqlite3 b/db.sqlite3 index dcd41b2..6630a75 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/docs/traceback/trace5.log b/docs/traceback/trace5.log new file mode 100644 index 0000000..5838bcd --- /dev/null +++ b/docs/traceback/trace5.log @@ -0,0 +1,74 @@ +/home/mnagel/Projekte/baseball_organisator/calendars/views.py changed, reloading. +Watching for file changes with StatReloader +Performing system checks... + +Exception in thread django-main-thread: +Traceback (most recent call last): + File "/usr/lib64/python3.13/threading.py", line 1043, in _bootstrap_inner + self.run() + ~~~~~~~~^^ + File "/usr/lib64/python3.13/threading.py", line 994, in run + self._target(*self._args, **self._kwargs) + ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/autoreload.py", line 64, in wrapper + fn(*args, **kwargs) + ~~^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/commands/runserver.py", line 134, in inner_run + self.check(**check_kwargs) + ~~~~~~~~~~^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/base.py", line 492, in check + all_issues = checks.run_checks( + app_configs=app_configs, + ...<2 lines>... + databases=databases, + ) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/registry.py", line 89, in run_checks + new_errors = check(app_configs=app_configs, databases=databases) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 16, in check_url_config + return check_resolver(resolver) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 26, in check_resolver + return check_method() + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 531, in check + for pattern in self.url_patterns: + ^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__ + res = instance.__dict__[self.name] = self.func(instance) + ~~~~~~~~~^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 718, in url_patterns + patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) + ^^^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__ + res = instance.__dict__[self.name] = self.func(instance) + ~~~~~~~~~^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 711, in urlconf_module + return import_module(self.urlconf_name) + File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 1387, in _gcd_import + File "", line 1360, in _find_and_load + File "", line 1331, in _find_and_load_unlocked + File "", line 935, in _load_unlocked + File "", line 1026, in exec_module + File "", line 488, in _call_with_frames_removed + File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/urls.py", line 25, in + path('calendars/', include('calendars.urls')), + ~~~~~~~^^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/conf.py", line 39, in include + urlconf_module = import_module(urlconf_module) + File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 1387, in _gcd_import + File "", line 1360, in _find_and_load + File "", line 1331, in _find_and_load_unlocked + File "", line 935, in _load_unlocked + File "", line 1026, in exec_module + File "", line 488, in _call_with_frames_removed + File "/home/mnagel/Projekte/baseball_organisator/calendars/urls.py", line 2, in + from . import views + File "/home/mnagel/Projekte/baseball_organisator/calendars/views.py", line 2, in + @login_required + ^^^^^^^^^^^^^^ +NameError: name 'login_required' is not defined +