#
tokens: 18841/50000 7/75 files (page 2/2)
lines: off (toggle) GitHub
raw markdown copy
This is page 2 of 2. Use http://codebase.md/lallen30/mcp-remote-server?page={x} to view the full context.

# Directory Structure

```
├── .gitignore
├── build
│   └── index.js
├── package-lock.json
├── package.json
├── README.md
├── resources
│   ├── code-examples
│   │   └── react-native
│   │       ├── assets
│   │       │   └── images
│   │       │       ├── event.png
│   │       │       ├── qr-codeeee13.png
│   │       │       └── [email protected]
│   │       ├── components
│   │       │   ├── Button.tsx
│   │       │   ├── ErrorBoundary.tsx
│   │       │   ├── LoadingSpinner.tsx
│   │       │   └── UpdateModal.tsx
│   │       ├── config
│   │       │   ├── apiConfig.ts
│   │       │   └── environment.ts
│   │       ├── hooks
│   │       │   ├── useAppUpdate.ts
│   │       │   └── useForm.ts
│   │       ├── navigation
│   │       │   ├── AppNavigator.tsx
│   │       │   ├── DrawerNavigator.tsx
│   │       │   ├── NavigationWrapper.tsx
│   │       │   └── TabNavigator.tsx
│   │       ├── screens
│   │       │   ├── AboutUs.tsx
│   │       │   ├── HomeScreen.js
│   │       │   ├── HomeScreen.tsx
│   │       │   ├── PostLogin
│   │       │   │   ├── AboutUs
│   │       │   │   │   ├── AboutUsScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── BluestoneAppsAI
│   │       │   │   │   ├── BluestoneAppsAIScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── Calendar
│   │       │   │   │   ├── CalendarScreen.tsx
│   │       │   │   │   ├── EventDetails.tsx
│   │       │   │   │   ├── EventDetailsStyles.ts
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── ChangePassword
│   │       │   │   │   ├── ChangePasswordScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── Contact
│   │       │   │   │   ├── ContactScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── CustomerSupport
│   │       │   │   │   ├── CustomerSupportScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── EditProfile
│   │       │   │   │   ├── EditProfileScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   ├── Home
│   │       │   │   │   └── HomeScreen.tsx
│   │       │   │   ├── MyProfile
│   │       │   │   │   ├── MyProfileScreen.tsx
│   │       │   │   │   └── Styles.ts
│   │       │   │   └── Posts
│   │       │   │       ├── PostScreen.tsx
│   │       │   │       ├── PostsScreen.tsx
│   │       │   │       ├── PostStyles.ts
│   │       │   │       └── Styles.ts
│   │       │   └── PreLogin
│   │       │       ├── ForgotPassword
│   │       │       │   ├── ForgotPasswordScreen.tsx
│   │       │       │   └── Styles.ts
│   │       │       ├── Legal
│   │       │       │   ├── PrivacyPolicyScreen.tsx
│   │       │       │   └── TermsAndConditionsScreen.tsx
│   │       │       ├── Login
│   │       │       │   ├── LoginScreen.tsx
│   │       │       │   └── Styles.tsx
│   │       │       ├── SignUp
│   │       │       │   ├── SignUpScreen.tsx
│   │       │       │   └── Styles.ts
│   │       │       └── VerifyEmail
│   │       │           ├── Styles.ts
│   │       │           └── VerifyEmailScreen.tsx
│   │       ├── services
│   │       │   ├── apiService.ts
│   │       │   ├── authService.ts
│   │       │   ├── axiosRequest.ts
│   │       │   ├── config.ts
│   │       │   ├── NavigationMonitorService.ts
│   │       │   ├── storageService.ts
│   │       │   ├── types.ts
│   │       │   ├── UpdateService.ts
│   │       │   └── userService.ts
│   │       ├── theme
│   │       │   ├── colors_original.ts
│   │       │   ├── colors.ts
│   │       │   ├── README.md
│   │       │   ├── theme.ts
│   │       │   └── typography.ts
│   │       ├── tsconfig.json
│   │       ├── types
│   │       │   └── react-native.d.ts
│   │       └── utils
│   │           ├── axiosUtils.ts
│   │           └── LogSuppressor.ts
│   └── standards
│       ├── api_communication.md
│       ├── component_design.md
│       ├── project_structure.md
│       └── state_management.md
├── src
│   └── index.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/resources/code-examples/react-native/services/UpdateService.ts:
--------------------------------------------------------------------------------

```typescript
import { Platform, Linking } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import { API } from '../config/apiConfig';
import DeviceInfo from 'react-native-device-info';
import { compareVersions } from 'compare-versions';

// Storage keys
const STORAGE_KEYS = {
  SKIPPED_VERSIONS: 'skipped_versions',
  CURRENT_VERSION: 'current_version',
};

// App store URLs and IDs
const APP_STORE = {
  IOS_URL: 'https://apps.apple.com/us/app/id6670172327',
  IOS_LOOKUP_URL: 'https://itunes.apple.com/lookup?id=6670172327',
  ANDROID_URL: 'https://play.google.com/store/apps/details?id=your.package.name',
};

interface VersionData {
  latestVersion: string;
  minimumVersion: string;
  releaseNotes?: string;
}

class UpdateService {
  /**
   * Get the current app version
   * @returns Promise resolving to the current app version
   */
  static async getCurrentVersion(): Promise<string> {
    try {
      return DeviceInfo.getVersion();
    } catch (error) {
      console.error('Error getting current version:', error);
      return '1.0.0'; // Fallback version
    }
  }

  /**
   * Get the stored app version
   * @returns Promise resolving to the stored app version or null if not found
   */
  static async getStoredVersion(): Promise<string | null> {
    try {
      return await AsyncStorage.getItem(STORAGE_KEYS.CURRENT_VERSION);
    } catch (error) {
      console.error('Error getting stored version:', error);
      return null;
    }
  }

  /**
   * Update the stored app version
   * @param version The version to store
   * @returns Promise resolving when the version is stored
   */
  static async updateStoredVersion(version: string): Promise<void> {
    try {
      await AsyncStorage.setItem(STORAGE_KEYS.CURRENT_VERSION, version);
    } catch (error) {
      console.error('Error updating stored version:', error);
    }
  }

  /**
   * Check for updates from the server
   * @returns Promise resolving to the version data
   */
  static async checkForUpdates(): Promise<VersionData | null> {
    try {
      // First try to get the version from the App Store if on iOS
      if (Platform.OS === 'ios') {
        const appStoreVersion = await this.fetchAppStoreVersion();
        if (appStoreVersion) {
          return {
            latestVersion: appStoreVersion,
            minimumVersion: appStoreVersion, // Assuming minimum version is the same as latest for App Store
            releaseNotes: 'A new version is available in the App Store.',
          };
        }
      }
      
      // If App Store check fails or we're not on iOS, fall back to API check
      
      // Add a timeout to prevent long waits if the server is unresponsive
      const response = await axios.get(`${API.BASE_URL}/${API.ENDPOINTS.APP_VERSION}`, {
        timeout: 5000, // 5 second timeout
      });
      
      if (response.data && response.data.success) {
        return {
          latestVersion: response.data.data.latestVersion || '1.0.0',
          minimumVersion: response.data.data.minimumVersion || '1.0.0',
          releaseNotes: response.data.data.releaseNotes || '',
        };
      }
      
      // Return a default version info instead of null
      return await this.getDefaultVersionInfo();
    } catch (error) {
      console.error('Error checking for updates');
      // Instead of just logging the error, provide a fallback
      return await this.getDefaultVersionInfo();
    }
  }
  
  /**
   * Fetch the latest version from the App Store
   * @returns Promise resolving to the App Store version or null if not found
   */
  static async fetchAppStoreVersion(): Promise<string | null> {
    try {
      const response = await axios.get(APP_STORE.IOS_LOOKUP_URL, {
        timeout: 5000, // 5 second timeout
      });
      
      if (response.data && response.data.resultCount > 0) {
        const appStoreVersion = response.data.results[0].version;
        return appStoreVersion;
      }
      
      return null;
    } catch (error) {
      console.error('Error fetching app version from App Store');
      return null;
    }
  }

  /**
   * Get default version information when the server is unavailable
   * @returns Default version data
   */
  private static async getDefaultVersionInfo(): Promise<VersionData> {
    // Get the current version from the app
    const currentVersion = await this.getCurrentVersion();
    
    return {
      latestVersion: currentVersion, // Use current version as latest if we can't fetch it
      minimumVersion: '1.0.0', // Use a safe default for minimum version
      releaseNotes: 'Unable to fetch update information. Please check your internet connection.',
    };
  }

  /**
   * Check if an update is required
   * @param currentVersion The current app version
   * @param minimumVersion The minimum required version
   * @returns True if an update is required, false otherwise
   */
  static isUpdateRequired(currentVersion: string, minimumVersion: string): boolean {
    try {
      return compareVersions(currentVersion, minimumVersion) < 0;
    } catch (error) {
      console.error('Error checking if update is required');
      return false; // Default to not required if there's an error
    }
  }

  /**
   * Check if the update modal should be shown
   * @param currentVersion Current app version
   * @param latestVersion Latest available version
   * @param minimumRequiredVersion Minimum required version
   * @returns Boolean indicating if the update modal should be shown
   */
  static shouldShowUpdateModal(
    currentVersion: string,
    latestVersion: string,
    minimumRequiredVersion: string
  ): boolean {
    // Check if update is required (current version is less than minimum required)
    const isRequired = this.isUpdateRequired(currentVersion, minimumRequiredVersion);

    // Check if update is available (current version is less than latest version)
    const isUpdateAvailable = compareVersions(currentVersion, latestVersion) < 0;

    // Only show modal if update is required or an update is available
    return isRequired || isUpdateAvailable;
  }

  /**
   * Skip a version
   * @param version The version to skip
   * @returns Promise resolving when the version is skipped
   */
  static async skipVersion(version: string): Promise<void> {
    try {
      // Get the current skipped versions
      const skippedVersionsString = await AsyncStorage.getItem(STORAGE_KEYS.SKIPPED_VERSIONS);
      const skippedVersions = skippedVersionsString ? JSON.parse(skippedVersionsString) : [];
      
      // Add the version if it's not already skipped
      if (!skippedVersions.includes(version)) {
        skippedVersions.push(version);
        await AsyncStorage.setItem(STORAGE_KEYS.SKIPPED_VERSIONS, JSON.stringify(skippedVersions));
      }
    } catch (error) {
      console.error('Error skipping version:', error);
    }
  }

  /**
   * Check if a version has been skipped
   * @param version The version to check
   * @returns Promise resolving to true if the version has been skipped, false otherwise
   */
  static async isVersionSkipped(version: string): Promise<boolean> {
    try {
      const skippedVersionsString = await AsyncStorage.getItem(STORAGE_KEYS.SKIPPED_VERSIONS);
      const skippedVersions = skippedVersionsString ? JSON.parse(skippedVersionsString) : [];
      
      return skippedVersions.includes(version);
    } catch (error) {
      console.error('Error checking if version is skipped:', error);
      return false;
    }
  }

  /**
   * Open the app store
   * @returns Promise resolving when the app store is opened
   */
  static async openAppStore(): Promise<void> {
    try {
      const url = Platform.OS === 'ios' ? APP_STORE.IOS_URL : APP_STORE.ANDROID_URL;
      
      const canOpen = await Linking.canOpenURL(url);
      
      if (canOpen) {
        await Linking.openURL(url);
      } else {
        console.warn(`Cannot open URL: ${url}`);
      }
    } catch (error) {
      console.error('Error opening app store:', error);
    }
  }

  /**
   * Check if the app is installed from the App Store
   * @returns Promise resolving to whether the app is from the App Store
   */
  static async isAppStoreVersion(): Promise<boolean> {
    try {
      if (Platform.OS === 'ios') {
        // On iOS, we can use DeviceInfo to determine if the app is running from the App Store
        // This is a simplified approach - in a real app you might need a more robust check
        const bundleId = DeviceInfo.getBundleId();
        const isTestFlight = await DeviceInfo.isEmulator();
        
        // If it's not an emulator and has a valid bundle ID, it's likely from the App Store
        return !isTestFlight && !!bundleId;
      }
      
      // For Android, we would need a different approach
      return false;
    } catch (error) {
      console.error('Error determining app source:', error);
      return false;
    }
  }
}

export default UpdateService;

```

--------------------------------------------------------------------------------
/resources/standards/state_management.md:
--------------------------------------------------------------------------------

```markdown
# State Management Standards

BluestoneApps follows these standards for state management in React Native applications.

## State Management Strategy

We use a pragmatic approach to state management with a focus on simplicity and maintainability:

1. **Local Component State**: For UI state that doesn't need to be shared
2. **Custom Hooks**: For reusable state logic
3. **AsyncStorage**: For persistent data
4. **Context API**: For state shared across components (when necessary)

## Local Component State

Use React's `useState` and `useEffect` hooks for component-local state:

```typescript
// Simple state with useState
const [isLoading, setIsLoading] = useState<boolean>(false);
const [data, setData] = useState<DataType | null>(null);

// Side effects with useEffect
useEffect(() => {
  const fetchData = async () => {
    try {
      setIsLoading(true);
      const result = await apiService.getData();
      setData(result);
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setIsLoading(false);
    }
  };
  
  fetchData();
}, []);
```

### When to use local state:

- Form input values
- UI states like open/closed, visible/hidden
- Component-specific data loading states
- Temporary data that doesn't need persistence

## Custom Hooks

Extract reusable state logic into custom hooks:

```typescript
// src/hooks/useAppUpdate.ts
import { useState, useCallback, useEffect } from 'react';
import UpdateService from '../services/UpdateService';
import AsyncStorage from '@react-native-async-storage/async-storage';

interface VersionInfo {
  latestVersion: string;
  minimumVersion: string;
  releaseNotes?: string;
}

const useAppUpdate = (checkOnMount = true, updateCheckInterval = 60 * 60 * 1000) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [versionInfo, setVersionInfo] = useState<VersionInfo | null>(null);
  const [updateModalVisible, setUpdateModalVisible] = useState(false);
  
  // Check for updates
  const checkForUpdates = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      
      const info = await UpdateService.checkForUpdates();
      setVersionInfo(info);
      
      // Show update modal if needed
      if (info && UpdateService.isUpdateRequired(info)) {
        setUpdateModalVisible(true);
      }
      
      // Store last check time
      await AsyncStorage.setItem('last_update_check', Date.now().toString());
      
      return info;
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
      return null;
    } finally {
      setLoading(false);
    }
  }, []);
  
  // Check for updates on mount if enabled
  useEffect(() => {
    if (checkOnMount) {
      checkForUpdates();
    }
  }, [checkOnMount, checkForUpdates]);
  
  // Return state and functions
  return {
    loading,
    error,
    versionInfo,
    updateModalVisible,
    setUpdateModalVisible,
    checkForUpdates,
  };
};

export default useAppUpdate;
```

### When to use custom hooks:

- Reusable state logic across multiple components
- Complex state management with multiple related states
- API communication patterns
- Feature-specific logic that combines multiple React hooks

## AsyncStorage for Persistence

Use AsyncStorage for persisting data across app sessions:

```typescript
// Example in authService.ts
import AsyncStorage from '@react-native-async-storage/async-storage';

class AuthService {
  async login(email: string, password: string): Promise<LoginResponse> {
    try {
      const response = await axiosRequest.post<LoginResponse>(
        API.ENDPOINTS.LOGIN,
        { email, password }
      );

      if (response?.loginInfo?.token) {
        // Store authentication data
        await AsyncStorage.setItem('userToken', response.loginInfo.token);
        await AsyncStorage.setItem('userData', JSON.stringify({ loginInfo: response.loginInfo }));
      }

      return response;
    } catch (error) {
      console.error('Login error:', error);
      throw error;
    }
  }

  async logout(): Promise<void> {
    try {
      // Remove stored data
      await AsyncStorage.multiRemove(['userToken', 'userData', 'rememberMe']);
    } catch (error) {
      console.error('Logout error:', error);
      throw error;
    }
  }
  
  async isLoggedIn(): Promise<boolean> {
    try {
      const token = await AsyncStorage.getItem('userToken');
      return token !== null;
    } catch (error) {
      console.error('Error checking login status:', error);
      return false;
    }
  }
}

export default new AuthService();
```

### When to use AsyncStorage:

- Authentication tokens
- User preferences
- App configuration
- Cached data that should persist between app launches
- Form data that should be saved if the app closes

## Context API (When Needed)

For cases where state needs to be shared across multiple components, use the Context API:

```typescript
// src/navigation/NavigationContext.tsx
import React, { createContext, useState, useContext, ReactNode } from 'react';

interface NavigationContextType {
  currentScreen: string;
  setCurrentScreen: (screen: string) => void;
  previousScreen: string | null;
  navigateBack: () => void;
}

const NavigationContext = createContext<NavigationContextType | undefined>(undefined);

export const NavigationProvider: React.FC<{children: ReactNode}> = ({ children }) => {
  const [currentScreen, setCurrentScreen] = useState<string>('Home');
  const [previousScreen, setPreviousScreen] = useState<string | null>(null);
  
  const handleSetCurrentScreen = (screen: string) => {
    setPreviousScreen(currentScreen);
    setCurrentScreen(screen);
  };
  
  const navigateBack = () => {
    if (previousScreen) {
      setCurrentScreen(previousScreen);
      setPreviousScreen(null);
    }
  };
  
  return (
    <NavigationContext.Provider 
      value={{ 
        currentScreen, 
        setCurrentScreen: handleSetCurrentScreen,
        previousScreen,
        navigateBack
      }}
    >
      {children}
    </NavigationContext.Provider>
  );
};

export const useNavigation = () => {
  const context = useContext(NavigationContext);
  if (context === undefined) {
    throw new Error('useNavigation must be used within a NavigationProvider');
  }
  return context;
};
```

### When to use Context API:

- Theme information
- Authentication state (when needed across many components)
- Navigation state
- Localization data
- Application-wide preferences

## Best Practices

1. **Keep state as local as possible** - Only lift state up when necessary
2. **Use TypeScript** - Define proper interfaces for all state
3. **Implement proper error handling** - Always handle errors in async operations
4. **Separate concerns** - Keep UI state separate from data state
5. **Optimize performance** - Use memoization techniques like `useMemo` and `useCallback`
6. **Consistent patterns** - Use similar patterns across the application
7. **Minimize state** - Only track what's necessary in state
8. **Document state management** - Add comments explaining complex state logic

const selectUsers = (state) => state.users.data;
const selectCurrentUserId = (state) => state.auth.user?.id;

export const selectCurrentUser = createSelector(
  [selectUsers, selectCurrentUserId],
  (users, currentUserId) => {
    if (!users || !currentUserId) return null;
    return users.find(user => user.id === currentUserId);
  }
);

export const selectActiveUsers = createSelector(
  [selectUsers],
  (users) => users.filter(user => user.isActive)
);
```

## Persistence

For persisting state across app restarts:

```javascript
// src/store/index.js
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers';

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  whitelist: ['auth', 'userPreferences'], // only these reducers will be persisted
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],
      },
    }),
});

export const persistor = persistStore(store);
```

## State Management Best Practices

1. **Single Source of Truth**: Store overlapping data in only one place
2. **Immutable Updates**: Always use immutable patterns for updating state
3. **Normalize Complex Data**: Use normalized state structure for relational data
4. **Minimal State**: Only store essential application state
5. **Separate UI State**: Keep UI state separate from domain/data state
6. **Smart/Dumb Components**: Use container/presentational pattern
7. **Consistent Pattern**: Choose specific patterns for specific state needs
8. **Avoid Prop Drilling**: Use Context or Redux instead of passing props deeply

```

--------------------------------------------------------------------------------
/resources/code-examples/react-native/screens/PostLogin/Calendar/CalendarScreen.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { useState, useEffect, useMemo } from 'react';
import { View, Text, ScrollView, TouchableOpacity } from 'react-native';
import { Calendar } from 'react-native-calendars';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { styles } from './Styles';
import axiosRequest from '../../../helper/axiosRequest';
import { API } from '../../../helper/config';
import axios from 'axios';
import { colors } from '../../../theme/colors';

interface CalendarEvent {
  event_id: string;
  event_title: string;
  event_content: string;
  event_date: string;
  event_to_time: string;
  event_from_time: string;
  event_street_address: string;
  event_apt_suite: string;
  event_city: string;
  event_state: string;
  event_zip: string;
  event_longitude: string | null;
  event_latitude: string | null;
  event_price: string | null;
}

interface MarkedDates {
  [date: string]: {
    marked?: boolean;
    selected?: boolean;
    dotColor?: string;
  };
}

const CalendarScreen = ({ navigation }: any) => {
  const [selectedDate, setSelectedDate] = useState(new Date().toISOString().split('T')[0]);
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [markedDates, setMarkedDates] = useState<MarkedDates>({});

  const fetchEvents = async () => {
    try {
      // Try to get token from both possible storage locations
      let token = await AsyncStorage.getItem('userToken');
      if (!token) {
        const userDataStr = await AsyncStorage.getItem('userData');
        if (userDataStr) {
          const userData = JSON.parse(userDataStr);
          token = userData?.loginInfo?.token;
        }
      }

      if (!token) {
        console.error('No token found in either storage location');
        return;
      }

      console.log('Fetching events with token');
      const response = await axiosRequest.get(API.ENDPOINTS.GET_EVENTS, {
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        params: { 
          month: new Date(selectedDate).getMonth() + 1, // Adding 1 because getMonth() returns 0-11
          year: new Date(selectedDate).getFullYear()
        }
      });
      
      console.log('Events API Response:', response);

      if (response?.data?.status === 'ok' && Array.isArray(response?.data?.listing)) {
        const eventsData = response.data.listing;
        console.log('Events found:', eventsData);
        setEvents(eventsData);
        
        // Mark dates that have events
        const marked: MarkedDates = {};
        eventsData.forEach((event: CalendarEvent) => {
          const eventDate = event.event_date;
          marked[eventDate] = {
            marked: true,
            dotColor: colors.tertiary
          };
        });
        
        // Also mark the selected date
        const selectedDateKey = new Date(selectedDate).toISOString().split('T')[0];
        marked[selectedDateKey] = {
          ...marked[selectedDateKey],
          selected: true,
          selectedColor: colors.primary // Add this to make selected date more visible
        };
        
        setMarkedDates(marked);
      } else {
        console.warn('Unexpected response format:', response);
        setEvents([]);
        setMarkedDates({
          [selectedDate]: {
            selected: true,
            selectedColor: colors.primary
          }
        });
      }
    } catch (error) {
      console.error('Error fetching events:', error);
      if (axios.isAxiosError(error)) {
        console.error('Error details:', {
          status: error.response?.status,
          statusText: error.response?.statusText,
          url: error.config?.url,
          method: error.config?.method,
          headers: error.config?.headers,
          params: error.config?.params,
          response: error.response?.data
        });
      }
      setEvents([]);
      setMarkedDates({
        [selectedDate]: {
          selected: true
        }
      });
    }
  };

  useEffect(() => {
    fetchEvents();
  }, [selectedDate]); // Re-fetch when selected date changes

  useEffect(() => {
    console.log('Selected date changed to:', selectedDate);
    console.log('Current events:', events);
    console.log('Filtered events:', filteredEvents);
  }, [selectedDate, events, filteredEvents]);

  const onDayPress = (day: any) => {
    console.log('Day pressed - raw data:', day);
    const newSelectedDate = day.dateString;
    console.log('Setting new selected date:', newSelectedDate);
    
    // Update marked dates to include the new selection
    const newMarkedDates = { ...markedDates };
    
    // Remove selected state from previous date
    const previousSelectedDateKey = new Date(selectedDate).toISOString().split('T')[0];
    if (markedDates[previousSelectedDateKey]) {
      newMarkedDates[previousSelectedDateKey] = {
        ...markedDates[previousSelectedDateKey],
        selected: false
      };
      // If the date only had selected: true, remove it entirely
      if (!newMarkedDates[previousSelectedDateKey].marked) {
        delete newMarkedDates[previousSelectedDateKey];
      }
    }
    
    // Add selected state to new date
    newMarkedDates[newSelectedDate] = {
      ...markedDates[newSelectedDate],
      selected: true
    };
    
    // Update states
    setMarkedDates(newMarkedDates);
    setSelectedDate(newSelectedDate);
  };

  // Filter events for selected date
  const filteredEvents = useMemo(() => {
    console.log('Filtering events for date:', selectedDate);
    console.log('Available events:', events);
    const filtered = events.filter(event => event.event_date === selectedDate);
    console.log('Filtered events for selected date:', filtered);
    return filtered;
  }, [events, selectedDate]);

  const formatDate = (dateString: string) => {
    console.log('Formatting date:', dateString);
    try {
      const [year, month, day] = dateString.split('-').map(num => parseInt(num, 10));
      const date = new Date(year, month - 1, day); // month is 0-based in Date constructor
      console.log('Constructed date:', date);
      return date.toLocaleDateString('en-US', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      });
    } catch (error) {
      console.error('Error formatting date:', error);
      return dateString;
    }
  };

  const formattedSelectedDate = useMemo(() => {
    return formatDate(selectedDate);
  }, [selectedDate]);

  useEffect(() => {
    console.log('Selected date state updated:', selectedDate);
    console.log('Formatted date:', formatDate(selectedDate));
  }, [selectedDate]);

  const formatTime = (timeStr: string) => {
    const [hours, minutes] = timeStr.split(':');
    const date = new Date();
    date.setHours(parseInt(hours, 10));
    date.setMinutes(parseInt(minutes, 10));
    return date.toLocaleTimeString('en-US', {
      hour: 'numeric',
      minute: '2-digit',
      hour12: true
    });
  };

  return (
    <View style={styles.container}>
      <Calendar
        style={styles.calendar}
        onDayPress={onDayPress}
        markedDates={markedDates}
        theme={{
          selectedDayBackgroundColor: colors.secondary,
          selectedDayTextColor: colors.white,
          todayTextColor: colors.primary,
          dotColor: colors.danger,
          arrowColor: colors.dark,
          monthTextColor: colors.dark,
          textDayFontWeight: '300',
          textMonthFontWeight: 'bold',
          textDayHeaderFontWeight: '500',
          textDayColor: colors.tertiary,
          textDayHeaderColor: colors.secondary
        }}
      />
      <View style={[styles.sectionHeader, { padding: 20, marginVertical: 15 }]}>
        <Text style={[styles.sectionTitle, { fontSize: 20, fontWeight: '600' }]}>
          Events for {formatDate(selectedDate)}
        </Text>
      </View>
      <ScrollView style={styles.eventsContainer}>
        {filteredEvents.length > 0 ? (
          filteredEvents.map((event) => (
            <TouchableOpacity
              key={event.event_id}
              style={styles.eventCard}
              onPress={() => navigation.navigate('EventDetails', { event })}
            >
              <Text style={styles.eventTitle}>{event.event_title}</Text>
              <Text style={styles.eventTime}>
                {formatTime(event.event_from_time)} - {formatTime(event.event_to_time)}
              </Text>
              <Text style={styles.eventLocation}>
                {event.event_street_address}
                {event.event_apt_suite ? `, ${event.event_apt_suite}` : ''}
                {event.event_city ? `, ${event.event_city}` : ''}
                {event.event_state ? `, ${event.event_state}` : ''}
                {event.event_zip ? ` ${event.event_zip}` : ''}
              </Text>
            </TouchableOpacity>
          ))
        ) : (
          <Text style={styles.noEventsText}>No events on this date</Text>
        )}
      </ScrollView>
    </View>
  );
};

export default CalendarScreen;

```

--------------------------------------------------------------------------------
/resources/code-examples/react-native/navigation/DrawerNavigator.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react';
import { withNavigationWrapper } from './NavigationWrapper';
import { View, StyleSheet, Platform, TouchableOpacity } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/Ionicons';
import authService from '../services/authService';
import TabNavigator from './TabNavigator';
import AboutUsScreen from '../screens/PostLogin/AboutUs/AboutUsScreen';
import CalendarScreen from '../screens/PostLogin/Calendar/CalendarScreen';
import EventDetails from '../screens/PostLogin/Calendar/EventDetails';
import MyProfileScreen from '../screens/PostLogin/MyProfile/MyProfileScreen';
import EditProfileScreen from '../screens/PostLogin/EditProfile/EditProfileScreen';
import ChangePasswordScreen from '../screens/PostLogin/ChangePassword/ChangePasswordScreen';
import BluestoneAppsAIScreen from '../screens/PostLogin/BluestoneAppsAI/BluestoneAppsAIScreen';
import HomeScreen from '../screens/PostLogin/Home/HomeScreen';
import ContactScreen from '../screens/PostLogin/Contact/ContactScreen';
import PostsScreen from '../screens/PostLogin/Posts/PostsScreen';
import PostScreen from '../screens/PostLogin/Posts/PostScreen';
import { colors } from '../theme/colors';

const Drawer = createDrawerNavigator();

// Create a wrapper component that combines screen content with TabNavigator
const ScreenWrapper = ({ children, navigation }: { children: React.ReactNode; navigation: any }) => {
  return (
    <View style={styles.container}>
      <View style={styles.contentWrapper}>
        {React.cloneElement(children as React.ReactElement, { navigation })}
      </View>
      <View style={styles.tabNavigator}>
        <TabNavigator />
      </View>
    </View>
  );
};

// Create screen-specific wrappers
const AboutUsWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <AboutUsScreen />
  </ScreenWrapper>
));

const HomeWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <HomeScreen />
  </ScreenWrapper>
));

const CalendarWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <CalendarScreen />
  </ScreenWrapper>
));

const EventDetailsWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <EventDetails />
  </ScreenWrapper>
));

const ProfileWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <MyProfileScreen />
  </ScreenWrapper>
));

const EditProfileWrapper = withNavigationWrapper(({ navigation }: any) => (
  <View style={styles.container}>
    <EditProfileScreen navigation={navigation} />
  </View>
));

const ChangePasswordWrapper = withNavigationWrapper(({ navigation }: any) => (
  <View style={styles.container}>
    <ChangePasswordScreen navigation={navigation} />
  </View>
));

const AIWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <BluestoneAppsAIScreen />
  </ScreenWrapper>
));

const ContactWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <ContactScreen />
  </ScreenWrapper>
));

const PostWrapper = withNavigationWrapper(({ navigation }: any) => (
  <ScreenWrapper navigation={navigation}>
    <PostScreen />
  </ScreenWrapper>
));

const DrawerNavigator = ({ navigation }: any) => {
  const handleLogout = async () => {
    try {
      // Call the logout service
      await authService.logout();
    } catch (error) {
      console.error('Logout error:', error);
    } finally {
      // Always navigate to login screen, even if there was an error in logout
      navigation.reset({
        index: 0,
        routes: [{ name: 'Login' }],
      });
    }
  };

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Drawer.Navigator
        screenOptions={{
          headerShown: true,
          headerStyle: {
            backgroundColor: colors.headerBg,
            elevation: 0,
            shadowOpacity: 0,
            borderBottomWidth: 1,
            borderBottomColor: colors.light,
          },
          headerTintColor: colors.headerFont,
          headerTitleStyle: {
            fontWeight: '600',
            color: colors.headerFont,
          },
          drawerStyle: {
            backgroundColor: colors.white,
            width: 280,
          },
          drawerActiveBackgroundColor: colors.footerBg,
          drawerActiveTintColor: colors.footerFont,
          drawerInactiveTintColor: colors.dark,
        }}
      >
        <Drawer.Screen
          name="Home"
          component={HomeWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="home-outline" size={24} color={color} />
            ),
          }}
        />
        <Drawer.Screen
          name="MyProfile"
          component={ProfileWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="person-outline" size={24} color={color} />
            ),
            drawerLabel: 'My Profile',
          }}
        />
        {/* Temporarily hidden Bluestone AI screen */}
        {/* <Drawer.Screen
          name="BluestoneAI"
          component={AIWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="bulb-outline" size={24} color={color} />
            ),
            drawerLabel: 'Bluestone AI',
          }}
        /> */}
        <Drawer.Screen
          name="Calendar"
          component={CalendarWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="calendar-outline" size={24} color={color} />
            ),
            drawerLabel: 'Calendar',
          }}
        />
        <Drawer.Screen
          name="EventDetails"
          component={EventDetailsWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="calendar-outline" size={24} color={color} />
            ),
            drawerLabel: () => null,
            drawerItemStyle: { display: 'none' },
            headerLeft: () => (
              <Icon
                name="chevron-back"
                size={28}
                color={colors.headerFont}
                style={{ marginLeft: 15 }}
                onPress={() => navigation.navigate('Calendar')}
              />
            ),
          }}
        />
        <Drawer.Screen
          name="About Us"
          component={AboutUsWrapper}
          options={{
            drawerIcon: ({ focused, size, color }) => (
              <Icon name={focused ? 'information-circle' : 'information-circle-outline'} size={size} color={focused ? color : '#666'} />
            ),
          }}
        />
        <Drawer.Screen
          name="Posts"
          component={PostsScreen}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="newspaper-outline" size={24} color={color} />
            ),
            drawerLabel: 'Posts',
          }}
        />
        <Drawer.Screen
          name="Post"
          component={PostWrapper}
          options={{
            drawerItemStyle: { display: 'none' },
            headerLeft: () => (
              <Icon
                name="chevron-back"
                size={28}
                color={colors.headerFont}
                style={{ marginLeft: 15 }}
                onPress={() => navigation.navigate('Posts')}
              />
            ),
            headerStyle: {
              backgroundColor: colors.headerBg,
              elevation: 0,
              shadowOpacity: 0,
              borderBottomWidth: 1,
              borderBottomColor: colors.light,
            },
            headerTitleStyle: {
              color: colors.headerFont,
              fontSize: 18,
            },
          }}
        />
        <Drawer.Screen
          name="EditProfile"
          component={EditProfileWrapper}
          options={{
            drawerItemStyle: { display: 'none' },
            headerTitle: 'Edit Profile'
          }}
        />
        <Drawer.Screen
          name="ChangePassword"
          component={ChangePasswordWrapper}
          options={{
            drawerItemStyle: { display: 'none' },
            headerTitle: 'Change Password'
          }}
        />
        <Drawer.Screen
          name="Contact"
          component={ContactWrapper}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="mail-outline" size={24} color={color} />
            ),
            drawerLabel: 'Contact Us',
            headerTitle: 'Contact Us',
          }}
        />
        <Drawer.Screen
          name="Logout"
          component={EmptyComponent}
          options={{
            drawerIcon: ({ color }) => (
              <Icon name="log-out-outline" size={24} color={color} />
            ),
          }}
          listeners={{
            drawerItemPress: () => handleLogout(),
          }}
        />
      </Drawer.Navigator>
    </GestureHandlerRootView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  contentWrapper: {
    flex: 1,
    marginBottom: Platform.select({
      ios: 80,
      android: 60,
    }),
  },
  content: {
    flex: 1,
  },
  tabNavigator: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: '#fff',
    borderTopWidth: 1,
    borderTopColor: '#e0e0e0',
  },
});

const EmptyComponent = () => null;

export default DrawerNavigator; 
```

--------------------------------------------------------------------------------
/resources/code-examples/react-native/screens/HomeScreen.js:
--------------------------------------------------------------------------------

```javascript
/**
 * HomeScreen Component
 * 
 * Main screen of the application displaying featured content,
 * recent activities, and navigation options.
 */

import React, { useState, useEffect } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  Image,
  FlatList,
  RefreshControl,
  StatusBar,
  SafeAreaView
} from 'react-native';
import { useNavigation } from '@react-navigation/native';

// Import components
import Button from '../components/Button';
import Card from '../components/Card';
import FeatureCarousel from '../components/FeatureCarousel';
import LoadingIndicator from '../components/LoadingIndicator';

// Import services and utilities
import ApiService from '../services/ApiService';
import { useAuth } from '../contexts/AuthContext';
import { formatDate } from '../utils/dateUtils';
import theme from '../theme/theme';

const HomeScreen = () => {
  const navigation = useNavigation();
  const { user } = useAuth();
  
  // State management
  const [featuredItems, setFeaturedItems] = useState([]);
  const [recentActivities, setRecentActivities] = useState([]);
  const [recommendations, setRecommendations] = useState([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState(null);

  // Load data on component mount
  useEffect(() => {
    fetchHomeData();
  }, []);

  // Function to fetch all necessary data
  const fetchHomeData = async () => {
    try {
      setLoading(true);
      setError(null);
      
      // Fetch featured items
      const featuredData = await ApiService.get('/featured', {}, {
        withCache: true,
        cacheTTL: 10 * 60 * 1000 // 10 minutes
      });
      
      // Fetch recent activity
      const activitiesData = await ApiService.get('/activities/recent');
      
      // Fetch personalized recommendations if user is logged in
      let recommendationsData = [];
      if (user) {
        recommendationsData = await ApiService.get('/recommendations');
      }
      
      // Update state with fetched data
      setFeaturedItems(featuredData.items || []);
      setRecentActivities(activitiesData.activities || []);
      setRecommendations(recommendationsData.items || []);
    } catch (err) {
      console.error('Error fetching home data:', err);
      setError('Unable to load content. Please try again later.');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  // Pull-to-refresh handler
  const onRefresh = () => {
    setRefreshing(true);
    fetchHomeData();
  };

  // Navigate to item details
  const handleItemPress = (item) => {
    navigation.navigate('ItemDetails', { itemId: item.id });
  };

  // Render activity item
  const renderActivityItem = ({ item }) => (
    <TouchableOpacity 
      style={styles.activityItem}
      onPress={() => navigation.navigate('ActivityDetails', { activityId: item.id })}
    >
      <Image 
        source={{ uri: item.imageUrl }} 
        style={styles.activityImage}
      />
      <View style={styles.activityContent}>
        <Text style={styles.activityTitle} numberOfLines={1}>
          {item.title}
        </Text>
        <Text style={styles.activityMeta}>
          {formatDate(item.date)} • {item.category}
        </Text>
      </View>
    </TouchableOpacity>
  );

  // Render recommendation item
  const renderRecommendationItem = ({ item }) => (
    <Card 
      style={styles.recommendationCard}
      onPress={() => handleItemPress(item)}
    >
      <Image 
        source={{ uri: item.imageUrl }} 
        style={styles.recommendationImage}
      />
      <View style={styles.recommendationContent}>
        <Text style={styles.recommendationTitle} numberOfLines={2}>
          {item.title}
        </Text>
        <Text style={styles.recommendationDescription} numberOfLines={3}>
          {item.description}
        </Text>
      </View>
    </Card>
  );

  // Loading state
  if (loading && !refreshing) {
    return <LoadingIndicator fullScreen />;
  }

  return (
    <SafeAreaView style={styles.safeArea}>
      <StatusBar barStyle="dark-content" />
      
      <ScrollView
        style={styles.container}
        refreshControl={
          <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh}
            colors={[theme.colors.primary]}
          />
        }
      >
        {/* Welcome section */}
        <View style={styles.welcomeSection}>
          <Text style={styles.welcomeTitle}>
            {user ? `Welcome back, ${user.firstName}!` : 'Welcome to AppName'}
          </Text>
          <Text style={styles.welcomeSubtitle}>
            Discover what's new today
          </Text>
        </View>
        
        {/* Featured carousel */}
        {featuredItems.length > 0 ? (
          <View style={styles.carouselContainer}>
            <FeatureCarousel
              items={featuredItems}
              onItemPress={handleItemPress}
            />
          </View>
        ) : null}
        
        {/* Quick actions */}
        <View style={styles.quickActions}>
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Search')}
          >
            <Image 
              source={require('../assets/icons/search.png')} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Search</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Categories')}
          >
            <Image 
              source={require('../assets/icons/categories.png')} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Categories</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Favorites')}
          >
            <Image 
              source={require('../assets/icons/favorite.png')} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Favorites</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Notifications')}
          >
            <Image 
              source={require('../assets/icons/notification.png')} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Updates</Text>
          </TouchableOpacity>
        </View>
        
        {/* Recent activity section */}
        {recentActivities.length > 0 && (
          <View style={styles.section}>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionTitle}>Recent Activity</Text>
              <TouchableOpacity onPress={() => navigation.navigate('AllActivities')}>
                <Text style={styles.seeAllText}>See All</Text>
              </TouchableOpacity>
            </View>
            
            <FlatList
              data={recentActivities}
              renderItem={renderActivityItem}
              keyExtractor={(item) => item.id.toString()}
              horizontal
              showsHorizontalScrollIndicator={false}
              contentContainerStyle={styles.activitiesList}
            />
          </View>
        )}
        
        {/* Recommendations section (only for logged in users) */}
        {user && recommendations.length > 0 && (
          <View style={styles.section}>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionTitle}>Recommended for You</Text>
              <TouchableOpacity onPress={() => navigation.navigate('Recommendations')}>
                <Text style={styles.seeAllText}>See All</Text>
              </TouchableOpacity>
            </View>
            
            <FlatList
              data={recommendations}
              renderItem={renderRecommendationItem}
              keyExtractor={(item) => item.id.toString()}
              horizontal
              showsHorizontalScrollIndicator={false}
              contentContainerStyle={styles.recommendationsList}
            />
          </View>
        )}
        
        {/* Call to action */}
        <View style={styles.ctaContainer}>
          <Image 
            source={require('../assets/images/cta-background.png')} 
            style={styles.ctaBackground}
          />
          <View style={styles.ctaContent}>
            <Text style={styles.ctaTitle}>Ready to get started?</Text>
            <Text style={styles.ctaDescription}>
              Join thousands of users and start exploring now.
            </Text>
            <Button
              title={user ? "Explore Premium" : "Sign Up Now"}
              onPress={() => navigation.navigate(user ? 'Subscription' : 'Signup')}
              variant="primary"
              style={styles.ctaButton}
            />
          </View>
        </View>
        
        {/* Error message */}
        {error && (
          <View style={styles.errorContainer}>
            <Text style={styles.errorText}>{error}</Text>
            <Button
              title="Try Again"
              onPress={fetchHomeData}
              variant="outline"
              size="small"
              style={styles.retryButton}
            />
          </View>
        )}
        
        {/* Bottom padding */}
        <View style={styles.bottomPadding} />
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: theme.colors.background,
  },
  container: {
    flex: 1,
  },
  welcomeSection: {
    padding: theme.spacing.lg,
  },
  welcomeTitle: {
    ...theme.typography.h4,
    color: theme.colors.textPrimary,
    marginBottom: theme.spacing.xs,
  },
  welcomeSubtitle: {
    ...theme.typography.body,
    color: theme.colors.textSecondary,
  },
  carouselContainer: {
    marginBottom: theme.spacing.lg,
  },
  quickActions: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.xl,
  },
  actionButton: {
    alignItems: 'center',
    width: 70,
  },
  actionIcon: {
    width: 40,
    height: 40,
    marginBottom: theme.spacing.xs,
  },
  actionText: {
    ...theme.typography.caption,
    color: theme.colors.textPrimary,
  },
  section: {
    marginBottom: theme.spacing.xl,
  },
  sectionHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.md,
  },
  sectionTitle: {
    ...theme.typography.h5,
    color: theme.colors.textPrimary,
  },
  seeAllText: {
    ...theme.typography.body,
    color: theme.colors.primary,
  },
  activitiesList: {
    paddingLeft: theme.spacing.lg,
  },
  activityItem: {
    width: 280,
    marginRight: theme.spacing.md,
    borderRadius: theme.borderRadius.md,
    backgroundColor: theme.colors.white,
    ...theme.shadows.sm,
    overflow: 'hidden',
  },
  activityImage: {
    width: '100%',
    height: 150,
    resizeMode: 'cover',
  },
  activityContent: {
    padding: theme.spacing.md,
  },
  activityTitle: {
    ...theme.typography.h6,
    marginBottom: theme.spacing.xs,
  },
  activityMeta: {
    ...theme.typography.caption,
    color: theme.colors.textSecondary,
  },
  recommendationsList: {
    paddingLeft: theme.spacing.lg,
  },
  recommendationCard: {
    width: 200,
    marginRight: theme.spacing.md,
    overflow: 'hidden',
  },
  recommendationImage: {
    width: '100%',
    height: 120,
    resizeMode: 'cover',
  },
  recommendationContent: {
    padding: theme.spacing.md,
  },
  recommendationTitle: {
    ...theme.typography.h6,
    fontSize: 15,
    marginBottom: theme.spacing.xs,
  },
  recommendationDescription: {
    ...theme.typography.caption,
    color: theme.colors.textSecondary,
  },
  ctaContainer: {
    marginHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.xl,
    borderRadius: theme.borderRadius.lg,
    overflow: 'hidden',
    position: 'relative',
    height: 180,
  },
  ctaBackground: {
    position: 'absolute',
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
  ctaContent: {
    padding: theme.spacing.lg,
    backgroundColor: 'rgba(0,0,0,0.5)',
    height: '100%',
    justifyContent: 'center',
  },
  ctaTitle: {
    ...theme.typography.h4,
    color: theme.colors.white,
    marginBottom: theme.spacing.sm,
  },
  ctaDescription: {
    ...theme.typography.body,
    color: theme.colors.white,
    marginBottom: theme.spacing.lg,
  },
  ctaButton: {
    alignSelf: 'flex-start',
  },
  errorContainer: {
    margin: theme.spacing.lg,
    padding: theme.spacing.lg,
    backgroundColor: theme.colors.errorLight,
    borderRadius: theme.borderRadius.md,
    alignItems: 'center',
  },
  errorText: {
    ...theme.typography.body,
    color: theme.colors.error,
    marginBottom: theme.spacing.md,
    textAlign: 'center',
  },
  retryButton: {
    marginTop: theme.spacing.sm,
  },
  bottomPadding: {
    height: 40,
  },
});

export default HomeScreen;

```

--------------------------------------------------------------------------------
/resources/code-examples/react-native/screens/HomeScreen.tsx:
--------------------------------------------------------------------------------

```typescript
/**
 * HomeScreen Component
 * 
 * Main screen of the application displaying featured content,
 * recent activities, and navigation options.
 */

import React, { useState, useEffect } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  Image,
  FlatList,
  RefreshControl,
  StatusBar,
  SafeAreaView,
  ImageSourcePropType
} from 'react-native';
import { useNavigation } from '@react-navigation/native';

// Import components
import Button from '../components/Button';
import Card from '../components/Card';
import FeatureCarousel from '../components/FeatureCarousel';
import LoadingIndicator from '../components/LoadingIndicator';

// Import services and utilities
import ApiService from '../services/ApiService';
import { useAuth } from '../contexts/AuthContext';
import { formatDate } from '../utils/dateUtils';
import theme from '../theme/theme';

// Define interfaces for data types
interface FeaturedItem {
  id: string;
  title: string;
  description: string;
  imageUrl: string;
}

interface Activity {
  id: string;
  title: string;
  date: string;
  category: string;
  imageUrl: string;
}

interface Recommendation {
  id: string;
  title: string;
  description: string;
  imageUrl: string;
}

interface User {
  firstName: string;
}

const HomeScreen: React.FC = () => {
  const navigation = useNavigation();
  const { user } = useAuth() as { user: User | null };
  
  // State management
  const [featuredItems, setFeaturedItems] = useState<FeaturedItem[]>([]);
  const [recentActivities, setRecentActivities] = useState<Activity[]>([]);
  const [recommendations, setRecommendations] = useState<Recommendation[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [refreshing, setRefreshing] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  // Load data on component mount
  useEffect(() => {
    fetchHomeData();
  }, []);

  // Function to fetch all necessary data
  const fetchHomeData = async (): Promise<void> => {
    try {
      setLoading(true);
      setError(null);
      
      // Fetch featured items
      const featuredData = await ApiService.get('/featured', {}, {
        withCache: true,
        cacheTTL: 10 * 60 * 1000 // 10 minutes
      });
      
      // Fetch recent activity
      const activitiesData = await ApiService.get('/activities/recent');
      
      // Fetch personalized recommendations if user is logged in
      let recommendationsData = { items: [] };
      if (user) {
        recommendationsData = await ApiService.get('/recommendations');
      }
      
      // Update state with fetched data
      setFeaturedItems(featuredData.items || []);
      setRecentActivities(activitiesData.activities || []);
      setRecommendations(recommendationsData.items || []);
    } catch (err) {
      console.error('Error fetching home data:', err);
      setError('Unable to load content. Please try again later.');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  };

  // Pull-to-refresh handler
  const onRefresh = (): void => {
    setRefreshing(true);
    fetchHomeData();
  };

  // Navigate to item details
  const handleItemPress = (item: FeaturedItem | Recommendation): void => {
    navigation.navigate('ItemDetails' as never, { itemId: item.id } as never);
  };

  // Render activity item
  const renderActivityItem = ({ item }: { item: Activity }): React.ReactElement => (
    <TouchableOpacity 
      style={styles.activityItem}
      onPress={() => navigation.navigate('ActivityDetails' as never, { activityId: item.id } as never)}
    >
      <Image 
        source={{ uri: item.imageUrl }} 
        style={styles.activityImage}
      />
      <View style={styles.activityContent}>
        <Text style={styles.activityTitle} numberOfLines={1}>
          {item.title}
        </Text>
        <Text style={styles.activityMeta}>
          {formatDate(item.date)} • {item.category}
        </Text>
      </View>
    </TouchableOpacity>
  );

  // Render recommendation item
  const renderRecommendationItem = ({ item }: { item: Recommendation }): React.ReactElement => (
    <Card 
      style={styles.recommendationCard}
      onPress={() => handleItemPress(item)}
    >
      <Image 
        source={{ uri: item.imageUrl }} 
        style={styles.recommendationImage}
      />
      <View style={styles.recommendationContent}>
        <Text style={styles.recommendationTitle} numberOfLines={2}>
          {item.title}
        </Text>
        <Text style={styles.recommendationDescription} numberOfLines={3}>
          {item.description}
        </Text>
      </View>
    </Card>
  );

  // Loading state
  if (loading && !refreshing) {
    return <LoadingIndicator fullScreen />;
  }

  return (
    <SafeAreaView style={styles.safeArea}>
      <StatusBar barStyle="dark-content" />
      
      <ScrollView
        style={styles.container}
        refreshControl={
          <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh}
            colors={[theme.colors.primary]}
          />
        }
      >
        {/* Welcome section */}
        <View style={styles.welcomeSection}>
          <Text style={styles.welcomeTitle}>
            {user ? `Welcome back, ${user.firstName}!` : 'Welcome to AppName'}
          </Text>
          <Text style={styles.welcomeSubtitle}>
            Discover what's new today
          </Text>
        </View>
        
        {/* Featured carousel */}
        {featuredItems.length > 0 ? (
          <View style={styles.carouselContainer}>
            <FeatureCarousel
              items={featuredItems}
              onItemPress={handleItemPress}
            />
          </View>
        ) : null}
        
        {/* Quick actions */}
        <View style={styles.quickActions}>
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Search' as never)}
          >
            <Image 
              source={require('../assets/icons/search.png') as ImageSourcePropType} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Search</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Categories' as never)}
          >
            <Image 
              source={require('../assets/icons/categories.png') as ImageSourcePropType} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Categories</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Favorites' as never)}
          >
            <Image 
              source={require('../assets/icons/favorite.png') as ImageSourcePropType} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Favorites</Text>
          </TouchableOpacity>
          
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => navigation.navigate('Notifications' as never)}
          >
            <Image 
              source={require('../assets/icons/notification.png') as ImageSourcePropType} 
              style={styles.actionIcon}
            />
            <Text style={styles.actionText}>Updates</Text>
          </TouchableOpacity>
        </View>
        
        {/* Recent activity section */}
        {recentActivities.length > 0 && (
          <View style={styles.section}>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionTitle}>Recent Activity</Text>
              <TouchableOpacity onPress={() => navigation.navigate('AllActivities' as never)}>
                <Text style={styles.seeAllText}>See All</Text>
              </TouchableOpacity>
            </View>
            
            <FlatList
              data={recentActivities}
              renderItem={renderActivityItem}
              keyExtractor={(item) => item.id.toString()}
              horizontal
              showsHorizontalScrollIndicator={false}
              contentContainerStyle={styles.activitiesList}
            />
          </View>
        )}
        
        {/* Recommendations section (only for logged in users) */}
        {user && recommendations.length > 0 && (
          <View style={styles.section}>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionTitle}>Recommended for You</Text>
              <TouchableOpacity onPress={() => navigation.navigate('Recommendations' as never)}>
                <Text style={styles.seeAllText}>See All</Text>
              </TouchableOpacity>
            </View>
            
            <FlatList
              data={recommendations}
              renderItem={renderRecommendationItem}
              keyExtractor={(item) => item.id.toString()}
              horizontal
              showsHorizontalScrollIndicator={false}
              contentContainerStyle={styles.recommendationsList}
            />
          </View>
        )}
        
        {/* Call to action */}
        <View style={styles.ctaContainer}>
          <Image 
            source={require('../assets/images/cta-background.png') as ImageSourcePropType} 
            style={styles.ctaBackground}
          />
          <View style={styles.ctaContent}>
            <Text style={styles.ctaTitle}>Ready to get started?</Text>
            <Text style={styles.ctaDescription}>
              Join thousands of users and start exploring now.
            </Text>
            <Button
              title={user ? "Explore Premium" : "Sign Up Now"}
              onPress={() => navigation.navigate(user ? 'Subscription' as never : 'Signup' as never)}
              style={styles.ctaButton}
            />
          </View>
        </View>
        
        {/* Error message */}
        {error && (
          <View style={styles.errorContainer}>
            <Text style={styles.errorText}>{error}</Text>
            <Button
              title="Try Again"
              onPress={fetchHomeData}
              style={styles.retryButton}
            />
          </View>
        )}
        
        {/* Bottom padding */}
        <View style={styles.bottomPadding} />
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: theme.colors.background,
  },
  container: {
    flex: 1,
  },
  welcomeSection: {
    padding: theme.spacing.lg,
  },
  welcomeTitle: {
    ...theme.typography.h4,
    color: theme.colors.textPrimary,
    marginBottom: theme.spacing.xs,
  },
  welcomeSubtitle: {
    ...theme.typography.body,
    color: theme.colors.textSecondary,
  },
  carouselContainer: {
    marginBottom: theme.spacing.lg,
  },
  quickActions: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.xl,
  },
  actionButton: {
    alignItems: 'center',
    width: 70,
  },
  actionIcon: {
    width: 40,
    height: 40,
    marginBottom: theme.spacing.xs,
  },
  actionText: {
    ...theme.typography.caption,
    color: theme.colors.textPrimary,
  },
  section: {
    marginBottom: theme.spacing.xl,
  },
  sectionHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.md,
  },
  sectionTitle: {
    ...theme.typography.h5,
    color: theme.colors.textPrimary,
  },
  seeAllText: {
    ...theme.typography.body,
    color: theme.colors.primary,
  },
  activitiesList: {
    paddingLeft: theme.spacing.lg,
  },
  activityItem: {
    width: 280,
    marginRight: theme.spacing.md,
    borderRadius: theme.borderRadius.md,
    backgroundColor: theme.colors.white,
    ...theme.shadows.sm,
    overflow: 'hidden',
  },
  activityImage: {
    width: '100%',
    height: 150,
    resizeMode: 'cover',
  },
  activityContent: {
    padding: theme.spacing.md,
  },
  activityTitle: {
    ...theme.typography.h6,
    marginBottom: theme.spacing.xs,
  },
  activityMeta: {
    ...theme.typography.caption,
    color: theme.colors.textSecondary,
  },
  recommendationsList: {
    paddingLeft: theme.spacing.lg,
  },
  recommendationCard: {
    width: 200,
    marginRight: theme.spacing.md,
    overflow: 'hidden',
  },
  recommendationImage: {
    width: '100%',
    height: 120,
    resizeMode: 'cover',
  },
  recommendationContent: {
    padding: theme.spacing.md,
  },
  recommendationTitle: {
    ...theme.typography.h6,
    fontSize: 15,
    marginBottom: theme.spacing.xs,
  },
  recommendationDescription: {
    ...theme.typography.caption,
    color: theme.colors.textSecondary,
  },
  ctaContainer: {
    marginHorizontal: theme.spacing.lg,
    marginBottom: theme.spacing.xl,
    borderRadius: theme.borderRadius.lg,
    overflow: 'hidden',
    position: 'relative',
    height: 180,
  },
  ctaBackground: {
    position: 'absolute',
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
  ctaContent: {
    padding: theme.spacing.lg,
    backgroundColor: 'rgba(0,0,0,0.5)',
    height: '100%',
    justifyContent: 'center',
  },
  ctaTitle: {
    ...theme.typography.h4,
    color: theme.colors.white,
    marginBottom: theme.spacing.sm,
  },
  ctaDescription: {
    ...theme.typography.body,
    color: theme.colors.white,
    marginBottom: theme.spacing.lg,
  },
  ctaButton: {
    alignSelf: 'flex-start',
  },
  errorContainer: {
    margin: theme.spacing.lg,
    padding: theme.spacing.lg,
    backgroundColor: theme.colors.errorLight,
    borderRadius: theme.borderRadius.md,
    alignItems: 'center',
  },
  errorText: {
    ...theme.typography.body,
    color: theme.colors.error,
    marginBottom: theme.spacing.md,
    textAlign: 'center',
  },
  retryButton: {
    marginTop: theme.spacing.sm,
  },
  bottomPadding: {
    height: 40,
  },
});

export default HomeScreen;

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { glob } from 'glob';

// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Base directory for resources
const BASE_DIR = path.resolve(__dirname, '..');
const RESOURCES_DIR = path.join(BASE_DIR, "resources");
const CODE_EXAMPLES_DIR = path.join(RESOURCES_DIR, "code-examples");

// Create server instance
const server = new McpServer({
  name: "bluestoneapps",
  version: "0.2.1",
  capabilities: {
    tools: {},
  },
});

// Helper function to get standard content
function getStandardContent(category: string, standardId: string): { content?: string; error?: string } {
  const standardPath = path.join(RESOURCES_DIR, category, `${standardId}.md`);
  
  if (!fs.existsSync(standardPath)) {
    return { error: `Standard ${standardId} not found` };
  }
  
  try {
    const content = fs.readFileSync(standardPath, 'utf8');
    return { content };
  } catch (err) {
    console.error(`Error reading standard ${standardId}:`, err);
    return { error: `Error reading standard ${standardId}` };
  }
}

// Helper function to find file in subdirectories
function findFileInSubdirectories(baseDir: string, fileName: string, extensions: string[] = ['.js', '.jsx', '.ts', '.tsx']) {
  // First, try with exact filename match
  let files = glob.sync(`${baseDir}/**/${fileName}`);
  if (files.length > 0) {
    return files[0];
  }
  
  // Then try with file name + extensions
  for (const ext of extensions) {
    const fileWithExt = `${fileName}${ext}`;
    files = glob.sync(`${baseDir}/**/${fileWithExt}`);
    if (files.length > 0) {
      return files[0];
    }
  }
  
  return null;
}

// Helper function to get example content
function getExampleContent(subcategory: string, filename: string): { content?: string[]; path?: string; error?: string } {
  const searchDir = path.join(CODE_EXAMPLES_DIR, "react-native", subcategory);
  
  const filePath = findFileInSubdirectories(searchDir, filename);
  
  if (!filePath || !fs.existsSync(filePath)) {
    return { error: `Example ${filename} not found` };
  }
  
  try {
    const content = fs.readFileSync(filePath, 'utf8');
    return {
      content: [content],
      path: path.relative(BASE_DIR, filePath)
    };
  } catch (err) {
    console.error(`Error reading example ${filename}:`, err);
    return { error: `Error reading example ${filename}` };
  }
}

// Find closest match implementation
function findClosestMatch(directory: string, searchName: string, extensions: string[] = ['.js', '.jsx', '.ts', '.tsx']) {
  if (!fs.existsSync(directory)) return null;
  
  let closestMatch = null;
  
  for (const ext of extensions) {
    const files = glob.sync(`${directory}/**/*${ext}`);
    
    for (const filePath of files) {
      const fileName = path.basename(filePath);
      const fileNameNoExt = path.basename(fileName, path.extname(fileName));
      
      if (fileNameNoExt.toLowerCase().includes(searchName.toLowerCase())) {
        closestMatch = fileNameNoExt;
        break;
      }
    }
    
    if (closestMatch) break;
  }
  
  return closestMatch;
}

// List all available examples
function listAvailableExamples() {
  const examples: Record<string, string[]> = {
    components: [],
    hooks: [],
    services: [],
    screens: [],
    themes: []
  };
  
  const categories = [
    { key: "components", dir: "components" },
    { key: "hooks", dir: "hooks" },
    { key: "services", dir: "services" },
    { key: "screens", dir: "screens" },
    { key: "themes", dir: "theme" }
  ];
  
  const extensions = ['.js', '.jsx', '.ts', '.tsx'];
  
  for (const category of categories) {
    const dirPath = path.join(CODE_EXAMPLES_DIR, "react-native", category.dir);
    if (fs.existsSync(dirPath)) {
      for (const ext of extensions) {
        const files = glob.sync(`${dirPath}/**/*${ext}`);
        for (const filePath of files) {
          const fileName = path.basename(filePath);
          const fileNameNoExt = path.basename(fileName, path.extname(fileName));
          examples[category.key].push(fileNameNoExt);
        }
      }
    }
  }
  
  return examples;
}

// Register tools
// 1. Get project structure
server.tool(
  "get_project_structure",
  "Get project structure standards for React Native development",
  {},
  async () => {
    const result = getStandardContent("standards", "project_structure");
    
    return {
      content: [
        {
          type: "text",
          text: result.content ?? result.error ?? "Error: No content or error message available",
        },
      ],
    };
  },
);

// 2. Get API communication
server.tool(
  "get_api_communication",
  "Get API communication standards for React Native development",
  {},
  async () => {
    const result = getStandardContent("standards", "api_communication");
    
    return {
      content: [
        {
          type: "text",
          text: result.content ?? result.error ?? "Error: No content or error message available",
        },
      ],
    };
  },
);

// 3. Get component design
server.tool(
  "get_component_design",
  "Get component design standards for React Native development",
  {},
  async () => {
    const result = getStandardContent("standards", "component_design");
    
    return {
      content: [
        {
          type: "text",
          text: result.content ?? result.error ?? "Error: No content or error message available",
        },
      ],
    };
  },
);

// 4. Get state management
server.tool(
  "get_state_management",
  "Get state management standards for React Native development",
  {},
  async () => {
    const result = getStandardContent("standards", "state_management");
    
    return {
      content: [
        {
          type: "text",
          text: result.content ?? result.error ?? "Error: No content or error message available",
        },
      ],
    };
  },
);

// 5. Get component example
server.tool(
  "get_component_example",
  "Get a React Native component example",
  {
    component_name: z.string().describe("Component Name"),
  },
  async ({ component_name }) => {
    if (!component_name) {
      return {
        content: [
          {
            type: "text",
            text: "Component name not specified",
          },
        ],
      };
    }
    
    try {
      // First try exact match
      const result = getExampleContent("components", component_name);
      
      if (result.error) {
        // Try to find by fuzzy match
        const componentsDir = path.join(CODE_EXAMPLES_DIR, "react-native", "components");
        const closestMatch = findClosestMatch(componentsDir, component_name);
        
        if (closestMatch) {
          const fuzzyResult = getExampleContent("components", closestMatch);
          return {
            content: [
              {
                type: "text",
                text: fuzzyResult.content?.[0] ?? fuzzyResult.error ?? "Error: No content available",
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: "text",
                text: `Component ${component_name} not found`,
              },
            ],
          };
        }
      }
      
      return {
        content: [
          {
            type: "text",
            text: result.content?.[0] ?? result.error ?? "Error: No content available",
          },
        ],
      };
    } catch (err) {
      console.error(`Error getting component example ${component_name}:`, err);
      return {
        content: [
          {
            type: "text",
            text: `Error getting component example: ${err}`,
          },
        ],
      };
    }
  },
);

// 6. Get hook example
server.tool(
  "get_hook_example",
  "Get a React Native hook example",
  {
    hook_name: z.string().describe("Hook Name"),
  },
  async ({ hook_name }) => {
    if (!hook_name) {
      return {
        content: [
          {
            type: "text",
            text: "Hook name not specified",
          },
        ],
      };
    }
    
    try {
      // First try exact match
      const result = getExampleContent("hooks", hook_name);
      
      if (result.error) {
        // Try to find by fuzzy match
        const hooksDir = path.join(CODE_EXAMPLES_DIR, "react-native", "hooks");
        const closestMatch = findClosestMatch(hooksDir, hook_name);
        
        if (closestMatch) {
          const fuzzyResult = getExampleContent("hooks", closestMatch);
          return {
            content: [
              {
                type: "text",
                text: fuzzyResult.content?.[0] ?? fuzzyResult.error ?? "Error: No content available",
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: "text",
                text: `Hook ${hook_name} not found`,
              },
            ],
          };
        }
      }
      
      return {
        content: [
          {
            type: "text",
            text: result.content?.[0] ?? result.error ?? "Error: No content available",
          },
        ],
      };
    } catch (err) {
      console.error(`Error getting hook example ${hook_name}:`, err);
      return {
        content: [
          {
            type: "text",
            text: `Error getting hook example: ${err}`,
          },
        ],
      };
    }
  },
);

// 7. Get service example
server.tool(
  "get_service_example",
  "Get a React Native service example",
  {
    service_name: z.string().describe("Service Name"),
  },
  async ({ service_name }) => {
    if (!service_name) {
      return {
        content: [
          {
            type: "text",
            text: "Service name not specified",
          },
        ],
      };
    }
    
    try {
      // First try exact match
      const result = getExampleContent("services", service_name);
      
      if (result.error) {
        // Try to find by fuzzy match
        const servicesDir = path.join(CODE_EXAMPLES_DIR, "react-native", "services");
        const closestMatch = findClosestMatch(servicesDir, service_name);
        
        if (closestMatch) {
          const fuzzyResult = getExampleContent("helper", closestMatch);
          return {
            content: [
              {
                type: "text",
                text: fuzzyResult.content?.[0] ?? fuzzyResult.error ?? "Error: No content available",
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: "text",
                text: `Service ${service_name} not found`,
              },
            ],
          };
        }
      }
      
      return {
        content: [
          {
            type: "text",
            text: result.content?.[0] ?? result.error ?? "Error: No content available",
          },
        ],
      };
    } catch (err) {
      console.error(`Error getting service example ${service_name}:`, err);
      return {
        content: [
          {
            type: "text",
            text: `Error getting service example: ${err}`,
          },
        ],
      };
    }
  },
);

// 8. Get screen example
server.tool(
  "get_screen_example",
  "Get a React Native screen example",
  {
    screen_name: z.string().describe("Screen Name"),
  },
  async ({ screen_name }) => {
    if (!screen_name) {
      return {
        content: [
          {
            type: "text",
            text: "Screen name not specified",
          },
        ],
      };
    }
    
    try {
      // First try exact match
      const result = getExampleContent("screens", screen_name);
      
      if (result.error) {
        // Try to find by fuzzy match
        const screensDir = path.join(CODE_EXAMPLES_DIR, "react-native", "screens");
        const closestMatch = findClosestMatch(screensDir, screen_name);
        
        if (closestMatch) {
          const fuzzyResult = getExampleContent("screens", closestMatch);
          return {
            content: [
              {
                type: "text",
                text: fuzzyResult.content?.[0] ?? fuzzyResult.error ?? "Error: No content available",
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: "text",
                text: `Screen ${screen_name} not found`,
              },
            ],
          };
        }
      }
      
      return {
        content: [
          {
            type: "text",
            text: result.content?.[0] ?? result.error ?? "Error: No content available",
          },
        ],
      };
    } catch (err) {
      console.error(`Error getting screen example ${screen_name}:`, err);
      return {
        content: [
          {
            type: "text",
            text: `Error getting screen example: ${err}`,
          },
        ],
      };
    }
  },
);

// 9. Get theme example
server.tool(
  "get_theme_example",
  "Get code for a React Native theme",
  {
    theme_name: z.string().describe("Theme Name"),
  },
  async ({ theme_name }) => {
    if (!theme_name) {
      return {
        content: [
          {
            type: "text",
            text: "Theme name not specified",
          },
        ],
      };
    }
    
    try {
      // First try exact match
      const result = getExampleContent("theme", theme_name);
      
      if (result.error) {
        // Try to find by fuzzy match
        const themesDir = path.join(CODE_EXAMPLES_DIR, "react-native", "theme");
        const closestMatch = findClosestMatch(themesDir, theme_name);
        
        if (closestMatch) {
          const fuzzyResult = getExampleContent("theme", closestMatch);
          return {
            content: [
              {
                type: "text",
                text: fuzzyResult.content?.[0] ?? fuzzyResult.error ?? "Error: No content available",
              },
            ],
          };
        } else {
          return {
            content: [
              {
                type: "text",
                text: `Theme ${theme_name} not found`,
              },
            ],
          };
        }
      }
      
      return {
        content: [
          {
            type: "text",
            text: result.content?.[0] ?? result.error ?? "Error: No content available",
          },
        ],
      };
    } catch (err) {
      console.error(`Error getting theme example ${theme_name}:`, err);
      return {
        content: [
          {
            type: "text",
            text: `Error getting theme example: ${err}`,
          },
        ],
      };
    }
  },
);

// 10. List available examples
server.tool(
  "list_available_examples",
  "List all available code examples by category",
  {},
  async () => {
    try {
      const examples = listAvailableExamples();
      
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(examples, null, 2),
          },
        ],
      };
    } catch (err) {
      console.error("Error listing available examples:", err);
      return {
        content: [
          {
            type: "text",
            text: `Error listing available examples: ${err}`,
          },
        ],
      };
    }
  },
);

// Run the server
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("BluestoneApps MCP Server running on stdio");
}

main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});

```
Page 2/2FirstPrevNextLast