# Frontend Integration - Step by Step

## Current Status

✅ **API Infrastructure Complete**
- API client with axios interceptors
- Authentication hooks
- All feature hooks (customers, services, resources, appointments, business)
- Playwright testing setup
- Login page component
- Example App.tsx with real auth

✅ **Components Extracted**
- All components from zip copied to `src/*-extracted/` directories
- TypeScript types copied to `src/types.ts`

## Quick Start (5 Minutes)

### 1. Install Dependencies
```bash
cd frontend
npm install
npx playwright install
```

### 2. Start Backend
```bash
# In another terminal
cd backend
docker-compose up
docker-compose exec backend python manage.py migrate
docker-compose exec backend python manage.py createsuperuser
```

### 3. Start Frontend
```bash
npm run dev
```

### 4. Test Login
- Go to `http://lvh.me:5173`
- Login with your superuser credentials
- You should see a welcome screen with your user info!

## Integration Steps

### Step 1: Replace App.tsx

```bash
# Backup current App.tsx
mv src/App.tsx src/App.tsx.backup

# Use the integrated version
mv src/App-integrated.tsx src/App.tsx
```

### Step 2: Copy Components

```bash
# Copy all components at once
cp -r src/components-extracted/* src/components/ 2>/dev/null || true
cp -r src/layouts-extracted/* src/layouts/ 2>/dev/null || true
cp -r src/pages-extracted/* src/pages/ 2>/dev/null || true

# Or copy selectively, one feature at a time (recommended)
```

### Step 3: Update Component Imports

For each component you copy, replace mock data with API hooks.

#### Example: Dashboard.tsx

**Before:**
```typescript
import { APPOINTMENTS, SERVICES } from '../mockData';

const Dashboard = () => {
  const [appointments] = useState(APPOINTMENTS);
  const [services] = useState(SERVICES);
  // ...
}
```

**After:**
```typescript
import { useAppointments } from '../hooks/useAppointments';
import { useServices } from '../hooks/useServices';

const Dashboard = () => {
  const { data: appointments, isLoading: apptLoading } = useAppointments();
  const { data: services, isLoading: servicesLoading } = useServices();

  if (apptLoading || servicesLoading) {
    return <div>Loading...</div>;
  }
  // ...
}
```

#### Example: Customers.tsx

**Before:**
```typescript
import { CUSTOMERS } from '../mockData';

const Customers = () => {
  const [customers] = useState(CUSTOMERS);
  const [searchTerm, setSearchTerm] = useState('');
  // ...
}
```

**After:**
```typescript
import { useCustomers } from '../hooks/useCustomers';

const Customers = () => {
  const [searchTerm, setSearchTerm] = useState('');
  const { data: customers, isLoading } = useCustomers({ search: searchTerm });

  if (isLoading) {
    return <div>Loading...</div>;
  }
  // ...
}
```

#### Example: Scheduler.tsx

**Before:**
```typescript
import { APPOINTMENTS, RESOURCES, SERVICES } from '../mockData';

const Scheduler = () => {
  const [appointments] = useState(APPOINTMENTS);
  const [resources] = useState(RESOURCES);
  const [services] = useState(SERVICES);
  // ...
}
```

**After:**
```typescript
import { useAppointments } from '../hooks/useAppointments';
import { useResources } from '../hooks/useResources';
import { useServices } from '../hooks/useServices';

const Scheduler = () => {
  const { data: appointments, isLoading: apptLoading } = useAppointments();
  const { data: resources, isLoading: resLoading } = useResources();
  const { data: services, isLoading: servicesLoading } = useServices();

  if (apptLoading || resLoading || servicesLoading) {
    return <div>Loading...</div>;
  }
  // ...
}
```

### Step 4: Handle Create/Update/Delete Operations

For mutations, use the mutation hooks:

```typescript
import { useCreateCustomer, useUpdateCustomer, useDeleteCustomer } from '../hooks/useCustomers';

const Customers = () => {
  const { data: customers } = useCustomers();
  const createMutation = useCreateCustomer();
  const updateMutation = useUpdateCustomer();
  const deleteMutation = useDeleteCustomer();

  const handleCreateCustomer = (data: any) => {
    createMutation.mutate(data, {
      onSuccess: () => {
        console.log('Customer created!');
        // Maybe close a modal or reset a form
      },
      onError: (error) => {
        console.error('Failed to create customer:', error);
      }
    });
  };

  const handleUpdateCustomer = (id: string, updates: any) => {
    updateMutation.mutate({ id, updates }, {
      onSuccess: () => {
        console.log('Customer updated!');
      }
    });
  };

  const handleDeleteCustomer = (id: string) => {
    deleteMutation.mutate(id, {
      onSuccess: () => {
        console.log('Customer deleted!');
      }
    });
  };

  return (
    // Your JSX with handlers
    <button onClick={() => handleCreateCustomer(newCustomerData)}>
      Create Customer
    </button>
  );
};
```

### Step 5: Update App.tsx with Full Routing

Once components are copied and updated, implement role-based routing in App.tsx:

```typescript
// Import all your pages
import Dashboard from './pages/Dashboard';
import Scheduler from './pages/Scheduler';
import Customers from './pages/Customers';
// ... etc

const AppContent = () => {
  const { data: user } = useCurrentUser();
  const { data: business } = useCurrentBusiness();

  if (!user) return <LoginPage />;

  // Platform users
  if (['superuser', 'platform_manager', 'platform_support'].includes(user.role)) {
    return (
      <Routes>
        <Route element={<PlatformLayout user={user} />}>
          <Route path="/platform/dashboard" element={<PlatformDashboard />} />
          <Route path="/platform/businesses" element={<PlatformBusinesses />} />
          {/* ... more platform routes */}
        </Route>
      </Routes>
    );
  }

  // Customer users
  if (user.role === 'customer') {
    return (
      <Routes>
        <Route element={<CustomerLayout business={business} user={user} />}>
          <Route path="/" element={<CustomerDashboard />} />
          <Route path="/book" element={<BookingPage />} />
          {/* ... more customer routes */}
        </Route>
      </Routes>
    );
  }

  // Business users (owner, manager, staff, resource)
  return (
    <Routes>
      <Route element={<BusinessLayout business={business} user={user} />}>
        <Route path="/" element={<Dashboard />} />
        <Route path="/scheduler" element={<Scheduler />} />
        <Route path="/customers" element={<Customers />} />
        <Route path="/resources" element={<Resources />} />
        {/* ... more business routes */}
      </Route>
    </Routes>
  );
};
```

## Testing with Playwright

### Run Visual Tests

```bash
# Run tests and compare with extracted frontend
npm run test:headed

# Or use UI mode for debugging
npm run test:ui
```

### Create New Tests

Create test files in `tests/e2e/`:

```typescript
// tests/e2e/customers.spec.ts
import { test, expect } from '@playwright/test';

test.describe('Customers Page', () => {
  test.beforeEach(async ({ page }) => {
    // Login
    await page.goto('/');
    await page.getByLabel(/username/i).fill('testowner');
    await page.getByLabel(/password/i).fill('testpass123');
    await page.getByRole('button', { name: /sign in/i }).click();
    await page.waitForURL(/\//);
  });

  test('should display customers list', async ({ page }) => {
    await page.goto('/customers');

    // Wait for customers to load
    await page.waitForSelector('table tbody tr, [data-testid="customer-list"]');

    // Take screenshot for comparison
    await expect(page).toHaveScreenshot('customers-list.png');
  });

  test('should filter customers by status', async ({ page }) => {
    await page.goto('/customers');

    // Click status filter
    await page.getByRole('button', { name: /filter/i }).click();
    await page.getByRole('option', { name: /active/i }).click();

    // Verify filtered results
    const rows = await page.locator('table tbody tr').count();
    expect(rows).toBeGreaterThan(0);
  });
});
```

## Troubleshooting

### Issue: Types don't match
**Symptom**: TypeScript errors about id being string vs number

**Solution**: The hooks already handle transformation. Make sure you're using the hooks, not calling apiClient directly.

### Issue: Components look different from extracted version
**Symptom**: Visual differences in Playwright screenshots

**Solution**:
1. Check Tailwind classes are identical
2. Verify dark mode is applied correctly
3. Compare CSS files from extracted version
4. Use Playwright UI mode to inspect elements

### Issue: CORS errors in console
**Symptom**: "Access-Control-Allow-Origin" errors

**Solution**:
1. Verify backend is running
2. Check CORS settings in `backend/config/settings/base.py`
3. Ensure `X-Business-Subdomain` header is in CORS_ALLOW_HEADERS

### Issue: 404 on API calls
**Symptom**: API calls return 404

**Solution**:
1. Check you're using correct subdomain: `acme.lvh.me:5173`
2. Verify backend middleware is processing `X-Business-Subdomain` header
3. Check business exists in database with correct subdomain

### Issue: Data not loading
**Symptom**: Components show loading forever

**Solution**:
1. Check browser console for errors
2. Verify backend migrations are applied
3. Create test data in backend
4. Check React Query DevTools (install `@tanstack/react-query-devtools`)

## Adding React Query DevTools

For debugging:

```bash
npm install @tanstack/react-query-devtools
```

In App.tsx:
```typescript
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

<QueryClientProvider client={queryClient}>
  <Router>
    <AppContent />
  </Router>
  <ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
```

## Component Integration Checklist

- [ ] Login page works
- [ ] Dashboard displays
- [ ] Sidebar navigation works
- [ ] Dark mode toggle works
- [ ] Customers page loads data from API
- [ ] Can create new customer
- [ ] Can edit customer
- [ ] Can delete customer
- [ ] Services page loads data
- [ ] Resources page loads data
- [ ] Scheduler displays appointments
- [ ] Can create appointment
- [ ] Can drag-and-drop appointments
- [ ] Settings page loads business data
- [ ] Can update business settings
- [ ] Visual tests pass
- [ ] No console errors

## Next Steps After Basic Integration

1. **Error Boundaries**: Add error boundaries for better error handling
2. **Loading States**: Improve loading UI with skeletons
3. **Optimistic Updates**: Add optimistic updates for better UX
4. **Form Validation**: Add form validation with react-hook-form or similar
5. **Toast Notifications**: Add toast library for success/error messages
6. **Accessibility**: Add ARIA labels and keyboard navigation
7. **Performance**: Optimize re-renders with React.memo
8. **Tests**: Add more comprehensive Playwright tests

## Resources

- **Main Guide**: `../FRONTEND_INTEGRATION_GUIDE.md`
- **Backend API**: `../BACKEND_IMPLEMENTATION_SUMMARY.md`
- **All Hooks**: Check `src/hooks/` directory
- **Type Definitions**: `src/types.ts`
- **Example Components**: `src/*-extracted/` directories

You're ready to integrate! Start with the Dashboard, then move to individual features one by one.
