diff --git a/ANALYTICS_MIGRATION.md b/ANALYTICS_MIGRATION.md
deleted file mode 100644
index 6a4bdab..0000000
--- a/ANALYTICS_MIGRATION.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Analytics Migration: Aptabase to Countly
-
-## Overview
-Successfully migrated the project from Aptabase analytics to Countly with minimal disruption to the codebase.
-
-## What Was Changed
-
-### 1. Dependencies
-- ❌ **Removed**: `@aptabase/react-native`
-- ✅ **Added**: `countly-sdk-react-native-bridge@25.4.0`
-
-### 2. Analytics Service (`src/services/analytics.service.ts`)
-- **Completely rewritten** to use Countly SDK
-- **Maintained same interface** for components (same method names and signatures)
-- **Enhanced error handling** with retry logic and graceful degradation
-- **Added comprehensive session management** (start, end, extend)
-- **Proper user properties support**
-- **Environment-driven initialization** with fallback configuration
-
-#### Key Features:
-- ✅ Event tracking with properties
-- ✅ User properties management
-- ✅ Session lifecycle management
-- ✅ Error handling with retry mechanism
-- ✅ Service status monitoring
-- ✅ Graceful degradation on failures
-
-### 3. Hook Integration (`src/hooks/use-analytics.ts`)
-- **Updated** to use new `analyticsService` instead of `aptabaseService`
-- **Interface unchanged** - components continue working without modifications
-- **Performance optimized** with `useCallback`
-
-### 4. Environment Configuration
-- **Updated** `env.js` to support Countly variables:
- - `RESPOND_COUNTLY_APP_KEY` (replaces `RESPOND_APTABASE_APP_KEY`)
- - `RESPOND_COUNTLY_URL` (replaces `RESPOND_APTABASE_URL`)
-- **Updated** `.env.development` with new variable names
-
-### 5. App Initialization
-- **Integrated** analytics service into `AppInitializationService`
-- **Automatic initialization** during app startup
-- **Proper error handling** - analytics failures don't break app startup
-- **Environment-based configuration** - uses env vars automatically
-
-### 6. Removed Components
-- ❌ **Deleted**: `src/components/common/aptabase-provider.tsx`
-- ❌ **Removed**: All references to `AptabaseProviderWrapper` in `_layout.tsx`
-- ❌ **Cleaned up**: Old Aptabase mocks in test files
-
-### 7. Test Coverage
-- ✅ **New comprehensive test suite** for `analytics.service.ts` (23 passing tests)
-- ✅ **Updated hook tests** to use new service
-- ✅ **Cleaned up** old Aptabase references in component tests
-- ✅ **All tests passing** for analytics-related code
-
-## Migration Benefits
-
-### ✅ Minimal Disruption
-- **Zero changes** required in components using analytics
-- **Same API interface** maintained across the migration
-- **Existing analytics calls** continue working unchanged
-
-### ✅ Enhanced Reliability
-- **Better error handling** with exponential backoff retry logic
-- **Graceful degradation** when analytics fails
-- **Service status monitoring** with automatic recovery
-- **Proper session management**
-
-### ✅ Improved Architecture
-- **Centralized initialization** through AppInitializationService
-- **Environment-driven configuration**
-- **Comprehensive test coverage**
-- **Better logging and debugging**
-
-## Configuration Required
-
-To complete the setup, you need to configure the environment variables:
-
-```bash
-# In your .env files (development, staging, production)
-RESPOND_COUNTLY_APP_KEY=your_countly_app_key_here
-RESPOND_COUNTLY_URL=https://your-countly-server.com
-```
-
-## Testing Status
-
-✅ **All analytics tests passing**:
-- `src/services/__tests__/analytics.service.test.ts` - 23 tests ✅
-- `src/hooks/__tests__/use-analytics.test.ts` - All tests ✅
-- Component integration tests working ✅
-
-## Next Steps
-
-1. **Configure Countly server credentials** in environment files
-2. **Test in development environment** to verify data flow
-3. **Deploy to staging** for validation
-4. **Monitor analytics data** to ensure proper tracking
-
-## Rollback Plan (if needed)
-
-If rollback is required:
-1. Reinstall: `yarn add @aptabase/react-native`
-2. Restore: `src/services/aptabase.service.ts` from git history
-3. Revert: Environment variable changes
-4. Restore: `AptabaseProviderWrapper` in `_layout.tsx`
-
-However, the migration maintains full API compatibility, so rollback should not be necessary.
diff --git a/src/app/__tests__/onboarding.test.tsx b/src/app/__tests__/onboarding.test.tsx
index e3f7584..7b21fe7 100644
--- a/src/app/__tests__/onboarding.test.tsx
+++ b/src/app/__tests__/onboarding.test.tsx
@@ -213,7 +213,7 @@ describe('Onboarding Component', () => {
expect(getByTestId('onboarding-flatlist')).toBeTruthy();
expect(getByText('Skip')).toBeTruthy();
- // The FlatList content might not render immediately in tests,
+ // The FlashList content might not render immediately in tests,
// so we verify the component renders without crashing
expect(getByTestId('onboarding-flatlist')).toBeTruthy();
});
diff --git a/src/app/onboarding.tsx b/src/app/onboarding.tsx
index a4393e0..8414f39 100644
--- a/src/app/onboarding.tsx
+++ b/src/app/onboarding.tsx
@@ -3,8 +3,8 @@ import { FlashList } from '@shopify/flash-list';
import { useRouter } from 'expo-router';
import { Bell, ChevronRight, MapPin, Users } from 'lucide-react-native';
import { useColorScheme } from 'nativewind';
-import React, { useCallback, useEffect, useRef, useState } from 'react';
-import { Dimensions, Image } from 'react-native';
+import React, { useCallback, useMemo, useRef, useState } from 'react';
+import { Dimensions, Image, StyleSheet } from 'react-native';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { FocusAwareStatusBar, SafeAreaView, View } from '@/components/ui';
@@ -17,6 +17,50 @@ import { useIsFirstTime } from '@/lib/storage';
const { width } = Dimensions.get('window');
+// Color constants
+const COLORS = {
+ primary: '#FF7B1A',
+ text: {
+ light: {
+ primary: '#1f2937',
+ secondary: '#6b7280',
+ },
+ dark: {
+ primary: '#ffffff',
+ secondary: '#d1d5db',
+ },
+ },
+};
+
+// Static styles
+const styles = StyleSheet.create({
+ onboardingContainer: {
+ height: 400,
+ justifyContent: 'center',
+ alignItems: 'center',
+ paddingHorizontal: 32,
+ },
+ iconContainer: {
+ marginBottom: 32,
+ alignItems: 'center',
+ },
+ title: {
+ fontSize: 28,
+ fontWeight: 'bold',
+ textAlign: 'center',
+ marginBottom: 16,
+ },
+ description: {
+ fontSize: 16,
+ textAlign: 'center',
+ lineHeight: 24,
+ },
+ flexContainer: {
+ flex: 1,
+ minHeight: 400,
+ },
+});
+
type OnboardingItemProps = {
title: string;
description: string;
@@ -27,26 +71,37 @@ const onboardingData: OnboardingItemProps[] = [
{
title: 'Resgrid Responder',
description: 'Manage your status, staffing, and interact with your organization in real-time',
- icon: ,
+ icon: ,
},
{
title: 'Instant Notifications',
description: 'Receive immediate alerts for emergencies and important updates from your department',
- icon: ,
+ icon: ,
},
{
title: 'Interact with Calls',
description: 'Seamlessly view call information and interact with your team members for efficient emergency response',
- icon: ,
+ icon: ,
},
];
const OnboardingItem: React.FC = ({ title, description, icon }) => {
+ const { colorScheme } = useColorScheme();
+
+ // Compute dynamic colors once using useMemo
+ const textColors = useMemo(() => {
+ const isDark = colorScheme === 'dark';
+ return {
+ title: isDark ? COLORS.text.dark.primary : COLORS.text.light.primary,
+ description: isDark ? COLORS.text.dark.secondary : COLORS.text.light.secondary,
+ };
+ }, [colorScheme]);
+
return (
-
- {icon}
- {title}
- {description}
+
+ {icon}
+ {title}
+ {description}
);
};
@@ -140,19 +195,23 @@ export default function Onboarding() {
- }
- horizontal
- showsHorizontalScrollIndicator={false}
- pagingEnabled
- bounces={false}
- keyExtractor={(item: OnboardingItemProps) => item.title}
- onScroll={handleScroll}
- scrollEventThrottle={16}
- testID="onboarding-flatlist"
- />
+
+ }
+ horizontal
+ showsHorizontalScrollIndicator={false}
+ pagingEnabled
+ bounces={false}
+ keyExtractor={(item: OnboardingItemProps) => item.title}
+ onScroll={handleScroll}
+ scrollEventThrottle={16}
+ estimatedItemSize={width}
+ getItemType={() => 'onboarding-item'}
+ testID="onboarding-flatlist"
+ />
+
diff --git a/src/components/ui/index.tsx b/src/components/ui/index.tsx
index 4847d9e..ff38aec 100644
--- a/src/components/ui/index.tsx
+++ b/src/components/ui/index.tsx
@@ -1,7 +1,7 @@
import { cssInterop } from 'nativewind';
import Svg from 'react-native-svg';
-//export * from './button';
+export * from './button';
export * from './checkbox';
export * from './cover';
export * from './focus-aware-status-bar';
@@ -9,13 +9,14 @@ export * from './focus-aware-status-bar';
//export * from './input';
//export * from './list';
//export * from './modal';
+export * from './pressable';
//export * from './progress-bar';
//export * from './select';
-//export * from './text';
+export * from './text';
//export * from './utils';
// export base components from react-native
-export { ActivityIndicator, Pressable, ScrollView, TouchableOpacity, View } from 'react-native';
+export { ActivityIndicator, ScrollView, TouchableOpacity, View } from 'react-native';
export { SafeAreaView } from 'react-native-safe-area-context';
//Apply cssInterop to Svg to resolve className string into style