import React, { useState } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, TextInput, ScrollView, ActivityIndicator, Alert, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { router, useLocalSearchParams } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { AppColors, Spacing, BorderRadius, FontSizes, FontWeights } from '@/constants/theme'; import { useBeneficiary } from '@/contexts/BeneficiaryContext'; import { api } from '@/services/api'; export default function ActivateScreen() { // Get params - lovedOneName from purchase flow, beneficiaryId from existing beneficiary const params = useLocalSearchParams<{ lovedOneName?: string; beneficiaryId?: string }>(); const [activationCode, setActivationCode] = useState(''); const [isActivating, setIsActivating] = useState(false); const [step, setStep] = useState<'code' | 'beneficiary' | 'complete'>('code'); // Pre-fill beneficiary name from params if available const [beneficiaryName, setBeneficiaryName] = useState(params.lovedOneName || ''); const { addLocalBeneficiary, updateLocalBeneficiary, localBeneficiaries } = useBeneficiary(); // Check if we're activating for an existing beneficiary const existingBeneficiaryId = params.beneficiaryId ? parseInt(params.beneficiaryId, 10) : null; const existingBeneficiary = existingBeneficiaryId ? localBeneficiaries.find(b => b.id === existingBeneficiaryId) : null; // Demo serial for testing without real hardware const DEMO_SERIAL = 'DEMO-00000'; const handleActivate = async () => { const code = activationCode.trim().toUpperCase(); if (!code) { Alert.alert('Error', 'Please enter serial number'); return; } // Check for demo serial const isDemoMode = code === DEMO_SERIAL || code === 'DEMO-1234-5678'; // Validate code format: minimum 8 characters (or demo serial) if (!isDemoMode && code.length < 8) { Alert.alert('Invalid Code', 'Please enter a valid serial number from your WellNuo Starter Kit.\n\nFor testing, use: DEMO-00000'); return; } setIsActivating(true); try { // If we have an existing beneficiary, update them with device info if (existingBeneficiaryId && existingBeneficiary) { // Prepare update data const updateData: any = { hasDevices: true, device_id: code, equipmentStatus: 'active', // Clear awaiting state - sensors now active }; // If beneficiary has pending subscription (from kit purchase), activate it if (existingBeneficiary.subscription?.status === 'pending') { updateData.subscription = { ...existingBeneficiary.subscription, status: 'active', }; } await updateLocalBeneficiary(existingBeneficiaryId, updateData); setBeneficiaryName(existingBeneficiary.name); setStep('complete'); } else { // Creating new beneficiary const beneficiaryData: any = { name: params.lovedOneName?.trim() || '', hasDevices: true, device_id: code, }; if (isDemoMode) { beneficiaryData.isDemo = true; } // If name was already provided from add-loved-one screen, skip to saving if (params.lovedOneName && params.lovedOneName.trim()) { await addLocalBeneficiary(beneficiaryData); await api.setOnboardingCompleted(true); setStep('complete'); } else { // No name provided, show beneficiary form setStep('beneficiary'); } } } catch (error) { console.error('Failed to activate:', error); Alert.alert('Error', 'Failed to activate kit. Please try again.'); } finally { setIsActivating(false); } }; const handleAddBeneficiary = async () => { if (!beneficiaryName.trim()) { Alert.alert('Error', 'Please enter beneficiary name'); return; } setIsActivating(true); try { const code = activationCode.trim().toUpperCase(); const isDemoMode = code === DEMO_SERIAL || code === 'DEMO-1234-5678'; // Add beneficiary with device info await addLocalBeneficiary({ name: beneficiaryName.trim(), hasDevices: true, device_id: code, isDemo: isDemoMode, }); // Mark onboarding as completed await api.setOnboardingCompleted(true); setStep('complete'); } catch (error) { console.error('Failed to add beneficiary:', error); Alert.alert('Error', 'Failed to add beneficiary. Please try again.'); } finally { setIsActivating(false); } }; const handleComplete = () => { // If updating existing beneficiary, go back to their detail page if (existingBeneficiaryId) { router.replace(`/(tabs)/beneficiaries/${existingBeneficiaryId}`); } else { // Navigate to main app router.replace('/(tabs)'); } }; // Step 1: Enter activation code if (step === 'code') { return ( {/* Header */} {existingBeneficiary ? ( router.back()}> ) : ( )} {existingBeneficiary ? 'Connect Sensors' : 'Activate Kit'} {/* Icon */} {/* Instructions */} {existingBeneficiary ? `Connect sensors for ${existingBeneficiary.name}` : 'Enter the activation code from your WellNuo Starter Kit packaging'} {/* Input */} {/* Demo Code Link */} setActivationCode('DEMO-1234-5678')} > Use demo code {/* Activate Button */} {isActivating ? ( ) : ( Activate )} {/* Skip for now - only show for new onboarding, not for existing beneficiary */} {!existingBeneficiary && ( Skip for now )} ); } // Step 2: Add beneficiary if (step === 'beneficiary') { return ( {/* Header */} setStep('code')}> Add Beneficiary {/* Icon */} {/* Instructions */} Who will you be monitoring with this kit? {/* Name Input */} Full Name {/* Continue Button */} {isActivating ? ( ) : ( Continue )} ); } // Step 3: Complete const displayName = beneficiaryName || existingBeneficiary?.name || params.lovedOneName; return ( {/* Success Icon */} {existingBeneficiary ? 'Sensors Connected!' : 'Kit Activated!'} {existingBeneficiary ? `Sensors have been connected for ` : `Your WellNuo kit has been successfully activated for `} {displayName} {/* Next Steps */} Next Steps: {existingBeneficiary ? ( <> 1 Connect the hub to WiFi 2 Subscribe to start monitoring ($49/month) ) : ( <> 1 Place sensors in your loved one's home 2 Connect the hub to WiFi 3 Subscribe to start monitoring ($49/month) )} {/* Complete Button */} {existingBeneficiary ? 'Continue' : 'Go to Dashboard'} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: AppColors.background, }, content: { flex: 1, padding: Spacing.lg, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: Spacing.xl, }, backButton: { padding: Spacing.sm, marginLeft: -Spacing.sm, }, title: { fontSize: FontSizes.xl, fontWeight: FontWeights.bold, color: AppColors.textPrimary, }, placeholder: { width: 40, }, iconContainer: { alignItems: 'center', marginBottom: Spacing.xl, }, instructions: { fontSize: FontSizes.base, color: AppColors.textSecondary, textAlign: 'center', marginBottom: Spacing.xl, lineHeight: 24, }, inputContainer: { marginBottom: Spacing.lg, }, inputGroup: { marginBottom: Spacing.lg, }, inputLabel: { fontSize: FontSizes.sm, fontWeight: FontWeights.medium, color: AppColors.textPrimary, marginBottom: Spacing.sm, }, input: { backgroundColor: AppColors.surface, borderRadius: BorderRadius.lg, paddingHorizontal: Spacing.lg, paddingVertical: Spacing.md, fontSize: FontSizes.lg, color: AppColors.textPrimary, textAlign: 'center', borderWidth: 1, borderColor: AppColors.border, }, devNotice: { alignItems: 'center', marginBottom: Spacing.xl, paddingVertical: Spacing.lg, paddingHorizontal: Spacing.lg, backgroundColor: `${AppColors.warning}10`, borderRadius: BorderRadius.lg, borderWidth: 1, borderColor: `${AppColors.warning}30`, }, devNoticeTitle: { fontSize: FontSizes.base, fontWeight: FontWeights.semibold, color: AppColors.warning, marginTop: Spacing.sm, marginBottom: Spacing.sm, }, devNoticeText: { fontSize: FontSizes.sm, color: AppColors.textSecondary, textAlign: 'center', lineHeight: 20, marginBottom: Spacing.md, }, demoCodeButton: { paddingVertical: Spacing.sm, paddingHorizontal: Spacing.lg, backgroundColor: AppColors.warning, borderRadius: BorderRadius.md, }, demoCodeButtonText: { fontSize: FontSizes.sm, fontWeight: FontWeights.medium, color: AppColors.white, }, demoCodeLink: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 4, marginBottom: Spacing.md, }, demoCodeLinkText: { fontSize: FontSizes.sm, color: AppColors.textMuted, }, primaryButton: { backgroundColor: AppColors.primary, paddingVertical: Spacing.lg, borderRadius: BorderRadius.lg, alignItems: 'center', marginTop: Spacing.md, }, buttonDisabled: { opacity: 0.7, }, primaryButtonText: { fontSize: FontSizes.lg, fontWeight: FontWeights.semibold, color: AppColors.white, }, skipButton: { alignItems: 'center', paddingVertical: Spacing.lg, }, skipButtonText: { fontSize: FontSizes.base, color: AppColors.textSecondary, textDecorationLine: 'underline', }, successContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, successIcon: { marginBottom: Spacing.xl, }, successTitle: { fontSize: FontSizes['2xl'], fontWeight: FontWeights.bold, color: AppColors.textPrimary, marginBottom: Spacing.md, }, successMessage: { fontSize: FontSizes.base, color: AppColors.textSecondary, textAlign: 'center', marginBottom: Spacing.md, }, beneficiaryHighlight: { fontWeight: FontWeights.bold, color: AppColors.primary, }, nextSteps: { width: '100%', backgroundColor: AppColors.surface, borderRadius: BorderRadius.lg, padding: Spacing.lg, }, nextStepsTitle: { fontSize: FontSizes.base, fontWeight: FontWeights.semibold, color: AppColors.textPrimary, marginBottom: Spacing.md, }, stepItem: { flexDirection: 'row', alignItems: 'center', gap: Spacing.md, marginBottom: Spacing.sm, }, stepNumber: { width: 24, height: 24, borderRadius: 12, backgroundColor: AppColors.primary, color: AppColors.white, textAlign: 'center', lineHeight: 24, fontSize: FontSizes.sm, fontWeight: FontWeights.bold, overflow: 'hidden', }, stepText: { fontSize: FontSizes.sm, color: AppColors.textSecondary, flex: 1, }, });