Replace KPI/tenant wording in admin UI and help
This commit is contained in:
@@ -32,4 +32,4 @@ related:
|
|||||||
- Begrüßungstext kurz halten (1–2 Sätze).
|
- Begrüßungstext kurz halten (1–2 Sätze).
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`event-prep-checklist` für die Vorbereitung oder `tenant-dashboard-overview` für den Status.
|
Event-Vorbereitung: Checkliste für die Vorbereitung oder Event-Dashboard im Überblick für den Status.
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ related:
|
|||||||
- Mit einem Testgast den Ablauf einmal komplett durchspielen.
|
- Mit einem Testgast den Ablauf einmal komplett durchspielen.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`control-room-moderation` für die Queue oder `tenant-dashboard-overview` für Status-Checks.
|
Control Room für die Queue oder Event-Dashboard im Überblick für Status-Checks.
|
||||||
|
|||||||
@@ -32,4 +32,4 @@ related:
|
|||||||
- Bei Moderationsbedarf Auto‑Freigabe deaktivieren.
|
- Bei Moderationsbedarf Auto‑Freigabe deaktivieren.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`event-prep-checklist` für den Ablauf oder `guest-access-qr` für die Freigabe.
|
Event-Vorbereitung: Checkliste für den Ablauf oder Gästezugang & QR für die Freigabe.
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ Hier stellst du die Aufgaben zusammen, die Gäste im Event sehen und erfüllen s
|
|||||||
- 12–20 Aufgaben reichen meist aus.
|
- 12–20 Aufgaben reichen meist aus.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`event-prep-checklist` für die Vorbereitung oder `tenant-dashboard-overview` für den Status.
|
Event-Vorbereitung: Checkliste für die Vorbereitung oder Event-Dashboard im Überblick für den Status.
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ related:
|
|||||||
- Mitgliederrollen für temporäre Helfer nutzen.
|
- Mitgliederrollen für temporäre Helfer nutzen.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`event-settings` für Berechtigungen oder `tenant-dashboard-overview` für den Überblick.
|
Event-Einstellungen für Berechtigungen oder Event-Dashboard im Überblick für den Gesamtüberblick.
|
||||||
|
|||||||
@@ -28,4 +28,4 @@ related:
|
|||||||
- Link in gedruckte Einladungen integrieren.
|
- Link in gedruckte Einladungen integrieren.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`event-prep-checklist` für den kompletten Ablauf.
|
Event-Vorbereitung: Checkliste für den kompletten Ablauf.
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ related: []
|
|||||||
|
|
||||||
Dieses Portal sammelt alles, was Event-Admins für Vorbereitung, Kern-Workflows und Abschluss brauchen.
|
Dieses Portal sammelt alles, was Event-Admins für Vorbereitung, Kern-Workflows und Abschluss brauchen.
|
||||||
|
|
||||||
| Bereich | Kernfrage | Artikel-Slug |
|
| Bereich | Kernfrage | Artikel |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Dashboard | Wo sehe ich Status, KPIs und Schnellaktionen? | `tenant-dashboard-overview` |
|
| Dashboard | Wo sehe ich Status, Kennzahlen und Schnellaktionen? | Event-Dashboard im Überblick |
|
||||||
| Event-Einstellungen | Wo bearbeite ich Event-Basics und Status? | `event-settings` |
|
| Event-Einstellungen | Wo bearbeite ich Event-Basics und Status? | Event-Einstellungen |
|
||||||
| Branding | Wie lade ich Logos hoch und setze Farben? | `event-branding-assets` |
|
| Branding | Wie lade ich Logos hoch und setze Farben? | Branding & Assets |
|
||||||
| Aufgaben & Sammlungen | Wie verwalte ich Aufgaben und Prompts? | `event-tasks-setup` |
|
| Aufgaben & Sammlungen | Wie verwalte ich Aufgaben und Prompts? | Event-Aufgaben & Sammlungen |
|
||||||
| Gästezugang | Wie teile ich Join-Link oder QR? | `guest-access-qr` |
|
| Gästezugang | Wie teile ich Join-Link oder QR? | Gästezugang & QR |
|
||||||
| Team & Einladungen | Wie lade ich Helfer ein und vergebe Rollen? | `event-team-invites` |
|
| Team & Einladungen | Wie lade ich Helfer ein und vergebe Rollen? | Event-Team & Einladungen |
|
||||||
| Control Room | Wie moderiere ich Uploads und steuere die Queue? | `control-room-moderation` |
|
| Control Room | Wie moderiere ich Uploads und steuere die Queue? | Control Room: Moderation & Queue |
|
||||||
| Live Show | Wie richte ich den Live-Show-Player ein? | `live-show-setup` |
|
| Live Show | Wie richte ich den Live-Show-Player ein? | Live Show einrichten |
|
||||||
| Abrechnung & Exporte | Wo verwalte ich Pakete und Exporte? | `billing-packages-exports` |
|
| Abrechnung & Exporte | Wo verwalte ich Pakete und Exporte? | Pakete, Abrechnung & Exporte |
|
||||||
| Abschluss & Compliance | Was erledige ich nach dem Event? | `post-event-wrapup` |
|
| Abschluss & Compliance | Was erledige ich nach dem Event? | Nachbereitung & Abschluss |
|
||||||
| FAQ | Was sind die häufigsten Fragen? | `faq-admin` |
|
| FAQ | Was sind die häufigsten Fragen? | FAQ: Event-Admin |
|
||||||
|
|
||||||
Nutze das Help Center in der App für mobilfreundliches Lesen oder öffne `/help/admin` am Desktop.
|
Nutze das Help Center in der App für mobilfreundliches Lesen oder öffne `/help/admin` am Desktop.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Event-Dashboard im Überblick"
|
|||||||
locale: de
|
locale: de
|
||||||
slug: tenant-dashboard-overview
|
slug: tenant-dashboard-overview
|
||||||
audience: admin
|
audience: admin
|
||||||
summary: "Status, KPIs und Setup-Checkliste deines Events auf einen Blick."
|
summary: "Status, Kennzahlen und Setup-Checkliste deines Events auf einen Blick."
|
||||||
version_introduced: 2025.4
|
version_introduced: 2025.4
|
||||||
requires_app_version: "^3.2.0"
|
requires_app_version: "^3.2.0"
|
||||||
status: draft
|
status: draft
|
||||||
@@ -21,14 +21,14 @@ Direkt nach dem Anlegen eines Events oder als schneller Gesundheitscheck vor dem
|
|||||||
|
|
||||||
## Was das Dashboard zeigt
|
## Was das Dashboard zeigt
|
||||||
- **Event-Status** (Entwurf / Veröffentlicht), damit klar ist, was Gäste sehen.
|
- **Event-Status** (Entwurf / Veröffentlicht), damit klar ist, was Gäste sehen.
|
||||||
- **KPIs** zu Gästen, Uploads und Engagement für einen schnellen Puls-Check.
|
- **Kennzahlen** zu Gästen, Uploads und Engagement für einen schnellen Puls-Check.
|
||||||
- **Setup-Checkliste** mit den wichtigsten Restschritten bis zum Start.
|
- **Setup-Checkliste** mit den wichtigsten Restschritten bis zum Start.
|
||||||
- **Schnellaktionen** zu Aufgaben, Live Show, Branding und QR-Tools.
|
- **Schnellaktionen** zu Aufgaben, Live Show, Branding und QR-Tools.
|
||||||
|
|
||||||
## So nutzt du es
|
## So nutzt du es
|
||||||
1. **Status prüfen** und das Event bis zur Freigabe im Entwurf lassen.
|
1. **Status prüfen** und das Event bis zur Freigabe im Entwurf lassen.
|
||||||
2. **Checkliste abarbeiten** – sie bildet den typischen Vorbereitungsweg ab.
|
2. **Checkliste abarbeiten** – sie bildet den typischen Vorbereitungsweg ab.
|
||||||
3. **KPIs beobachten**, um Einladungen und Uploads zu verifizieren.
|
3. **Kennzahlen beobachten**, um Einladungen und Uploads zu verifizieren.
|
||||||
4. **Details öffnen** (Aufgaben, QR, Live Show) über die Schnellaktionen.
|
4. **Details öffnen** (Aufgaben, QR, Live Show) über die Schnellaktionen.
|
||||||
|
|
||||||
### Tipps
|
### Tipps
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ related:
|
|||||||
- Use the package shop for upgrades when needed.
|
- Use the package shop for upgrades when needed.
|
||||||
|
|
||||||
## Data exports
|
## Data exports
|
||||||
- Request a tenant‑wide or event‑specific export.
|
- Request an account‑wide or event‑specific export.
|
||||||
- Large exports can take a few minutes; refresh the list to see progress.
|
- Large exports can take a few minutes; refresh the list to see progress.
|
||||||
|
|
||||||
## Retention reminders
|
## Retention reminders
|
||||||
|
|||||||
@@ -32,4 +32,4 @@ related:
|
|||||||
- Keep welcome text short (1–2 sentences).
|
- Keep welcome text short (1–2 sentences).
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
See `event-prep-checklist` for the full prep flow or `tenant-dashboard-overview` for the status view.
|
See the Event Preparation Checklist for the full prep flow or the Event Dashboard overview for the status view.
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ related:
|
|||||||
- Use a test guest to verify the full flow end-to-end.
|
- Use a test guest to verify the full flow end-to-end.
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
Open `control-room-moderation` for queue handling or revisit `tenant-dashboard-overview` for status checks.
|
Open the Control Room article for queue handling or revisit the Event Dashboard overview for status checks.
|
||||||
|
|||||||
@@ -32,4 +32,4 @@ related:
|
|||||||
- If moderation is needed, disable auto‑approval.
|
- If moderation is needed, disable auto‑approval.
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
See `event-prep-checklist` for the full flow or `guest-access-qr` for sharing.
|
See the Event Preparation Checklist for the full flow or Guest Access & QR for sharing.
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ Use this page to shape the guest experience: tasks guide what guests should capt
|
|||||||
- Aim for 12–20 tasks per event to avoid overwhelming guests.
|
- Aim for 12–20 tasks per event to avoid overwhelming guests.
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
Open `event-prep-checklist` for the full prep flow or `tenant-dashboard-overview` for the status view.
|
Open the Event Preparation Checklist for the full prep flow or the Event Dashboard overview for status.
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ related:
|
|||||||
- Use member roles for temporary helpers.
|
- Use member roles for temporary helpers.
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
See `event-settings` for permissions or `tenant-dashboard-overview` for the full event overview.
|
See Event Settings for permissions or the Event Dashboard overview for the full event view.
|
||||||
|
|||||||
@@ -28,4 +28,4 @@ Open the QR page from the event dashboard. You can copy the join link or downloa
|
|||||||
- Add the link to printed invitations if the event is pre‑announced.
|
- Add the link to printed invitations if the event is pre‑announced.
|
||||||
|
|
||||||
### Need more help?
|
### Need more help?
|
||||||
See `event-prep-checklist` for the full prep flow.
|
See the Event Preparation Checklist for the full prep flow.
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ related: []
|
|||||||
|
|
||||||
This portal collects everything event admins need to configure events, run key workflows, and close out events smoothly.
|
This portal collects everything event admins need to configure events, run key workflows, and close out events smoothly.
|
||||||
|
|
||||||
| Section | Key Questions | Article Slug |
|
| Section | Key Questions | Article |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Dashboard | Where do I see status, KPIs, and quick actions? | `tenant-dashboard-overview` |
|
| Dashboard | Where do I see status, key numbers, and quick actions? | Event Dashboard Overview |
|
||||||
| Event Settings | Where do I edit the event basics and publish status? | `event-settings` |
|
| Event Settings | Where do I edit the event basics and publish status? | Event Settings |
|
||||||
| Branding | How do I upload logos and set colors? | `event-branding-assets` |
|
| Branding | How do I upload logos and set colors? | Branding & Assets |
|
||||||
| Tasks & Collections | How do I manage guest tasks and prompts? | `event-tasks-setup` |
|
| Tasks & Collections | How do I manage guest tasks and prompts? | Event Tasks & Collections |
|
||||||
| Guest Access | How do I share the join link or QR? | `guest-access-qr` |
|
| Guest Access | How do I share the join link or QR? | Guest Access & QR |
|
||||||
| Team & Invites | How do I invite staff and assign roles? | `event-team-invites` |
|
| Team & Invites | How do I invite staff and assign roles? | Event Team & Invites |
|
||||||
| Control Room | How do I moderate uploads and manage the queue? | `control-room-moderation` |
|
| Control Room | How do I moderate uploads and manage the queue? | Control Room: Moderation & Queue |
|
||||||
| Live Show | How do I configure the Live Show player? | `live-show-setup` |
|
| Live Show | How do I configure the Live Show player? | Set up & run Live Show |
|
||||||
| Billing & Exports | Where do I manage packages and data exports? | `billing-packages-exports` |
|
| Billing & Exports | Where do I manage packages and data exports? | Packages, Billing & Exports |
|
||||||
| Wrap-up & Compliance | What should I do after the event ends? | `post-event-wrapup` |
|
| Wrap-up & Compliance | What should I do after the event ends? | Post-Event Wrap-up |
|
||||||
| FAQ | What are the most common questions? | `faq-admin` |
|
| FAQ | What are the most common questions? | FAQ: Event Admin |
|
||||||
|
|
||||||
Use the in-app help center for mobile-friendly reading, or open `/help/admin` on desktop for the full layout.
|
Use the in-app help center for mobile-friendly reading, or open `/help/admin` on desktop for the full layout.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Event Dashboard Overview"
|
|||||||
locale: en
|
locale: en
|
||||||
slug: tenant-dashboard-overview
|
slug: tenant-dashboard-overview
|
||||||
audience: admin
|
audience: admin
|
||||||
summary: "Understand event status, KPIs, and the setup checklist at a glance."
|
summary: "Understand event status, key numbers, and the setup checklist at a glance."
|
||||||
version_introduced: 2025.4
|
version_introduced: 2025.4
|
||||||
requires_app_version: "^3.2.0"
|
requires_app_version: "^3.2.0"
|
||||||
status: draft
|
status: draft
|
||||||
@@ -21,14 +21,14 @@ Use this guide right after creating an event or whenever you need a quick health
|
|||||||
|
|
||||||
## What the dashboard shows
|
## What the dashboard shows
|
||||||
- **Event status** (Draft / Published) so you always know what guests can see.
|
- **Event status** (Draft / Published) so you always know what guests can see.
|
||||||
- **KPIs** for guests, uploads, and engagement so you can spot momentum early.
|
- **Key numbers** for guests, uploads, and engagement so you can spot momentum early.
|
||||||
- **Setup checklist** with the remaining steps before launch.
|
- **Setup checklist** with the remaining steps before launch.
|
||||||
- **Quick actions** that jump to tasks, Live Show, branding, and QR tools.
|
- **Quick actions** that jump to tasks, Live Show, branding, and QR tools.
|
||||||
|
|
||||||
## How to use it
|
## How to use it
|
||||||
1. **Confirm the status** and keep the event in Draft until everything is ready.
|
1. **Confirm the status** and keep the event in Draft until everything is ready.
|
||||||
2. **Work the checklist** from top to bottom; it mirrors the most common prep path.
|
2. **Work the checklist** from top to bottom; it mirrors the most common prep path.
|
||||||
3. **Check KPIs** to validate that invites and uploads are coming in.
|
3. **Check the numbers** to validate that invites and uploads are coming in.
|
||||||
4. **Jump into details** (tasks, QR, Live Show) using the quick actions.
|
4. **Jump into details** (tasks, QR, Live Show) using the quick actions.
|
||||||
|
|
||||||
### Tips
|
### Tips
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
},
|
},
|
||||||
"addOns": {
|
"addOns": {
|
||||||
"title": "Add-on-Verlauf",
|
"title": "Add-on-Verlauf",
|
||||||
"description": "Einmalige Add-ons, die für diesen Tenant gebucht wurden.",
|
"description": "Einmalige Add-ons, die für diesen Account gebucht wurden.",
|
||||||
"empty": "Noch keine Add-ons gebucht.",
|
"empty": "Noch keine Add-ons gebucht.",
|
||||||
"badge": "Add-ons",
|
"badge": "Add-ons",
|
||||||
"table": {
|
"table": {
|
||||||
@@ -2031,7 +2031,7 @@
|
|||||||
"sections": {
|
"sections": {
|
||||||
"mode": "Standard vs. Event-spezifisch",
|
"mode": "Standard vs. Event-spezifisch",
|
||||||
"toggleTitle": "Branding-Quelle wählen",
|
"toggleTitle": "Branding-Quelle wählen",
|
||||||
"toggleDescription": "Nutze das Standard-Branding des Tenants oder überschreibe es nur für dieses Event.",
|
"toggleDescription": "Nutze das Standard-Branding des Accounts oder überschreibe es nur für dieses Event.",
|
||||||
"palette": "Palette & Modus",
|
"palette": "Palette & Modus",
|
||||||
"colorsTitle": "Farben & Light/Dark",
|
"colorsTitle": "Farben & Light/Dark",
|
||||||
"colorsDescription": "Primär-, Sekundär-, Hintergrund- und Surface-Farbe festlegen.",
|
"colorsDescription": "Primär-, Sekundär-, Hintergrund- und Surface-Farbe festlegen.",
|
||||||
@@ -2047,7 +2047,7 @@
|
|||||||
},
|
},
|
||||||
"useDefault": "Standard nutzen",
|
"useDefault": "Standard nutzen",
|
||||||
"useCustom": "Event-spezifisch",
|
"useCustom": "Event-spezifisch",
|
||||||
"toggleHint": "Standard übernimmt die Tenant-Farben, Event-spezifisch überschreibt sie.",
|
"toggleHint": "Standard übernimmt die Account-Farben, Event-spezifisch überschreibt sie.",
|
||||||
"standard": "Standard",
|
"standard": "Standard",
|
||||||
"custom": "Event",
|
"custom": "Event",
|
||||||
"toggleAria": "Event-spezifisches Branding aktivieren",
|
"toggleAria": "Event-spezifisches Branding aktivieren",
|
||||||
@@ -2095,10 +2095,10 @@
|
|||||||
"saved": "Branding gespeichert.",
|
"saved": "Branding gespeichert.",
|
||||||
"saveError": "Branding konnte nicht gespeichert werden.",
|
"saveError": "Branding konnte nicht gespeichert werden.",
|
||||||
"footer": {
|
"footer": {
|
||||||
"default": "Standard-Farben des Tenants aktiv.",
|
"default": "Standard-Farben des Accounts aktiv.",
|
||||||
"custom": "Event-spezifisches Branding aktiv."
|
"custom": "Event-spezifisches Branding aktiv."
|
||||||
},
|
},
|
||||||
"usingDefault": "Tenant-Branding aktiv",
|
"usingDefault": "Account-Branding aktiv",
|
||||||
"usingCustom": "Event-Branding aktiv",
|
"usingCustom": "Event-Branding aktiv",
|
||||||
"preview": {
|
"preview": {
|
||||||
"demoTitle": "Demo-Event",
|
"demoTitle": "Demo-Event",
|
||||||
@@ -2662,7 +2662,7 @@
|
|||||||
"mobileSettings": {
|
"mobileSettings": {
|
||||||
"title": "Einstellungen",
|
"title": "Einstellungen",
|
||||||
"accountTitle": "Account",
|
"accountTitle": "Account",
|
||||||
"tenantBadge": "Tenant #{{id}}",
|
"tenantBadge": "Konto #{{id}}",
|
||||||
"notificationsTitle": "Benachrichtigungen",
|
"notificationsTitle": "Benachrichtigungen",
|
||||||
"notificationsLoading": "Lade Einstellungen ...",
|
"notificationsLoading": "Lade Einstellungen ...",
|
||||||
"pushTitle": "App Push",
|
"pushTitle": "App Push",
|
||||||
@@ -2848,12 +2848,12 @@
|
|||||||
"includeMediaHint": "Größeres ZIP; nur bei Bedarf."
|
"includeMediaHint": "Größeres ZIP; nur bei Bedarf."
|
||||||
},
|
},
|
||||||
"scopes": {
|
"scopes": {
|
||||||
"tenant": "Mandantenexport",
|
"tenant": "Kontoexport",
|
||||||
"event": "Event-Export"
|
"event": "Event-Export"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "Letzte Exporte",
|
"title": "Letzte Exporte",
|
||||||
"hint": "Die letzten 10 Exporte für Mandant und Events.",
|
"hint": "Die letzten 10 Exporte für dein Konto und Events.",
|
||||||
"empty": "Noch keine Exporte."
|
"empty": "Noch keine Exporte."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
},
|
},
|
||||||
"addOns": {
|
"addOns": {
|
||||||
"title": "Add-on history",
|
"title": "Add-on history",
|
||||||
"description": "One-time add-ons purchased for this tenant.",
|
"description": "One-time add-ons purchased for this account.",
|
||||||
"empty": "No add-ons purchased yet.",
|
"empty": "No add-ons purchased yet.",
|
||||||
"badge": "Add-ons",
|
"badge": "Add-ons",
|
||||||
"table": {
|
"table": {
|
||||||
@@ -2027,7 +2027,7 @@
|
|||||||
"sections": {
|
"sections": {
|
||||||
"mode": "Default vs. event-specific",
|
"mode": "Default vs. event-specific",
|
||||||
"toggleTitle": "Choose branding source",
|
"toggleTitle": "Choose branding source",
|
||||||
"toggleDescription": "Use tenant defaults or override only for this event.",
|
"toggleDescription": "Use account defaults or override only for this event.",
|
||||||
"palette": "Palette & mode",
|
"palette": "Palette & mode",
|
||||||
"colorsTitle": "Colors & light/dark",
|
"colorsTitle": "Colors & light/dark",
|
||||||
"colorsDescription": "Set primary, secondary, background, and surface colors.",
|
"colorsDescription": "Set primary, secondary, background, and surface colors.",
|
||||||
@@ -2043,7 +2043,7 @@
|
|||||||
},
|
},
|
||||||
"useDefault": "Use default",
|
"useDefault": "Use default",
|
||||||
"useCustom": "Event-specific",
|
"useCustom": "Event-specific",
|
||||||
"toggleHint": "Default uses tenant colors; event-specific overrides them.",
|
"toggleHint": "Default uses account colors; event-specific overrides them.",
|
||||||
"standard": "Default",
|
"standard": "Default",
|
||||||
"custom": "Event",
|
"custom": "Event",
|
||||||
"toggleAria": "Toggle event-specific branding",
|
"toggleAria": "Toggle event-specific branding",
|
||||||
@@ -2091,10 +2091,10 @@
|
|||||||
"saved": "Branding saved.",
|
"saved": "Branding saved.",
|
||||||
"saveError": "Branding could not be saved.",
|
"saveError": "Branding could not be saved.",
|
||||||
"footer": {
|
"footer": {
|
||||||
"default": "Tenant default colors active.",
|
"default": "Account default colors active.",
|
||||||
"custom": "Event-specific branding active."
|
"custom": "Event-specific branding active."
|
||||||
},
|
},
|
||||||
"usingDefault": "Tenant branding active",
|
"usingDefault": "Account branding active",
|
||||||
"usingCustom": "Event branding active",
|
"usingCustom": "Event branding active",
|
||||||
"preview": {
|
"preview": {
|
||||||
"demoTitle": "Demo event",
|
"demoTitle": "Demo event",
|
||||||
@@ -2664,7 +2664,7 @@
|
|||||||
"mobileSettings": {
|
"mobileSettings": {
|
||||||
"title": "Settings",
|
"title": "Settings",
|
||||||
"accountTitle": "Account",
|
"accountTitle": "Account",
|
||||||
"tenantBadge": "Tenant #{{id}}",
|
"tenantBadge": "Account #{{id}}",
|
||||||
"notificationsTitle": "Notifications",
|
"notificationsTitle": "Notifications",
|
||||||
"notificationsLoading": "Loading settings ...",
|
"notificationsLoading": "Loading settings ...",
|
||||||
"pushTitle": "App Push",
|
"pushTitle": "App Push",
|
||||||
@@ -2839,7 +2839,7 @@
|
|||||||
"title": "Data exports",
|
"title": "Data exports",
|
||||||
"request": {
|
"request": {
|
||||||
"title": "Export request",
|
"title": "Export request",
|
||||||
"hint": "Export tenant data or a specific event archive.",
|
"hint": "Export account data or a specific event archive.",
|
||||||
"progress": "Export is running. This list refreshes automatically."
|
"progress": "Export is running. This list refreshes automatically."
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
@@ -2850,12 +2850,12 @@
|
|||||||
"includeMediaHint": "Bigger ZIP; choose when needed."
|
"includeMediaHint": "Bigger ZIP; choose when needed."
|
||||||
},
|
},
|
||||||
"scopes": {
|
"scopes": {
|
||||||
"tenant": "Tenant export",
|
"tenant": "Account export",
|
||||||
"event": "Event export"
|
"event": "Event export"
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"title": "Recent exports",
|
"title": "Recent exports",
|
||||||
"hint": "Latest 10 exports for your tenant and events.",
|
"hint": "Latest 10 exports for your account and events.",
|
||||||
"empty": "No exports yet."
|
"empty": "No exports yet."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
|||||||
@@ -685,7 +685,7 @@ export default function MobileBrandingPage() {
|
|||||||
</XStack>
|
</XStack>
|
||||||
<Text fontSize="$xs" color={muted}>
|
<Text fontSize="$xs" color={muted}>
|
||||||
{form.useDefaultBranding
|
{form.useDefaultBranding
|
||||||
? t('events.branding.usingDefault', 'Tenant-Branding aktiv')
|
? t('events.branding.usingDefault', 'Account-Branding aktiv')
|
||||||
: t('events.branding.usingCustom', 'Event-Branding aktiv')}
|
: t('events.branding.usingCustom', 'Event-Branding aktiv')}
|
||||||
</Text>
|
</Text>
|
||||||
</MobileCard>
|
</MobileCard>
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export function DataExportsPanel({
|
|||||||
{t('dataExports.request.title', 'Export request')}
|
{t('dataExports.request.title', 'Export request')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="$xs" color={muted}>
|
<Text fontSize="$xs" color={muted}>
|
||||||
{t('dataExports.request.hint', 'Export tenant data or a specific event archive.')}
|
{t('dataExports.request.hint', 'Export account data or a specific event archive.')}
|
||||||
</Text>
|
</Text>
|
||||||
<YStack space="$2">
|
<YStack space="$2">
|
||||||
{!isRecap ? (
|
{!isRecap ? (
|
||||||
@@ -211,7 +211,7 @@ export function DataExportsPanel({
|
|||||||
compact
|
compact
|
||||||
style={{ minWidth: 140, maxWidth: 180 }}
|
style={{ minWidth: 140, maxWidth: 180 }}
|
||||||
>
|
>
|
||||||
<option value="tenant">{t('dataExports.scopes.tenant', 'Tenant')}</option>
|
<option value="tenant">{t('dataExports.scopes.tenant', 'Account')}</option>
|
||||||
<option value="event">{t('dataExports.scopes.event', 'Event')}</option>
|
<option value="event">{t('dataExports.scopes.event', 'Event')}</option>
|
||||||
</MobileSelect>
|
</MobileSelect>
|
||||||
</XStack>
|
</XStack>
|
||||||
@@ -281,7 +281,7 @@ export function DataExportsPanel({
|
|||||||
{t('dataExports.history.title', 'Recent exports')}
|
{t('dataExports.history.title', 'Recent exports')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="$xs" color={muted}>
|
<Text fontSize="$xs" color={muted}>
|
||||||
{t('dataExports.history.hint', 'Latest 10 exports for your tenant and events.')}
|
{t('dataExports.history.hint', 'Latest 10 exports for your account and events.')}
|
||||||
</Text>
|
</Text>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<YStack space="$2">
|
<YStack space="$2">
|
||||||
@@ -301,7 +301,7 @@ export function DataExportsPanel({
|
|||||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||||
{entry.scope === 'event'
|
{entry.scope === 'event'
|
||||||
? t('dataExports.scopes.event', 'Event export')
|
? t('dataExports.scopes.event', 'Event export')
|
||||||
: t('dataExports.scopes.tenant', 'Tenant export')}
|
: t('dataExports.scopes.tenant', 'Account export')}
|
||||||
</Text>
|
</Text>
|
||||||
{entry.event ? (
|
{entry.event ? (
|
||||||
<Text fontSize="$xs" color={muted}>
|
<Text fontSize="$xs" color={muted}>
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ export default function MobileSettingsPage() {
|
|||||||
{user?.name ?? user?.email ?? t('settings.session.unknown', 'Benutzer')}
|
{user?.name ?? user?.email ?? t('settings.session.unknown', 'Benutzer')}
|
||||||
</Text>
|
</Text>
|
||||||
{user?.tenant_id ? (
|
{user?.tenant_id ? (
|
||||||
<PillBadge tone="muted">{t('mobileSettings.tenantBadge', 'Tenant #{{id}}', { id: user.tenant_id })}</PillBadge>
|
<PillBadge tone="muted">{t('mobileSettings.tenantBadge', 'Account #{{id}}', { id: user.tenant_id })}</PillBadge>
|
||||||
) : null}
|
) : null}
|
||||||
<XStack space="$2">
|
<XStack space="$2">
|
||||||
<CTAButton label={t('settings.profile.actions.openProfile', 'Profil bearbeiten')} onPress={() => navigate(ADMIN_PROFILE_ACCOUNT_PATH)} />
|
<CTAButton label={t('settings.profile.actions.openProfile', 'Profil bearbeiten')} onPress={() => navigate(ADMIN_PROFILE_ACCOUNT_PATH)} />
|
||||||
|
|||||||
119
resources/js/admin/mobile/__tests__/DataExportsPage.test.tsx
Normal file
119
resources/js/admin/mobile/__tests__/DataExportsPage.test.tsx
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
const navigateMock = vi.fn();
|
||||||
|
|
||||||
|
const tMock = (
|
||||||
|
_key: string,
|
||||||
|
fallback?: string | Record<string, unknown>,
|
||||||
|
options?: Record<string, unknown>,
|
||||||
|
) => {
|
||||||
|
let value = typeof fallback === 'string' ? fallback : _key;
|
||||||
|
if (options) {
|
||||||
|
Object.entries(options).forEach(([key, val]) => {
|
||||||
|
value = value.replaceAll(`{{${key}}}`, String(val));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mock('react-router-dom', () => ({
|
||||||
|
useNavigate: () => navigateMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('react-i18next', () => ({
|
||||||
|
useTranslation: () => ({ t: tMock }),
|
||||||
|
initReactI18next: {
|
||||||
|
type: '3rdParty',
|
||||||
|
init: () => undefined,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useBackNavigation', () => ({
|
||||||
|
useBackNavigation: () => vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../theme', () => ({
|
||||||
|
useAdminTheme: () => ({
|
||||||
|
textStrong: '#111827',
|
||||||
|
text: '#111827',
|
||||||
|
muted: '#6b7280',
|
||||||
|
border: '#e5e7eb',
|
||||||
|
danger: '#b91c1c',
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/MobileShell', () => ({
|
||||||
|
MobileShell: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
HeaderActionButton: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/Primitives', () => ({
|
||||||
|
MobileCard: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
CTAButton: ({ label, onPress }: { label: string; onPress?: () => void }) => (
|
||||||
|
<button type="button" onClick={onPress}>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
PillBadge: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
||||||
|
SkeletonCard: () => <div>Loading...</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/FormControls', () => ({
|
||||||
|
MobileSelect: ({ children, ...props }: { children: React.ReactNode }) => (
|
||||||
|
<select {...props}>{children}</select>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/stacks', () => ({
|
||||||
|
YStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
XStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/text', () => ({
|
||||||
|
SizableText: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/switch', () => ({
|
||||||
|
Switch: Object.assign(
|
||||||
|
({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
{ Thumb: () => <div /> },
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/react-native-web-lite', () => ({
|
||||||
|
Pressable: ({
|
||||||
|
children,
|
||||||
|
onPress,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
onPress?: () => void;
|
||||||
|
[key: string]: unknown;
|
||||||
|
}) => (
|
||||||
|
<button type="button" onClick={onPress} {...rest}>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
FlatList: ({ data = [], renderItem }: { data?: unknown[]; renderItem?: (info: any) => React.ReactNode }) => (
|
||||||
|
<div>{renderItem ? data.map((item, index) => renderItem({ item, index })) : null}</div>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../../api', () => ({
|
||||||
|
listTenantDataExports: vi.fn().mockResolvedValue([]),
|
||||||
|
getEvents: vi.fn().mockResolvedValue([]),
|
||||||
|
requestTenantDataExport: vi.fn(),
|
||||||
|
downloadTenantDataExport: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
import MobileDataExportsPage from '../DataExportsPage';
|
||||||
|
|
||||||
|
describe('MobileDataExportsPage', () => {
|
||||||
|
it('renders account scope label', async () => {
|
||||||
|
render(<MobileDataExportsPage />);
|
||||||
|
|
||||||
|
expect(await screen.findByText('Account')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
152
resources/js/admin/mobile/__tests__/SettingsPage.test.tsx
Normal file
152
resources/js/admin/mobile/__tests__/SettingsPage.test.tsx
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
const navigateMock = vi.fn();
|
||||||
|
const logoutMock = vi.fn();
|
||||||
|
|
||||||
|
const tMock = (
|
||||||
|
_key: string,
|
||||||
|
fallback?: string | Record<string, unknown>,
|
||||||
|
options?: Record<string, unknown>,
|
||||||
|
) => {
|
||||||
|
let value = typeof fallback === 'string' ? fallback : _key;
|
||||||
|
if (options) {
|
||||||
|
Object.entries(options).forEach(([key, val]) => {
|
||||||
|
value = value.replaceAll(`{{${key}}}`, String(val));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mock('react-router-dom', () => ({
|
||||||
|
useNavigate: () => navigateMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('react-i18next', () => ({
|
||||||
|
useTranslation: () => ({ t: tMock }),
|
||||||
|
initReactI18next: {
|
||||||
|
type: '3rdParty',
|
||||||
|
init: () => undefined,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../../auth/context', () => ({
|
||||||
|
useAuth: () => ({ user: { name: 'Test User', tenant_id: 123 }, logout: logoutMock }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../../api', () => ({
|
||||||
|
getNotificationPreferences: vi.fn().mockResolvedValue({ defaults: {}, preferences: {} }),
|
||||||
|
updateNotificationPreferences: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/MobileShell', () => ({
|
||||||
|
MobileShell: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/Primitives', () => ({
|
||||||
|
MobileCard: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
CTAButton: ({ label, onPress }: { label: string; onPress?: () => void }) => (
|
||||||
|
<button type="button" onClick={onPress}>
|
||||||
|
{label}
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
PillBadge: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../components/MobileInstallBanner', () => ({
|
||||||
|
MobileInstallBanner: () => null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useAdminPushSubscription', () => ({
|
||||||
|
useAdminPushSubscription: () => ({ supported: false, permission: 'default', subscribed: false }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useDevicePermissions', () => ({
|
||||||
|
useDevicePermissions: () => ({
|
||||||
|
loading: false,
|
||||||
|
notifications: 'granted',
|
||||||
|
camera: 'granted',
|
||||||
|
storage: 'available',
|
||||||
|
requestPersistentStorage: vi.fn().mockResolvedValue(false),
|
||||||
|
refresh: vi.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useInstallPrompt', () => ({
|
||||||
|
useInstallPrompt: () => ({
|
||||||
|
isInstalled: false,
|
||||||
|
isStandalone: false,
|
||||||
|
canInstall: false,
|
||||||
|
isIos: false,
|
||||||
|
promptInstall: vi.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useBackNavigation', () => ({
|
||||||
|
useBackNavigation: () => vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../hooks/useOnlineStatus', () => ({
|
||||||
|
useOnlineStatus: () => true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../lib/installBanner', () => ({
|
||||||
|
getInstallBannerDismissed: () => false,
|
||||||
|
setInstallBannerDismissed: () => undefined,
|
||||||
|
shouldShowInstallBanner: () => false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../lib/mobileTour', () => ({
|
||||||
|
setTourSeen: () => undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('../theme', () => ({
|
||||||
|
useAdminTheme: () => ({
|
||||||
|
text: '#111827',
|
||||||
|
muted: '#6b7280',
|
||||||
|
border: '#e5e7eb',
|
||||||
|
danger: '#b91c1c',
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/stacks', () => ({
|
||||||
|
YStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
XStack: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/text', () => ({
|
||||||
|
SizableText: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/group', () => ({
|
||||||
|
YGroup: Object.assign(({ children }: { children: React.ReactNode }) => <div>{children}</div>, {
|
||||||
|
Item: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/list-item', () => ({
|
||||||
|
ListItem: ({ title, subTitle }: { title?: React.ReactNode; subTitle?: React.ReactNode }) => (
|
||||||
|
<div>
|
||||||
|
{title}
|
||||||
|
{subTitle}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@tamagui/switch', () => ({
|
||||||
|
Switch: Object.assign(
|
||||||
|
({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||||
|
{ Thumb: () => <div /> },
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
import MobileSettingsPage from '../SettingsPage';
|
||||||
|
|
||||||
|
describe('MobileSettingsPage', () => {
|
||||||
|
it('renders account badge for the current user', async () => {
|
||||||
|
render(<MobileSettingsPage />);
|
||||||
|
|
||||||
|
expect(await screen.findByText('Account #123')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user