KI-AGENT: Mobile Push Registrierung anbinden

This commit is contained in:
2026-05-22 17:34:52 +02:00
parent 5400fd7ad5
commit cacfce4d15
14 changed files with 630 additions and 20 deletions

View File

@@ -3,6 +3,8 @@ import { Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-
import { router } from 'expo-router';
import { DEFAULT_API_BASE_URL } from '@/src/config/env';
import { sendMobileTestPush } from '@/src/lib/api';
import { registerDeviceForPush } from '@/src/lib/push-registration';
import {
getApiBaseUrlSync,
hydrateApiBaseUrl,
@@ -23,6 +25,7 @@ export default function SettingsScreen() {
const [serverUrl, setServerUrlInput] = useState(getApiBaseUrlSync());
const [savedUrl, setSavedUrl] = useState(getApiBaseUrlSync());
const [submitting, setSubmitting] = useState(false);
const [pushSubmitting, setPushSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null);
@@ -85,6 +88,46 @@ export default function SettingsScreen() {
}
}
async function onRegisterPush() {
setError(null);
setSuccess(null);
if (!token) {
setError('Bitte zuerst anmelden, um dieses Gerät für Push zu registrieren.');
return;
}
setPushSubmitting(true);
try {
const result = await registerDeviceForPush(token);
setSuccess(`Push registriert: ${result.centralDeviceId || result.id || 'aktiv'}`);
} catch (err) {
setError(err instanceof Error ? err.message : 'Push-Registrierung fehlgeschlagen.');
} finally {
setPushSubmitting(false);
}
}
async function onSendTestPush() {
setError(null);
setSuccess(null);
if (!token) {
setError('Bitte zuerst anmelden, um eine Testnachricht zu senden.');
return;
}
setPushSubmitting(true);
try {
const result = await sendMobileTestPush(token);
setSuccess(`Testnachricht angefordert: ${result.accepted} akzeptiert, ${result.rejected} abgelehnt.`);
} catch (err) {
setError(err instanceof Error ? err.message : 'Testnachricht konnte nicht gesendet werden.');
} finally {
setPushSubmitting(false);
}
}
const isDirty = serverUrl.trim() !== savedUrl;
return (
@@ -131,6 +174,30 @@ export default function SettingsScreen() {
</Pressable>
</View>
</View>
<View style={styles.card}>
<Text style={styles.title}>Mobile Push</Text>
<Text style={styles.hint}>
Registriert dieses Gerät bei deiner FEDEO-Instanz und leitet den nativen Push-Token an den zentralen
Push-Server weiter.
</Text>
<View style={styles.actions}>
<Pressable
style={[styles.saveButton, (!token || pushSubmitting) ? styles.buttonDisabled : null]}
onPress={onRegisterPush}
disabled={!token || pushSubmitting}>
<Text style={styles.saveButtonText}>{pushSubmitting ? 'Bitte warten...' : 'Gerät registrieren'}</Text>
</Pressable>
<Pressable
style={[styles.resetButton, (!token || pushSubmitting) ? styles.buttonDisabled : null]}
onPress={onSendTestPush}
disabled={!token || pushSubmitting}>
<Text style={styles.resetButtonText}>Testnachricht senden</Text>
</Pressable>
</View>
</View>
</ScrollView>
);
}
@@ -140,6 +207,7 @@ const styles = StyleSheet.create({
flexGrow: 1,
backgroundColor: '#f9fafb',
padding: 16,
gap: 12,
},
card: {
backgroundColor: '#ffffff',