1. Overview

The Site Listing module is a comprehensive administrative interface for managing physical locations (sites) within the Nimbly audit management system. It provides functionality for viewing, creating, editing, scheduling audits, and [bulk operationss](../Bulk Operation/BulkOperationOverview.md) on sites. The module is built using React with Redux for state management and implements role-based [access control](../Settings/Access control/AccessControlOverview.md).

1.1 Key Capabilities

  • Site Management: Create, view, edit, and delete sites
  • [Bulk Operationss](../Bulk Operation/BulkOperationOverview.md): Perform mass updates on multiple sites simultaneously
  • Scheduling: Configure audit [schedules](../Schedule/Schedule Listing/ScheduleListingOverview.md) for sites
  • Activity Tracking: Monitor site activity history and changes
  • Filtering & Sorting: Advanced search and organization capabilities
  • Department Integration: Associate sites with organizational departments
  • Performance Monitoring: Track site metrics and reporting status

2. Architecture

2.1 High-Level Architecture

graph TB
    subgraph "Frontend Layer"
        A[Site Pages] --> B[Site Components]
        B --> C[Redux Store]
        C --> D[Redux Actions]
        D --> E[API Services]
    end
    
    subgraph "State Layer"
        C --> F[Sites Reducer]
        C --> G[Departments Reducer]
        C --> H[Users Reducer]
        C --> I[Firebase Auth]
    end
    
    subgraph "Backend Layer"
        E --> J[REST APIs]
        J --> K[Database]
    end
    
    style A fill:#e1f5e1
    style C fill:#ffe1e1
    style J fill:#e1e1ff

2.2 Module Structure

The site listing module follows a modular architecture pattern with clear separation of concerns:

  1. Pages Layer (src/pages/sites.js): Entry point for site management
  2. Components Layer (src/components/sites/): Reusable UI components
  3. State Management (src/reducers/sites/): Redux reducers and actions
  4. Routing (src/routes/admin-routes.js): Route definitions
  5. Services: API integration layer

3. Component Structure

3.1 Core Components Hierarchy

graph TD
    A[SitesPage] --> B[Layout]
    A --> C[SitesManager]
    A --> D[Modal Components]
    
    C --> E[SitesListHeader]
    C --> F[SiteTabNavigation]
    C --> G[SitesList]
    
    D --> H[SitesBulkModal]
    D --> I[SitesScheduleModal]
    D --> J[SitesScheduleEditModal]
    D --> K[SitesBulkSchedule]
    D --> L[SitesConfirmModal]
    
    G --> M[SiteItem]
    M --> N[Site Actions]

3.2 Component Details

3.2.1 SitesPage Component

  • Location: src/pages/sites.js
  • Purpose: Main container component that orchestrates the site listing interface
  • Key Props:
    • showBulkModal: Controls bulk operations modal visibility
    • showScheduleModal: Controls scheduling modal visibility
    • selectedSite: Currently selected site object
    • allQuestions: Available questionnaire templates
    • manageState: Administrative state management

3.2.2 SitesManager Component

  • Location: src/components/sites/SitesManager/SitesManager.js
  • Purpose: Core management interface for site operations
  • Responsibilities:
    • Fetches and displays site data
    • Handles pagination and sorting
    • Manages activity history modal
    • Controls tab navigation (Active/Blocked sites)

3.2.3 SitesList Component

  • Location: src/components/sites/SitesList/SitesList.js
  • Purpose: Renders the paginated list of sites with different views for desktop and mobile
  • Key Features:
    • Virtual scrolling using react-window for performance
    • Responsive design (table view for desktop, card view for mobile)
    • Dynamic row height calculation based on content
    • Warning indicators for incomplete site data
    • Direct navigation to site details on click

3.2.4 SitesListHeader Component

3.2.5 Modal Components

3.2.5.1 SitesBulkModal
  • Purpose: Bulk site creation via Excel upload
  • Key Features:
    • Excel file upload and validation
    • Progress tracking for bulk operations
    • Error reporting for failed imports
    • Department association for imported sites
3.2.5.2 SitesQuickScheduleModal
  • Purpose: Quick scheduling interface with calendar
  • Features:
    • Calendar-based schedule selection
    • Multi-site scheduling support
    • Questionnaire template selection
    • Time slot configuration
3.2.5.3 SiteBulkScheduleEditModal
  • Purpose: Bulk editing of existing schedules
  • Features:
    • Multi-schedule selection
    • Batch update operations
    • Conflict detection
    • Schedule validation
3.2.5.4 SiteBulkScheduleModal
  • Purpose: Create multiple schedules simultaneously
  • Features:
    • Excel-based bulk schedule creation
    • Template download functionality
    • Validation and error reporting
3.2.5.5 SiteBlockConfirmationModal
  • Purpose: Confirmation dialog for site blocking/unblocking
  • Features:
    • Schedule impact preview
    • Confirmation messaging
    • Action validation

4. Routes and Navigation

Route PathComponentAccess RequiredDescription
/admin/sitesSitesPageADMIN_SITES_ALLMain site listing page
/admin/sites/:siteKeySitePageADMIN_SITES_ALLIndividual site details
/admin/site-groups/:deptId?SiteGroupsPageADMIN_SITES_ALLSite groups management
/admin/sites/[reports](../Reports/ReportsOverview.md)ReportPageADMIN_SITES_ALLSite reports interface
/admin/bulk-operationsBulkOperationsPageADMIN_SITES_ALLNew bulk operations interface (feature-flagged)

4.2 Navigation Flow

graph LR
    A[Admin Dashboard] --> B[Sites Page]
    B --> C[Site Details]
    B --> D[Site Groups]
    B --> E[Reports](../Reports/ReportsOverview.md)
    B --> F[Bulk Operations]
    
    C --> G[Edit Site]
    C --> H[Schedule Audit]
    C --> I[View Activity]
    
    D --> J[Create Group]
    D --> K[Manage Groups]
    
    style B fill:#ffe1e1
    style C fill:#e1f5e1
    style D fill:#e1e1ff

4.3 Route Protection

All site-related routes implement:

  1. Authentication Check: User must be logged in
  2. Role Validation: User must have appropriate permissions
  3. Feature Flags: Some routes depend on enabled features
  4. Organization Context: Routes may behave differently based on organization settings

5. State Management

5.1 Redux Store Structure

The site listing module uses a comprehensive Redux architecture with actions, reducers, and sagas for async operations.

5.1.1 Sites State Interface

interface SitesState {
  // Data Management
  sites: Site[]
  site: Site | null
  orderedSites: Site[]
  allOrderedSites: Site[]
  paginationSites: Site[]
  
  // Pagination & Filtering
  pageIndex: number
  paginateSites: PaginatedSites
  processedSites: Site[]
  totalSites: number
  totalActive: number
  totalDisabled: number
  filterQuery: string
  
  // Sorting Configuration
  sortBy: string
  colorSelected: string
  name: SortDirection
  auditor: SortDirection
  primaryDepartment: SortDirection
  site: SortDirection
  reports: SortDirection
  status: SortDirection
  color: SortDirection
  supervisor: SortDirection
  updatedAt: SortDirection
  updatedBy: SortDirection
  
  // UI State
  modalVisible: ModalState
  selectedTab: string
  listActiveTab: 'active' | 'blocked'
  selectedSite: Site | null
  scrollPosition: number
  
  // Loading States
  isLoading: boolean
  isConfirmationLoading: boolean
  isSiteLoaded: boolean
  isSitesLoaded: boolean
}

5.1.2 Modal State Management

interface ModalState {
  bulk: boolean
  schedule: boolean
  bulkSchedule: boolean
  bulkScheduleEdit: boolean
  confirmBlockSite: boolean
}

5.2 Key Actions

5.2.1 Data Fetching Actions

ActionPurposeEndpoint
fetchSitesFetch all sites/sites
fetchPaginateSitesFetch paginated sites with filtering/sites/paginate
fetchSiteByIdFetch single site details/sites/{id}/populated
fetchSiteDepartmentsFetch site’s department associations/[departments](../Departments/DepartmentOverview.md)/site/{id}

5.2.2 UI State Actions

ActionPurposeState Changed
setSitesFilterQueryUpdate search filterfilterQuery
setSortSitesChange sort configurationsortBy, sort directions
setPageIndexNavigate to pagepageIndex
setSiteListTabSwitch between active/blockedlistActiveTab
showBulkModalDisplay bulk operations modalmodalVisible.bulk
showScheduleModalDisplay scheduling modalmodalVisible.[schedule](../Schedule/Schedule Listing/ScheduleListingOverview.md)

5.3 Redux Saga Implementation

The module uses Redux Saga for handling async operations and side effects:

graph TB
    A[Component Dispatch] --> B[Action Creator]
    B --> C[Saga Watcher]
    C --> D[Saga Worker]
    D --> E[API Call]
    E --> F[Success/Failure Action]
    F --> G[Reducer Update]
    G --> H[Component Re-render]
    
    style C fill:#ffe1e1
    style D fill:#e1f5e1
    style E fill:#e1e1ff

5.3.1 Key Saga Functions

  1. fetchPaginateSites(limit): Handles paginated data fetching with sorting and filtering
  2. getPopulatedSites(action): Orchestrates the complete site loading process
  3. fetchSiteById(action): Loads individual site with full details
  4. updateSiteDepartments(action): Manages department associations for sites

5.4 Data Flow Patterns

5.4.1 Search and Filter Flow

sequenceDiagram
    participant U as User
    participant C as Component
    participant S as Store
    participant API as API
    
    U->>C: Types in search box
    C->>S: dispatch(setSitesFilterQuery)
    S->>C: filterQuery updated
    C->>S: dispatch(fetchPaginateSites)
    S->>API: GET /sites/paginate?query=...
    API->>S: Return filtered sites
    S->>C: orderedSites updated
    C->>U: Display filtered results

5.4.2 Pagination Flow

  1. User clicks page navigation
  2. setPageIndex action dispatched
  3. fetchPaginateSites triggered with new page
  4. API call with pagination parameters
  5. State updated with new page data
  6. Component re-renders with new sites

5.4.3 Modal Management Flow

All modals follow a consistent pattern:

  1. User triggers modal action (button click)
  2. Show modal action dispatched (showBulkModal, showScheduleModal, etc.)
  3. Modal visibility state updated in Redux
  4. Component conditionally renders modal based on state
  5. Modal operations may trigger additional actions
  6. Dismiss modal action resets visibility state

6. API Endpoints

6.1 Site Data Endpoints

MethodEndpointPurposeFile Location
GET/sitesFetch all sitessites.actionSaga.ts
GET/sites/paginateFetch paginated sites with filteringsites.actionSaga.ts
GET/sites/{siteID}/populatedFetch single site with full detailssites.actionSaga.ts
GET/sites/compactFetch compact site list for dropdownssiteCompact.actionSaga.ts
GET/sites/compact/paginateFetch paginated compact sitessiteCompact.actionSaga.ts
GET/sites/internal/overviewFetch site overview statisticssite.api.ts

6.2 Site Management Endpoints

MethodEndpointPurposeFile Location
POST/sites/Create new sitecreateSite.ts
PUT/sites/{siteID}Update existing siteupdateSite.ts
POST/sites/internalGet internal sites with filterssite.api.ts
PUT/sites/internal/createCreate site internallysite.api.ts
PUT/sites/internal/updateUpdate site internallysite.api.ts

6.3 Site Groups Endpoints

MethodEndpointPurposeFile Location
GET/sites/groupFetch all site groupssiteGroups.services.ts
POST/sites/groupCreate new site groupsiteGroups.services.ts
GET/sites/group/{siteGroupId}Fetch single site groupsiteGroups.services.ts
PUT/sites/group/{siteGroupId}Update site groupsiteGroups.services.ts
PUT/sites/group/toggle-status/{siteGroupId}Toggle site group active statussiteGroups.services.ts

6.4 Department Integration Endpoints

MethodEndpointPurposeFile Location
GET/[departments](../Departments/DepartmentOverview.md)/site/{siteKey}Fetch departments for a sitesites.actionSaga.ts
POST/[departments](../Departments/DepartmentOverview.md)/insert-siteUpdate site department associationssites.actionSaga.ts

6.5 Site Schedule & Off Days Endpoints

MethodEndpointPurposeFile Location
GET/sites/off-days/{siteID}Fetch site off dayssiteOffDays.service.ts
PUT/sites/off-days/{siteID}Update site off dayssiteOffDays.service.ts
GET/[schedules](../Schedule/Schedule Listing/ScheduleListingOverview.md)/activityFetch site schedule activitysiteScheduleActivity.service.ts

6.6 API Integration Patterns

6.6.1 Authentication

All API calls include Firebase authentication tokens in headers:

headers: {
  'Authorization': `Bearer ${firebaseToken}`,
  'Content-Type': 'application/json'
}

6.6.2 Error Handling

The application implements consistent error handling across all endpoints:

  1. Network errors trigger toast notifications
  2. API errors are captured in Redux state
  3. Loading states are managed during API calls
  4. Retry logic for failed requests

6.6.3 Base URL Configuration

The application uses different base URLs for different services:

  • App Engine: ${appengineURL} - Main site operations
  • API: ${apiURL} - Department and group operations
  • Alt API: ${apiURLAlt} - Schedule and activity operations

6.6.4 Request Patterns

Pagination Requests:

GET /sites/paginate?
  page=1&
  limit=20&
  sortBy=name&
  sortDirection=asc&
  filterQuery=search_term&
  status=active

Filter Requests:

POST /sites/internal
{
  "organizationID": "org_id",
  "query": {
    "departments": ["dept1", "dept2"],
    "status": "active",
    "search": "site_name"
  }
}

7. Features and Workflows

7.1 Core Features

7.1.1 Site Listing and Management

  • Paginated Display: Efficient handling of large site datasets
  • Responsive Design: Optimized for both desktop and mobile devices
  • Real-time Updates: Live synchronization with backend changes
  • Bulk Operations: Mass operations on multiple sites simultaneously

7.1.2 Search and Filtering

  • Text Search: Real-time search across site names and descriptions
  • Department Filtering: Filter sites by associated departments
  • Status Filtering: Filter by active/blocked status
  • Advanced Sorting: Multi-column sorting with persistent preferences

7.1.3 Site Status Management

  • Active/Blocked Toggle: Easy status switching with confirmation
  • Schedule Impact Analysis: Preview impact before blocking sites
  • Activity History: Track all site status changes
  • Audit Trail: Complete change tracking with user attribution

7.1.4 Scheduling Integration

  • Quick Schedule: Rapid audit scheduling from site list
  • Bulk Scheduling: Schedule multiple sites simultaneously
  • Schedule Editing: Modify existing schedules in bulk
  • Conflict Detection: Prevent scheduling conflicts

7.2 User Workflows

7.2.1 Site Discovery Workflow

flowchart TD
    A[User visits /admin/sites] --> B[Load Sites List]
    B --> C{Sites Available?}
    C -->|Yes| D[Display Sites Table]
    C -->|No| E[Show Empty State]
    
    D --> F[User can:]
    F --> G[Search Sites]
    F --> H[Filter by Department]
    F --> I[Sort Columns]
    F --> J[Navigate Pages]
    
    G --> K[Update Results]
    H --> K
    I --> K
    J --> K
    
    K --> L[Display Updated List]
    L --> M[User selects action]
    
    M --> N[View Site Details]
    M --> O[Schedule Audit]
    M --> P[Block/Unblock Site]
    M --> Q[View Activity History]

7.2.2 Bulk Operations Workflow

flowchart TD
    A[User clicks Bulk Operations] --> B[Select Operation Type]
    B --> C{Operation Type}
    
    C -->|Create Sites| D[Upload Excel File]
    C -->|Schedule Audits| E[Select Sites & Date]
    C -->|Update Sites| F[Select Sites & Changes]
    
    D --> G[Validate File Format]
    G --> H{Valid?}
    H -->|No| I[Show Errors]
    H -->|Yes| J[Preview Changes]
    
    E --> J
    F --> J
    
    J --> K[User Confirms]
    K --> L[Execute Operation]
    L --> M[Show Progress]
    M --> N[Display Results]
    N --> O[Update Site List]

7.2.3 Site Scheduling Workflow

flowchart TD
    A[User clicks Schedule] --> B{Single or Multiple?}
    B -->|Single Site| C[Quick Schedule Modal]
    B -->|Multiple Sites| D[Bulk Schedule Modal]
    
    C --> E[Select Date & Time]
    D --> F[Upload Schedule Template]
    
    E --> G[Choose Questionnaire]
    F --> H[Validate Schedule Data]
    
    G --> I[Assign Auditor]
    H --> I
    
    I --> J[Check Conflicts]
    J --> K{Conflicts Found?}
    K -->|Yes| L[Show Conflict Resolution]
    K -->|No| M[Create Schedule]
    
    L --> N[User Resolves]
    N --> M
    M --> O[Confirm Success]
    O --> P[Update Calendar]

7.3 Advanced Features

7.3.1 Performance Optimization

  • Virtual Scrolling: Handles thousands of sites without performance degradation
  • Lazy Loading: Components loaded on demand
  • Memoization: Prevents unnecessary re-renders
  • Debounced Search: Reduces API calls during typing

7.3.2 Tutorial Integration

  • Progressive Disclosure: Step-by-step feature introduction
  • Contextual Help: In-app guidance for complex operations
  • Interactive Tooltips: Real-time assistance for UI elements

7.3.3 Accessibility Features

  • Keyboard Navigation: Full keyboard support for all operations
  • Screen Reader Support: ARIA labels and semantic HTML
  • Color Contrast: WCAG-compliant color schemes
  • Focus Management: Proper focus handling in modals

7.3.4 Error Handling and Recovery

  • Graceful Degradation: Fallback UI for failed operations
  • Retry Mechanisms: Automatic retry for failed API calls
  • User Feedback: Clear error messages and resolution steps
  • State Recovery: Maintains user context during errors

8. Data Flow

8.1 Complete Data Flow Architecture

graph TB
    subgraph "User Interface"
        A[Site List View] --> B[Search Input]
        A --> C[Filter Controls]
        A --> D[Sort Headers]
        A --> E[Pagination]
        A --> F[Action Buttons]
    end
    
    subgraph "Component Layer"
        B --> G[SitesListHeader]
        C --> G
        D --> H[SitesList]
        E --> H
        F --> I[Modal Components]
    end
    
    subgraph "State Management"
        G --> J[Sites Actions]
        H --> J
        I --> J
        J --> K[Sites Saga]
        K --> L[Sites Reducer]
        L --> M[Redux Store]
    end
    
    subgraph "API Layer"
        K --> N[Site API Service]
        N --> O[HTTP Client]
        O --> P[REST Endpoints]
    end
    
    subgraph "Backend Services"
        P --> Q[Site Service]
        P --> R[Department Service]
        P --> S[Schedule Service]
        Q --> T[Database]
        R --> T
        S --> T
    end
    
    style M fill:#ffe1e1
    style P fill:#e1f5e1
    style T fill:#e1e1ff

8.2 State Update Flow

sequenceDiagram
    participant UI as User Interface
    participant AC as Action Creator
    participant SG as Saga
    participant API as API Service
    participant RD as Reducer
    participant ST as Store
    
    UI->>AC: User Action (search, filter, etc.)
    AC->>SG: Dispatch Action
    SG->>API: API Call
    API->>SG: Response Data
    SG->>RD: Success/Error Action
    RD->>ST: Update State
    ST->>UI: Re-render Components
    
    Note over SG,API: Async Operation
    Note over RD,ST: Synchronous Update

8.3 Component Communication Patterns

8.3.1 Parent-Child Communication

graph TD
    A[SitesPage] -->|Props| B[SitesManager]
    B -->|Props| C[SitesListHeader]
    B -->|Props| D[SitesList]
    B -->|Props| E[Modal Components]
    
    C -->|Events| B
    D -->|Events| B
    E -->|Events| B
    
    B -->|Redux Actions| F[Global State]
    F -->|State Updates| B

8.3.2 Redux State Flow

graph LR
    A[Component] -->|dispatch| B[Action]
    B --> C[Saga Middleware]
    C -->|API Call| D[External Service]
    D -->|Response| C
    C -->|Success/Error| E[Reducer]
    E --> F[Store]
    F -->|New State| A
    
    style C fill:#ffe1e1
    style E fill:#e1f5e1
    style F fill:#e1e1ff

9. Package Dependencies

9.1 Core Dependencies

PackageVersionPurposeUsage in Module
react^17.0.2Core React libraryAll components and hooks
react-redux^7.2.6Redux React bindingsState management integration
redux^4.1.2State managementGlobal state container
redux-saga^1.1.3Async side effectsAPI calls and complex flows
react-router-dom^5.3.0Client-side routingNavigation between views
styled-components^5.3.3CSS-in-JS stylingComponent styling

9.2 UI and Interaction Dependencies

PackageVersionPurposeUsage in Module
react-window^1.8.6Virtual scrollingLarge site list performance
react-toastify^8.1.0Toast notificationsUser feedback and errors
react-i18next^11.15.1InternationalizationMulti-language support
@loadable/component^5.15.2Code splittingLazy loading of components

9.3 Firebase and Authentication

PackageVersionPurposeUsage in Module
firebase^9.6.1Firebase SDKAuthentication and real-time data
react-redux-firebase^3.10.0Firebase Redux bindingsFirebase state integration

9.4 Utility Dependencies

PackageVersionPurposeUsage in Module
lodash^4.17.21Utility functionsData manipulation and formatting
moment^2.29.1Date/time handlingSchedule formatting and validation
axios^0.25.0HTTP clientAPI requests

9.5 Internal Dependencies

PackagePurposeUsage in Module
@nimbly-technologies/nimbly-commonShared utilities and constantsEnumerators, role resources, features

9.6 Development Dependencies

PackageVersionPurposeUsage in Module
@types/react^17.0.38TypeScript typesType safety for React components
@types/react-redux^7.1.20TypeScript typesRedux type safety
@types/styled-components^5.1.20TypeScript typesStyled components type safety

9.7 Bundle Size Impact

pie title Bundle Size Distribution
    "React Core" : 35
    "Redux Ecosystem" : 25
    "UI Libraries" : 20
    "Firebase" : 12
    "Utilities" : 8

9.8 Performance Considerations

9.8.1 Bundle Optimization

  • Code Splitting: Components lazy-loaded using @loadable/component
  • Tree Shaking: Unused code eliminated during build
  • Dynamic Imports: Heavy components loaded on demand

9.8.2 Runtime Performance

  • Memoization: React.memo used for expensive components
  • Virtual Scrolling: react-window handles large datasets
  • Debouncing: Search inputs debounced to reduce API calls

10. Technical Implementation Details

10.1 Performance Optimizations

10.1.1 Virtual Scrolling Implementation

// SitesList component uses react-window for performance
import { FixedSizeList as List } from 'react-window';
 
const SitesList = ({ sites, itemHeight = 60 }) => {
  const renderSiteItem = ({ index, style }) => (
    <div style={style}>
      <SiteItem site={sites[index]} />
    </div>
  );
 
  return (
    <List
      height={600}
      itemCount={sites.length}
      itemSize={itemHeight}
      itemData={sites}
    >
      {renderSiteItem}
    </List>
  );
};

10.1.2 Memoization Patterns

// Memoized components prevent unnecessary re-renders
const SiteItem = React.memo(({ site, onAction }) => {
  return (
    <div className="site-item">
      <span>{site.name}</span>
      <button onClick={() => onAction(site.id)}>
        Action
      </button>
    </div>
  );
}, (prevProps, nextProps) => {
  // Custom comparison logic
  return prevProps.site.id === nextProps.site.id &&
         prevProps.site.updatedAt === nextProps.site.updatedAt;
});

10.2 Error Handling Strategies

10.2.1 API Error Boundaries

class SiteListErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }
 
  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }
 
  componentDidCatch(error, errorInfo) {
    console.error('Site List Error:', error, errorInfo);
    // Log to monitoring service
  }
 
  render() {
    if (this.state.hasError) {
      return <ErrorFallback error={this.state.error} />;
    }
    return this.props.children;
  }
}

10.2.2 Saga Error Handling

function* fetchSitesSaga(action) {
  try {
    yield put(setIsLoading(true));
    const sites = yield call(siteAPI.fetchSites, action.payload);
    yield put(fetchSitesSuccess(sites));
  } catch (error) {
    yield put(fetchSitesFailure(error.message));
    yield call(toast.error, 'Failed to load sites');
  } finally {
    yield put(setIsLoading(false));
  }
}

10.3 Security Implementation

10.3.1 Role-Based Access Control

const RouteWithValidation = ({ 
  component: Component, 
  access, 
  feature,
  ...rest 
}) => {
  const userPermissions = useSelector(state => state.userAccess);
  const featureFlags = useSelector(state => state.featureAccess);
 
  const hasAccess = () => {
    if (access && !userPermissions[access]) return false;
    if (feature && !featureFlags[feature]) return false;
    return true;
  };
 
  return (
    <Route
      {...rest}
      render={(props) => 
        hasAccess() ? (
          <Component {...props} />
        ) : (
          <UnauthorizedComponent />
        )
      }
    />
  );
};

10.3.2 Data Sanitization

const sanitizeSiteData = (siteData) => {
  return {
    ...siteData,
    name: DOMPurify.sanitize(siteData.name),
    description: DOMPurify.sanitize(siteData.description),
    // Remove sensitive fields
    internalNotes: undefined,
    systemFlags: undefined
  };
};

10.4 Testing Strategies

10.4.1 Component Testing

import { render, screen, fireEvent } from '@testing-library/react';
import { Provider } from 'react-redux';
import SitesList from './SitesList';
 
describe('SitesList Component', () => {
  const mockStore = createMockStore({
    sites: {
      orderedSites: mockSites,
      isLoading: false
    }
  });
 
  it('renders site list correctly', () => {
    render(
      <Provider store={mockStore}>
        <SitesList />
      </Provider>
    );
    
    expect(screen.getByText('Site 1')).toBeInTheDocument();
    expect(screen.getByText('Site 2')).toBeInTheDocument();
  });
 
  it('handles site selection', () => {
    const onSiteSelect = jest.fn();
    render(
      <Provider store={mockStore}>
        <SitesList onSiteSelect={onSiteSelect} />
      </Provider>
    );
    
    fireEvent.click(screen.getByText('Site 1'));
    expect(onSiteSelect).toHaveBeenCalledWith('site-1');
  });
});

10.4.2 Saga Testing

import { testSaga } from 'redux-saga-test-plan';
import { fetchSitesSaga } from './sites.actionSaga';
 
describe('fetchSitesSaga', () => {
  it('fetches sites successfully', () => {
    testSaga(fetchSitesSaga, { payload: { limit: 20 } })
      .next()
      .put(setIsLoading(true))
      .next()
      .call(siteAPI.fetchSites, { limit: 20 })
      .next(mockSitesResponse)
      .put(fetchSitesSuccess(mockSitesResponse))
      .next()
      .put(setIsLoading(false))
      .next()
      .isDone();
  });
});

10.5 Browser Compatibility

10.5.1 Supported Browsers

  • Chrome: 88+
  • Firefox: 85+
  • Safari: 14+
  • Edge: 88+

10.5.2 Polyfills Used

  • Promise: For older browser support
  • Fetch: HTTP request compatibility
  • IntersectionObserver: For infinite scrolling
  • ResizeObserver: For responsive layouts

10.6 Deployment Considerations

10.6.1 Build Optimization

// webpack.config.js optimizations
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
        sites: {
          test: /[\\/]src[\\/]components[\\/]sites[\\/]/,
          name: 'sites-module',
          chunks: 'all',
        }
      }
    }
  }
};

10.6.2 Environment Configuration

// Environment-specific API URLs
const getApiUrl = () => {
  switch (process.env.NODE_ENV) {
    case 'development':
      return 'http://localhost:3001/api';
    case 'staging':
      return 'https://staging-api.nimbly.io/api';
    case 'production':
      return 'https://api.nimbly.io/api';
    default:
      return 'http://localhost:3001/api';
  }
};

This comprehensive documentation covers all aspects of the Site Listing module, providing developers with the information needed to understand, maintain, and extend the functionality.