# CLAUDE.md - WooCommerce Plugin React Application

This file provides guidance for working with the Real ID WooCommerce plugin's React frontend application located at `apps/wc-plugin/src/`.

## Application Overview

The WC plugin's React application provides a comprehensive admin interface for WooCommerce merchants to manage ID verification settings, view checks, and configure their store's verification requirements.

### Technical Stack
- **React 18** with functional components and hooks
- **Shopify Polaris** - UI component library for consistent admin interface
- **React Router** - Client-side routing for single-page application
- **Formik** - Form management and validation
- **Axios** - HTTP client for WordPress REST API communication
- **Rebass** - Layout and spacing utilities

## Architecture Overview

### Component Structure
```
src/
├── components/           # React components by feature
│   ├── App.js           # Main application component with routing
│   ├── Settings.js      # Settings page with tabbed interface
│   ├── Home.js          # Dashboard with checks list
│   ├── NewCheck.js      # Manual check creation
│   ├── CheckDetails.js  # Individual check details view
│   ├── settings/        # Settings tab components
│   └── checks/          # Check-related components
├── providers/           # React context providers
├── services/           # API communication layer
├── hooks/              # Custom React hooks
└── utils/              # Utility functions
```

### Data Flow Architecture
```
React Components → WordPress REST API → Core API → External Services
                ↑                    ↓
         ShopProvider Context    Transient Cache
```

## Context Management

### ShopProvider Context
**Location**: `providers/ShopProvider.js`

The central state management for shop data throughout the application:

```javascript
// Context structure
{
  shop: {
    // Core shop data
    name: "shop.example.com",
    licenseKey: "abc123",
    sandboxMode: false,
    
    // Settings
    settings: {
      checkAllOrders: true,
      deliveryMethods: ["checkout"],
      wc: {
        orderStatusMapping: {...},
        excludedOrderStatuses: [...],
      }
    },
    
    // WordPress-specific fields (CRITICAL)
    wc_available_order_statuses: [...], // WooCommerce order statuses
    
    // Billing/subscription data
    usageSubscriptionItems: [...],
    monthlyPlan: "pro",
    usagePlan: "ai"
  },
  setShop: (shopData) => {...} // State setter
}
```

### Hook Usage Patterns
There are **two ways** to access shop context:

1. **Named export** (recommended):
   ```javascript
   import { useShop } from "providers/ShopProvider";
   const { shop, setShop } = useShop();
   ```

2. **Default export** (alternative):
   ```javascript
   import useShop from "hooks/useShop";
   const { shop, setShop } = useShop();
   ```

Both approaches access the same context but use different import patterns.

## Critical Pattern: Complete Shop Data Retrieval

### The Problem
Many operations (license activation, deactivation, settings updates) can return **incomplete shop data** that lacks WordPress-specific fields like `wc_available_order_statuses`. Setting this incomplete data causes React crashes during navigation.

### The Solution Pattern
**ALWAYS** fetch complete shop data after operations that modify shop state:

```javascript
import { getCurrentShop } from "services/wpApi";

// ❌ WRONG - Sets incomplete data
someOperation()
  .then(({ data }) => {
    setShop(data.shop); // Missing WC-specific fields!
  });

// ✅ CORRECT - Fetches complete data
someOperation()
  .then(({ data }) => {
    // Don't set incomplete shop data immediately
    return getCurrentShop();
  })
  .then(({ data: completeShopData }) => {
    setShop(completeShopData); // Complete data with all fields
  })
  .catch((error) => {
    // Handle errors appropriately
  });
```

### Where This Pattern Is Applied

1. **License Activation** (`components/LicensePrompt.js:43-54`)
2. **License Deactivation** (`components/settings/DeactivateLicenseKey.js:37-52`)
3. **Settings Updates** (should follow this pattern)

### Why This Pattern Is Critical

- **Complete Data Structure**: Ensures all WordPress-specific fields are present
- **Prevents Crashes**: Components expect `wc_available_order_statuses` and other WC fields
- **Consistent State**: Maintains same data structure as initial app load
- **Navigation Stability**: Prevents crashes when switching between Settings tabs

## Component Architecture

### Main Application (`components/App.js`)

**Responsibilities**:
- Initial shop data loading with `getCurrentShop()`
- Route management and navigation
- Global state initialization
- Authentication state handling

**Key Features**:
- WordPress admin menu integration via React portals
- Conditional rendering based on shop state
- Error boundaries for unauthorized/failed states
- Loading states during data fetching

### Settings Interface (`components/Settings.js`)

**Structure**: Tabbed interface with 6 main sections:
1. **Triggers** - Automatic ID verification rules
2. **Appearance** - UI customization and branding  
3. **Rules** - ID verification business logic
4. **Notifications** - Email/SMS settings and reminders
5. **WooCommerce** - Platform-specific integration settings
6. **Billing** - License management and subscription details

**Key Patterns**:
- **Formik Integration**: Uses `enableReinitialize` with `getDefaultValues(shop)`
- **Tab State Management**: `selectedTab` state controls which components render
- **Settings Persistence**: Updates saved via `updateSettings()` API call

### Settings Components Best Practices

#### Form Integration
```javascript
// Settings components receive props from Formik context
export default function SettingsComponent({ 
  values, 
  setFieldValue, 
  errors, 
  shop 
}) {
  // Component implementation
}
```

#### Shop Data Access
```javascript
// Access shop data via props (from Settings.js) or context
const { shop } = useShop();

// Always check for data existence
if (!shop?.settings?.specificSetting) {
  return <LoadingState />;
}
```

## API Communication (`services/wpApi.js`)

### WordPress REST API Integration
All API calls go through WordPress REST API routes that proxy to the Core API:

```javascript
// API call pattern
export const apiFunction = (params) => {
  return axios.post(wpRoute("/real-id/v1/endpoint"), params);
};

// Route helper
function wpRoute(path) {
  return window.realIdApiSettings.root + path;
}
```

### Authentication
- Uses WordPress nonce for API authentication
- Automatically added to all requests via axios interceptors
- Nonce provided by WordPress via `window.realIdApiSettings.nonce`

### Key API Functions
- `getCurrentShop()` - Fetch complete shop data (CRITICAL for state management)
- `updateSettings(settings)` - Update shop settings
- `activateLicense({ licenseKey })` - License activation
- `deactivateLicense()` - License deactivation
- `getChecks(params)` - Fetch ID verification checks
- `createCheck(data)` - Create new ID verification check

## React Component Patterns

### Conditional Rendering with Keys

**CRITICAL RULE**: When using **3 or more** conditional branches (nested ternaries) that render different UI states, **ALWAYS** add explicit `key` props to help React distinguish between them.

#### Why This Matters

React's reconciliation algorithm needs to distinguish between different conditional branches to properly update the DOM. Without keys on conditional fragments/divs, React cannot tell which branch is which, causing:

1. **AnimatePresence tracking internal state changes** instead of just component-level changes
2. **iOS WebKit NotFoundError crashes** during DOM manipulation conflicts
3. **Unpredictable animation behavior** as framer-motion tries to animate ambiguous changes
4. **DOM node reuse issues** where React incorrectly reuses nodes between states

#### The Pattern

**❌ WRONG - Nested conditionals without keys**:
```javascript
{state === "A" ? (
  <div>Content A</div>
) : state === "B" ? (
  <div>Content B</div>
) : (
  <div>Content C</div>
)}
```

**✅ CORRECT - Keys on each branch**:
```javascript
{state === "A" ? (
  <div key="a">Content A</div>
) : state === "B" ? (
  <div key="b">Content B</div>
) : (
  <div key="c">Content C</div>
)}
```

#### When to Apply This Rule

Apply keys to conditional branches when:

1. **3+ conditional branches** - Nested ternaries with multiple states
2. **Inside AnimatePresence** - Any conditional rendering within AnimatePresence wrappers
3. **Significantly different DOM structures** - Each branch renders substantially different content
4. **State machine patterns** - Components with multiple discrete UI states
5. **iOS compatibility required** - iOS WebKit is stricter about DOM manipulation

**Exception**: Simple two-branch ternaries usually don't need keys:
```javascript
// ✅ ACCEPTABLE - Simple ternary with 2 branches
{loading ? <Spinner /> : <Content />}
```

#### Debugging Checklist

If you encounter iOS crashes or AnimatePresence issues:

1. ✅ **Check for nested ternaries** - Look for `A ? <X/> : B ? <Y/> : <Z/>`
2. ✅ **Verify keys exist** - Each conditional branch should have a unique `key` prop
3. ✅ **Test state transitions** - Ensure all state changes work on iOS Safari/Chrome
4. ✅ **Check AnimatePresence** - Verify parent has `mode="wait"` and `key={step}` on child
5. ✅ **Use plain divs over fragments** - Fragments don't support key props directly

### useEffect Best Practices
**❌ WRONG - Async function directly in useEffect**:
```javascript
useEffect(async () => {
  const data = await fetchData();
  setData(data);
}, []);
```

**✅ CORRECT - Inner async function**:
```javascript
useEffect(() => {
  const fetchData = async () => {
    try {
      const { data } = await apiCall();
      setData(data);
    } catch (error) {
      handleError(error);
    }
  };
  
  fetchData();
}, []);
```

### Error Handling
```javascript
// Consistent error handling pattern
try {
  const result = await apiCall();
  setToast("Success message");
  // Handle success
} catch (error) {
  console.error(error);
  setToast("Error message for user");
  // Handle error state
}
```

### Loading States
```javascript
const [loading, setLoading] = useState(true);

useEffect(() => {
  const loadData = async () => {
    try {
      setLoading(true);
      const data = await fetchData();
      setData(data);
    } finally {
      setLoading(false);
    }
  };
  
  loadData();
}, []);

return (
  <LoadingScreen isLoading={loading}>
    {/* Component content */}
  </LoadingScreen>
);
```

## Styling and UI

### Shopify Polaris Components
The application uses Shopify Polaris components for consistent UI:
- `Card`, `Layout`, `Button`, `TextField` - Basic UI components
- `Banner`, `Toast` - User feedback components
- `Tabs`, `ContextualSaveBar` - Complex interface components

### Custom Styling
- **TailwindCSS** classes with `ri-` prefix to avoid conflicts
- **Rebass** components (`Box`, `Flex`) for layout
- **CSS-in-JS** for component-specific styles

### WordPress Admin Integration
- Custom CSS to integrate with WordPress admin theme
- Portal-based menu rendering for WordPress admin navigation
- Responsive design for WordPress admin constraints

## Error Handling and Recovery

### Component Error Boundaries
- Unauthorized states render `Unauthorized.js` component
- Network errors render `UnableToRetrieveShop.js` component
- Loading states handled by `LoadingScreen.js` component

### Transient Cache Issues
The application includes recovery mechanisms for corrupted cache data:
- Backend automatically clears corrupted transients
- Frontend refetches data on certain error conditions
- User receives transparent error recovery

### Common Error Scenarios
1. **Invalid License**: Shows license activation prompt
2. **Network Issues**: Shows retry/error messages
3. **Missing Shop Data**: Triggers data refetch
4. **Navigation Crashes**: Prevented by complete data patterns

## Development Guidelines

### Component Creation
1. **Use functional components** with hooks
2. **Follow Polaris design patterns** for UI consistency
3. **Implement proper error handling** for all async operations
4. **Use the shop context properly** - check for data existence
5. **Follow the complete data pattern** for shop state updates

### State Management
1. **Use ShopProvider context** for global shop data
2. **Use local state** for component-specific data
3. **Always fetch complete shop data** after state-changing operations
4. **Handle loading and error states** appropriately

### API Integration
1. **Use services/wpApi.js** for all API calls
2. **Handle promise rejections** with proper error messages
3. **Show user feedback** with toast notifications
4. **Implement loading states** for better UX

## Testing Considerations

### Component Testing
- Test components with mock shop context data
- Test loading states and error conditions
- Verify proper API call patterns
- Test form validation and submission

### Integration Testing
- Test complete user workflows (license activation, settings updates)
- Verify shop context updates correctly
- Test navigation between different Settings tabs
- Verify error recovery mechanisms

## Common Issues and Solutions

### "destroy is not a function" Error
- **Cause**: Async function passed directly to useEffect
- **Fix**: Use inner async function pattern

### React Crashes After License Operations
- **Cause**: Incomplete shop data missing WC-specific fields
- **Fix**: Use complete data retrieval pattern with `getCurrentShop()`

### Settings Not Persisting
- **Cause**: Form submission not calling proper API endpoints
- **Fix**: Ensure `updateSettings()` is called with complete form data

### Navigation Issues
- **Cause**: Shop context corruption or missing data
- **Fix**: Implement proper error boundaries and data validation

This React application provides a robust admin interface for WooCommerce merchants while maintaining consistent data flow and error handling patterns essential for stable operation within the WordPress admin environment.