feat: Push-Hinweis nach Erstellen eines Crew-Einladungslinks

Owner sieht einen Dialog zur Aktivierung von Crew-Push-Benachrichtigungen, sofern diese noch nicht aktiv sind.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-31 13:43:52 +02:00
parent c856c2e903
commit 3a267905b0
4 changed files with 68 additions and 0 deletions
+44
View File
@@ -6,6 +6,12 @@ import LogbookBackupPanel from './LogbookBackupPanel.tsx'
import { useDialog } from './ModalDialog.tsx'
import { PlausibleEvents, trackPlausibleEvent } from '../services/analytics.js'
import { apiFetch } from '../services/api.js'
import {
enableCollaboratorChangePush,
isCollaboratorPushActive,
isPushSupported
} from '../services/pushNotifications.js'
import { isIosDevice, isRunningStandalone } from '../hooks/usePwaInstall.js'
interface SettingsFormProps {
logbookId?: string | null
@@ -151,6 +157,43 @@ export default function SettingsForm({ logbookId, onLogbookRestored }: SettingsF
}
}
const promptPushAfterInviteCreated = async () => {
if (!isPushSupported()) return
if (await isCollaboratorPushActive()) return
const iosNeedsInstall = isIosDevice() && !isRunningStandalone()
if (iosNeedsInstall) {
await showAlert(
t('settings.invite_push_prompt_ios_message'),
t('settings.invite_push_prompt_title'),
t('settings.invite_push_prompt_later')
)
return
}
const enable = await showConfirm(
t('settings.invite_push_prompt_message'),
t('settings.invite_push_prompt_title'),
t('settings.invite_push_prompt_enable'),
t('settings.invite_push_prompt_later')
)
if (!enable) return
try {
await enableCollaboratorChangePush()
await showAlert(
t('settings.invite_push_prompt_success'),
t('settings.invite_push_prompt_title')
)
trackPlausibleEvent(PlausibleEvents.PUSH_ENABLED)
} catch (err: unknown) {
console.error('Failed to enable push after invite:', err)
showAlert(err instanceof Error ? err.message : t('profile.push_error'))
}
}
const handleGenerateInvite = async () => {
if (!logbookId) return
setGeneratingInvite(true)
@@ -175,6 +218,7 @@ export default function SettingsForm({ logbookId, onLogbookRestored }: SettingsF
setInviteLink(link)
trackPlausibleEvent(PlausibleEvents.INVITE_GENERATED)
await promptPushAfterInviteCreated()
} catch (err: unknown) {
console.error('Failed to generate invite:', err)
showAlert(err instanceof Error ? err.message : 'Failed to generate invite link.')
+6
View File
@@ -482,6 +482,12 @@
"delete_account_failed": "Konto konnte nicht gelöscht werden. Bitte versuche es erneut.",
"delete_backup_hint": "Tipp: Erstelle vor dem Löschen Backups deiner Logbücher (.daagbok.json) in den Einstellungen jedes Logbuchs.",
"deleting_account": "Konto wird gelöscht…",
"invite_push_prompt_title": "Push-Benachrichtigungen aktivieren?",
"invite_push_prompt_message": "Sobald eingeladene Crewmitglieder Änderungen synchronisieren, kannst du per Push informiert werden. Es werden keine Logbuch-Inhalte im Klartext gesendet.",
"invite_push_prompt_ios_message": "Sobald Crewmitglieder Änderungen synchronisieren, kannst du per Push informiert werden. Auf dem iPhone/iPad: App zum Home-Bildschirm hinzufügen (iOS 16.4+), dann Push im Benutzerprofil aktivieren.",
"invite_push_prompt_enable": "Jetzt aktivieren",
"invite_push_prompt_later": "Später",
"invite_push_prompt_success": "Push-Benachrichtigungen sind auf diesem Gerät aktiv.",
"backup_title": "Backup & Wiederherstellung",
"backup_desc": "Vollständiges verschlüsseltes Backup dieses Logbuchs (Einträge, Fotos, GPS-Tracks, Crew, Schiff). Mit Backup-Passphrase geschützt — für Restore auf diesem oder einem neuen Account.",
"backup_export_title": "Backup erstellen",
+6
View File
@@ -482,6 +482,12 @@
"delete_account_failed": "Failed to delete account. Please try again.",
"delete_backup_hint": "Tip: Before deleting, create backups of your logbooks (.daagbok.json) in each logbook's settings.",
"deleting_account": "Deleting account…",
"invite_push_prompt_title": "Enable push notifications?",
"invite_push_prompt_message": "When invited crew members sync changes, you can be notified via push. No logbook content is sent in plain text.",
"invite_push_prompt_ios_message": "When crew members sync changes, you can get push notifications. On iPhone/iPad: add the app to your Home Screen (iOS 16.4+), then enable push in your user profile.",
"invite_push_prompt_enable": "Enable now",
"invite_push_prompt_later": "Later",
"invite_push_prompt_success": "Push notifications are active on this device.",
"backup_title": "Backup & restore",
"backup_desc": "Full encrypted backup of this logbook (entries, photos, GPS tracks, crew, vessel). Protected with a backup passphrase — restore on this or a new account.",
"backup_export_title": "Create backup",
+12
View File
@@ -43,6 +43,18 @@ async function fetchVapidPublicKey(): Promise<string | null> {
}
}
/** True when crew-change push is enabled and notification permission is granted. */
export async function isCollaboratorPushActive(): Promise<boolean> {
if (!isPushSupported()) return false
if (getNotificationPermission() !== 'granted') return false
try {
const prefs = await fetchPushPrefs()
return prefs.collaboratorChangesEnabled
} catch {
return false
}
}
export async function fetchPushPrefs(): Promise<{ collaboratorChangesEnabled: boolean }> {
if (!localStorage.getItem('active_userid')) {
return { collaboratorChangesEnabled: false }