import { useEffect, useState } from 'react'; import { View, Text, ScrollView, Pressable, Alert } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { useColors } from '../lib/theme'; import { useMe, invalidateMe, type Plan } from '../hooks/useMe'; import { apiFetch } from '../lib/api'; export default function DebugScreen() { const router = useRouter(); const colors = useColors(); const { me } = useMe(); useEffect(() => { if (!__DEV__) { router.replace('/'); } }, [router]); if (!__DEV__) { return ; } return ( router.back()} hitSlop={8} style={({ pressed }) => ({ opacity: pressed ? 0.6 : 1, })} > Debug Dev only Diese Page ist nur in __DEV__ verfügbar. Production-Builds redirecten auf /. {me ? ( ) : null} ); } const PLANS: Plan[] = ['free', 'pro', 'legend']; const PLAN_COLOR: Record = { free: '#737373', pro: '#007AFF', legend: '#f59e0b', }; function PlanOverrideToggle({ colors, userId, currentPlan, }: { colors: import('../lib/theme').ColorScheme; userId: string; currentPlan: Plan; }) { const [loading, setLoading] = useState(false); async function switchPlan(plan: Plan) { if (plan === currentPlan) return; setLoading(true); try { // PATCH /api/admin/users/:id requires admin privileges. // If the dev-user is not admin, this returns 403 — see alert below. await apiFetch(`/api/admin/users/${userId}`, { method: 'PATCH', body: JSON.stringify({ plan }), }); invalidateMe(); } catch (e: unknown) { const msg = e instanceof Error ? e.message : String(e); if (msg.includes('403')) { Alert.alert( 'Kein Admin-Zugriff', 'PATCH /api/admin/users/:id setzt Admin-Rechte voraus. Plan manuell im Admin-Panel flippen.', ); } else { Alert.alert('Fehler', msg); } } finally { setLoading(false); } } return ( Plan-Override (DEV) PATCH /api/admin/users/:id — braucht Admin-Rechte {PLANS.map((plan) => { const isActive = plan === currentPlan; const accent = PLAN_COLOR[plan]; return ( switchPlan(plan)} disabled={loading || isActive} style={({ pressed }) => ({ flex: 1, paddingVertical: 10, borderRadius: 10, alignItems: 'center', backgroundColor: isActive ? accent : colors.surfaceElevated, opacity: loading ? 0.5 : pressed ? 0.7 : 1, })} > {plan} ); })} ); } function DebugStub({ title, subtitle, icon, }: { title: string; subtitle: string; icon: React.ComponentProps['name']; }) { const colors = useColors(); return ( {title} {subtitle} ); }