diff --git a/app/onboarding/personalizing.tsx b/app/onboarding/personalizing.tsx new file mode 100644 index 0000000..8915540 --- /dev/null +++ b/app/onboarding/personalizing.tsx @@ -0,0 +1,165 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { Animated, Easing, Image, StyleSheet, Text, View } from 'react-native'; +import { SafeAreaView } from 'react-native-safe-area-context'; +import { Ionicons } from '@expo/vector-icons'; +import { router } from 'expo-router'; +import Svg, { Circle } from 'react-native-svg'; +import { useApp } from '../../context/AppContext'; +import { useColors } from '../../constants/Colors'; +import { useSafeAnalytics } from '../../services/analytics'; +import { Language } from '../../types'; + +const getCopy = (language: Language) => { + if (language === 'de') { + return { + status: 'Dein Pflegeplan wird personalisiert…', + steps: ['Antworten werden analysiert', 'Pflegeplan wird erstellt', 'Scan-Credits werden vorbereitet', 'Plan wird finalisiert'], + testimonial: '„GreenLens hat meine Geigenfeige gerettet. Die täglichen Routinen sind unglaublich präzise."', + author: 'Elena R.', + rating: '4,8 APP-STORE-BEWERTUNG', + }; + } + if (language === 'es') { + return { + status: 'Personalizando tu plan de cuidados…', + steps: ['Analizando tus respuestas', 'Creando tu plan de cuidados', 'Preparando tus créditos de escaneo', 'Finalizando tu plan'], + testimonial: '"GreenLens salvó mi ficus lyrata. Las rutinas diarias son increíblemente precisas."', + author: 'Elena R.', + rating: '4.8 VALORACIÓN EN APP STORE', + }; + } + return { + status: 'Personalizing your care plan…', + steps: ['Analyzing your answers', 'Building your care plan', 'Preparing your scan credits', 'Finalizing your plan'], + testimonial: '"GreenLens completely saved my Fiddle Leaf Fig. The daily routines feel incredibly precise."', + author: 'Elena R.', + rating: '4.8 APP STORE RATING', + }; +}; + +const STEP_THRESHOLDS = [25, 50, 75, 95]; +const RING_SIZE = 150; +const RING_STROKE_WIDTH = 7; +const RING_RADIUS = (RING_SIZE - RING_STROKE_WIDTH) / 2; +const RING_CIRCUMFERENCE = 2 * Math.PI * RING_RADIUS; + +const AnimatedCircle = Animated.createAnimatedComponent(Circle); + +export default function OnboardingPersonalizingScreen() { + const { language, isDarkMode, colorPalette } = useApp(); + const colors = useColors(isDarkMode, colorPalette); + const posthog = useSafeAnalytics(); + const copy = getCopy(language); + const progress = useRef(new Animated.Value(0)).current; + const [percent, setPercent] = useState(0); + const navigated = useRef(false); + + const strokeDashoffset = progress.interpolate({ + inputRange: [0, 100], + outputRange: [RING_CIRCUMFERENCE, 0], + }); + + useEffect(() => { + posthog.capture('onboarding_personalizing_viewed'); + const listener = progress.addListener(({ value }) => setPercent(Math.round(value))); + Animated.timing(progress, { + toValue: 100, + duration: 6000, + easing: Easing.inOut(Easing.cubic), + useNativeDriver: false, + }).start(({ finished }) => { + if (finished && !navigated.current) { + navigated.current = true; + setTimeout(() => { + posthog.capture('paywall_opened', { source: 'onboarding' }); + router.replace('/profile/billing?view=paywall&context=onboarding'); + }, 450); + } + }); + return () => progress.removeListener(listener); + }, [progress, posthog]); + + return ( + + {percent}% + + + + + + + + + + {copy.status} + + + {copy.steps.map((label, index) => { + const done = percent >= STEP_THRESHOLDS[index]; + return ( + + + {label} + + ); + })} + + + + {copy.author} + + {[0, 1, 2, 3, 4].map((i) => )} + + + {copy.testimonial} + + + + {copy.rating} + + + ); +} + +const styles = StyleSheet.create({ + safe: { flex: 1, alignItems: 'center', paddingHorizontal: 24, paddingTop: 30 }, + percent: { fontSize: 56, fontWeight: '900', marginBottom: 16 }, + ringWrap: { width: 150, height: 150, alignItems: 'center', justifyContent: 'center', marginBottom: 22 }, + ringImage: { width: 112, height: 112, borderRadius: 56 }, + statusPill: { flexDirection: 'row', alignItems: 'center', gap: 8, borderRadius: 999, paddingHorizontal: 18, paddingVertical: 11, marginBottom: 26 }, + statusText: { fontSize: 14.5, fontWeight: '800' }, + checklist: { alignSelf: 'stretch', gap: 15, marginBottom: 26, paddingHorizontal: 8 }, + checkRow: { flexDirection: 'row', alignItems: 'center', gap: 12 }, + checkLabel: { fontSize: 16.5, fontWeight: '700' }, + testimonialCard: { alignSelf: 'stretch', borderRadius: 18, padding: 16, marginBottom: 14 }, + testimonialHeader: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 6 }, + testimonialAuthor: { fontSize: 14.5, fontWeight: '800' }, + starsRow: { flexDirection: 'row', gap: 2 }, + testimonialText: { fontSize: 14, lineHeight: 20, fontStyle: 'italic' }, + ratingBadge: { flexDirection: 'row', alignItems: 'center', gap: 7, borderWidth: 1.5, borderRadius: 999, paddingHorizontal: 16, paddingVertical: 9 }, + ratingText: { fontSize: 12.5, fontWeight: '900', letterSpacing: 0.6 }, +});