Scaffold the mobile member app: PWA shell, push, and app-shell tokens
New `mobile` Django app mounted at /app/ -- the installed PWA for Member mode (M1-M7, see design_handoff_rosterchief_platform/README.md). Coach mode (C1-C6) is a later phase and has no routes yet. Foundation pieces: - assets/mobile.css: Tailwind v4 theme reusing management.css's design tokens (same per-club --tenant-* theming pattern), plus the ice/coach accent and mobile's 14px card radius. - PushSubscription model + pywebpush-based sender (mobile/services/push.py), wired to notifications.Notification via a post_save signal so the existing notification system gains a push channel without knowing about PWAs itself. - Per-club manifest.webmanifest + service worker (served at /app/sw.js) + a server-rendered fallback home-screen icon (club initials on secondary_color) for clubs without an uploaded logo -- confirmed with the user as the fallback, never a generic RosterChief mark. - App shell (base.html): navy header, person switcher (every child a signed-in parent manages, plus "Me"), bottom tab bar, safe-area insets. Vendored htmx + Alpine for the screens built on top of it. - Placeholder views/routes for all seven M1-M7 screens so the shell is fully wired end-to-end before each screen is built out individually. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -78,8 +78,11 @@ INSTALLED_APPS = [
|
||||
"features.apps.FeaturesConfig",
|
||||
"controlpanel.apps.ControlpanelConfig",
|
||||
# Club-facing UI for team managers, coaches and admins -- not controlpanel (platform
|
||||
# staff managing every club) and not the future parent/player app.
|
||||
# staff managing every club) and not the mobile member/parent app below.
|
||||
"management.apps.ManagementConfig",
|
||||
# The installed PWA -- Member mode first (see design_handoff_rosterchief_platform/
|
||||
# README.md); Coach mode is a later phase, deliberately not built yet.
|
||||
"mobile.apps.MobileConfig",
|
||||
# Public, read-only JSON API for a club's own external website -- see api/urls.py.
|
||||
"api.apps.ApiConfig",
|
||||
]
|
||||
@@ -418,6 +421,15 @@ SERVER_EMAIL = config("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL)
|
||||
#: Where a club admin is told to direct a billing question. Shown in reminder emails.
|
||||
BILLING_CONTACT_EMAIL = config("ROSTERCHIEF_BILLING_CONTACT_EMAIL", default=DEFAULT_FROM_EMAIL)
|
||||
|
||||
# Web Push (mobile app, see mobile/services/push.py) -- one VAPID keypair for the whole
|
||||
# platform, not per club: it identifies the *sender* (RosterChief) to a browser's push
|
||||
# service, the same way DEFAULT_FROM_EMAIL identifies the sender of an email, and has
|
||||
# nothing to do with club branding. Generate a pair with `uv run vapid --gen`. Blank in
|
||||
# dev is fine -- mobile.services.push.send_push_to_member no-ops without a private key.
|
||||
VAPID_PUBLIC_KEY = config("DJANGO_VAPID_PUBLIC_KEY", default="")
|
||||
VAPID_PRIVATE_KEY = config("DJANGO_VAPID_PRIVATE_KEY", default="")
|
||||
VAPID_ADMIN_EMAIL = config("DJANGO_VAPID_ADMIN_EMAIL", default="admin@rosterchief.app")
|
||||
|
||||
|
||||
# Phone numbers (django-phonenumber-field)
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ urlpatterns = [
|
||||
path("", include("members.urls")),
|
||||
path("controlpanel/", include("controlpanel.urls")),
|
||||
path("manage/", include("management.urls")),
|
||||
path("app/", include("mobile.urls")),
|
||||
path("api/v1/", api.urls),
|
||||
# "/" resolves per tenant: a club subdomain lands on the club, the base domain
|
||||
# hands off to the control panel. This is why LOGIN_REDIRECT_URL can stay "/".
|
||||
|
||||
Reference in New Issue
Block a user