Files
RosterChief/mobile/urls.py
Bernard Siebens e211584696 Add Coach mode C5: post news, reusing the desktop's own NewsForm
management.forms.NewsForm defaults its teams field to every club team --
fine for an editor/admin, but a real gap for a coach, who should only ever
post as their own team, never "on behalf of" one they don't run. Re-scoped
to teams_managed_by via self.managed_teams, and made required (a coach's
post is always team-scoped, never empty/club-wide -- that stays an
editor/admin claim).

Gated with club.services.access.can_add_news, which already includes
is_coach_manager. On submit the post goes straight to
News.submit_for_review() plus the same notify_editors_of_pending_review
call the desktop's own NewsSubmitForReviewView makes, landing in an
editor's queue instead of a silent draft. The button reads "Send" rather
than the mock's "Publish" -- can_publish_news stays editor/admin-only, so
that's the honest description of what actually happens.

visibility is left at the model's own INTERNAL default rather than
building the mock's "also on club website" toggle -- an editor reviewing
the pending post can widen it before publishing if a public-site
placement is actually warranted; that's a real gate, not a decorative
row, so it isn't reproduced as one here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
2026-08-21 22:32:44 +02:00

31 lines
1.7 KiB
Python

from django.urls import path
from . import coach_views, views
app_name = "mobile"
urlpatterns = [
# PWA plumbing.
path("manifest.webmanifest", views.ManifestView.as_view(), name="manifest"),
path("sw.js", views.ServiceWorkerView.as_view(), name="service_worker"),
path("icon/<int:size>.png", views.AppIconView.as_view(), name="icon"),
path("push/subscribe/", views.PushSubscribeView.as_view(), name="push_subscribe"),
path("calendar/<str:token>.ics", views.CalendarFeedView.as_view(), name="calendar_feed"),
# Member mode (M1-M7).
path("", views.HomeView.as_view(), name="home"),
path("calendar/", views.CalendarView.as_view(), name="calendar"),
path("events/<uuid:pk>/", views.EventDetailView.as_view(), name="event_detail"),
path("news/", views.NewsListView.as_view(), name="news_list"),
path("news/<slug:slug>/", views.NewsDetailView.as_view(), name="news_detail"),
path("me/", views.MeView.as_view(), name="me"),
path("me/payments/", views.PaymentsView.as_view(), name="payments"),
path("me/calendar-sync/", views.CalendarFeedSettingsView.as_view(), name="calendar_feed_settings"),
path("me/<uuid:member_id>/edit/", views.EditProfileView.as_view(), name="edit_profile"),
path("notifications/", views.NotificationsView.as_view(), name="notifications"),
# Coach mode (C1-C6).
path("coach/", coach_views.CoachTodayView.as_view(), name="coach_today"),
path("coach/attendance/<uuid:event_id>/", coach_views.CoachAttendanceView.as_view(), name="coach_attendance"),
path("coach/events/new/", coach_views.CoachCreateEventView.as_view(), name="coach_create_event"),
path("coach/news/new/", coach_views.CoachCreateNewsView.as_view(), name="coach_create_news"),
]