{"id":29582999,"url":"https://github.com/mapp-digital/mapp-fashion-reactnative-plugin","last_synced_at":"2025-07-19T22:07:17.368Z","repository":{"id":302493083,"uuid":"1003004814","full_name":"mapp-digital/Mapp-Fashion-ReactNative-Plugin","owner":"mapp-digital","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-02T16:53:09.000Z","size":578,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-02T17:42:38.175Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mapp-digital.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-16T13:28:58.000Z","updated_at":"2025-07-02T16:53:13.000Z","dependencies_parsed_at":"2025-07-02T17:53:22.588Z","dependency_job_id":null,"html_url":"https://github.com/mapp-digital/Mapp-Fashion-ReactNative-Plugin","commit_stats":null,"previous_names":["mapp-digital/mapp-fashion-reactnative-plugin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mapp-digital/Mapp-Fashion-ReactNative-Plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapp-digital%2FMapp-Fashion-ReactNative-Plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapp-digital%2FMapp-Fashion-ReactNative-Plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapp-digital%2FMapp-Fashion-ReactNative-Plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapp-digital%2FMapp-Fashion-ReactNative-Plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mapp-digital","download_url":"https://codeload.github.com/mapp-digital/Mapp-Fashion-ReactNative-Plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapp-digital%2FMapp-Fashion-ReactNative-Plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266026535,"owners_count":23866034,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-19T22:07:14.137Z","updated_at":"2025-07-19T22:07:17.340Z","avatar_url":"https://github.com/mapp-digital.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dressipi React Native SDK\n\nA React Native SDK that provides easy integration with Dressipi's fashion AI services, including related items discovery, facetted search, and tracking capabilities.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Storage Configuration](#storage-configuration)\n- [API Reference](#api-reference)\n  - [DressipiProvider](#dressipiprovider)\n  - [useRelatedItems](#userelateditems)\n  - [useFacettedSearch](#usefacettedsearch)\n  - [useCompliance](#usecompliance)\n  - [Tracking](#tracking)\n- [Debug Logging](#debug-logging)\n- [Types](#types)\n- [Examples](#examples)\n\n## Installation\n\n```bash\nnpm install mapp-fashion-react-native-sdk\n```\n\n### Additional Dependencies\n\nThis SDK requires the following peer dependencies:\n\n```bash\nnpm install @snowplow/react-native-tracker lodash-es use-deep-compare-effect\n```\n\n## Quick Start\n\n### 1. Setup the Provider\n\nWrap your app with the `DressipiProvider` to initialize the SDK:\n\n```tsx\nimport React from 'react';\nimport { DressipiProvider } from 'mapp-fashion-react-native-sdk';\nimport { YourAppComponent } from './YourAppComponent';\n\nexport default function App() {\n  return (\n    \u003cDressipiProvider\n      namespaceId=\"your-namespace-id\"\n      domain=\"your-domain.com\"\n      clientId=\"your-client-id\"\n    \u003e\n      \u003cYourAppComponent /\u003e\n    \u003c/DressipiProvider\u003e\n  );\n}\n```\n\nFor an Expo setup, you need to install the [Expo Storage plugin](https://www.npmjs.com/package/mapp-fashion-react-native-sdk-expo).\n\n### 2. Use the Hooks\n\nOnce wrapped with the provider, you can use the SDK hooks in any component:\n\n```tsx\nimport React from 'react';\nimport { View, Text, FlatList } from 'react-native';\nimport {\n  useRelatedItems,\n  useFacettedSearch,\n  RelatedItemsMethod,\n} from 'mapp-fashion-react-native-sdk';\n\nexport function ProductRecommendations({ productId }: { productId: string }) {\n  // Get related items for a product\n  const { relatedItems, loading, error } = useRelatedItems({\n    item_id: productId,\n    methods: [RelatedItemsMethod.Outfits, RelatedItemsMethod.SimilarItems],\n  });\n\n  // Perform facetted search\n  const { items: searchResults } = useFacettedSearch({\n    facets: [\n      {\n        name: 'garment_category',\n        value: ['dresses', 'tops'],\n      },\n    ],\n    per_page: 20,\n  });\n\n  if (loading) return \u003cText\u003eLoading...\u003c/Text\u003e;\n  if (error) return \u003cText\u003eError: {error.message}\u003c/Text\u003e;\n\n  return (\n    \u003cView\u003e\n      {relatedItems?.outfits \u0026\u0026 (\n        \u003cFlatList\n          data={relatedItems.outfits}\n          renderItem={({ item }) =\u003e (\n            \u003cText\u003e\n              {item.occasion} - {item.items.length} items\n            \u003c/Text\u003e\n          )}\n        /\u003e\n      )}\n    \u003c/View\u003e\n  );\n}\n```\n\n## Storage Configuration\n\nThe Dressipi SDK supports different secure storage solutions depending on your React Native environment. The SDK automatically defaults to the most commonly used option but allows you to explicitly choose your preferred storage method.\n\n### Default Storage Behavior\n\nBy default, the SDK uses **React Native Keychain** (`react-native-keychain`) for secure credential storage. This works seamlessly in standard React Native applications without any additional configuration.\n\n```tsx\nimport { DressipiProvider } from 'mapp-fashion-react-native-sdk';\n\n// Uses React Native Keychain by default\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"your-domain.com\"\n  clientId=\"your-client-id\"\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e;\n```\n\n### Explicit Storage Configuration\n\nFor Expo applications or when you want to explicitly control the storage method, you can specify the `storage` prop:\n\n```tsx\nimport { DressipiProvider } from 'mapp-fashion-react-native-sdk';\nimport { SecureStoreAdapter } from 'mapp-fashion-react-native-sdk-expo';\n\n// Explicitly use Expo SecureStore for Expo applications\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"your-domain.com\"\n  clientId=\"your-client-id\"\n  storage={new SecureStoreAdapter()}\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e;\n```\n\n### Storage Dependencies\n\nMake sure you have the appropriate storage library installed for your chosen storage type:\n\n#### For React Native Keychain (Default)\n\n```bash\nnpm install react-native-keychain\n# For iOS, run: cd ios \u0026\u0026 pod install\n```\n\n#### For Expo SecureStore\n\n```bash\nnpm install expo-secure-store\n```\n\n### Storage Features\n\nBoth storage adapters provide identical functionality:\n\n- **Secure Credential Storage**: OAuth tokens are stored securely using platform-native secure storage\n- **Automatic Token Refresh**: Stored credentials are automatically used for token refresh operations\n- **Cross-Session Persistence**: Credentials persist across app restarts and device reboots\n- **Platform Security**: Leverages iOS Keychain and Android Keystore for maximum security\n\n### Migration Between Storage Types\n\nIf you need to switch storage types (e.g., migrating from React Native to Expo), users will need to re-authenticate as credentials from different storage adapters are not automatically migrated.\n\n## API Reference\n\n### DressipiProvider\n\nThe main provider component that initializes the SDK and provides authentication and tracking capabilities.\n\n#### Props\n\n| Prop             | Type                   | Required | Description                                                                        |\n| ---------------- | ---------------------- | -------- | ---------------------------------------------------------------------------------- |\n| `namespaceId`    | `string`               | Yes      | Your Dressipi namespace identifier                                                 |\n| `domain`         | `string`               | Yes      | Your Dressipi domain                                                               |\n| `clientId`       | `string`               | Yes      | Your OAuth client ID for authentication                                            |\n| `enableLogging`  | `boolean`              | No       | Enable debug logging for development (defaults to `false`)                         |\n| `storage`        | `SecureStorageAdapter` | No       | Custom storage adapter for credentials (defaults to KeyChain)                      |\n| `defaultConsent` | `boolean`              | No       | Default consent value when user hasn't made a choice yet (defaults to `undefined`) |\n| `children`       | `ReactNode`            | Yes      | Your app components                                                                |\n\n#### Features Provided\n\n- **Authentication Management**: Automatically handles OAuth token lifecycle and refresh\n- **Tracking Infrastructure**: Sets up Snowplow tracking for analytics\n- **Request Queue**: Manages API request queuing when offline\n- **Global Configuration**: Provides configuration context to all child components\n\n#### Example\n\n```tsx\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"api.dressipi.com\"\n  clientId=\"your-oauth-client-id\"\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e\n```\n\n#### Default Consent Configuration\n\nThe `defaultConsent` prop allows you to set a default consent value for data usage when the user hasn't explicitly made a choice yet. This is useful for controlling the initial behavior of the SDK:\n\n```tsx\n// Default to allowing data usage (authentication enabled)\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"api.dressipi.com\"\n  clientId=\"your-client-id\"\n  defaultConsent={true}\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e\n\n// Default to not allowing data usage (authentication disabled)\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"api.dressipi.com\"\n  clientId=\"your-client-id\"\n  defaultConsent={false}\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e\n```\n\n**Note:** The default value is only used when no stored consent preference exists. Once a user explicitly accepts or rejects consent via `useCompliance`, their choice is stored and takes precedence over the default.\n\n---\n\n### useRelatedItems\n\nA hook for fetching related items, outfits, and similar products for a given item.\n\n#### Parameters\n\n`request: RelatedItemsApiRequest` - Configuration object for the related items request.\n\n#### Returns\n\n`RelatedItemsState` - An object containing the response data and request state.\n\n| Property       | Type                                 | Description                                                                                                                      |\n| -------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |\n| `relatedItems` | `RelatedItemsMappedResponse \\| null` | The processed response data containing outfits, partner outfits, and similar items. `null` when no data is available or loading. |\n| `loading`      | `boolean`                            | Indicates whether the request is currently in progress. `true` during API calls, `false` when completed or idle.                 |\n| `error`        | `Error \\| null`                      | Contains error information if the request fails. `null` when no error has occurred.                                              |\n\n#### Request Parameters (RelatedItemsApiRequest)\n\n| Property               | Type                         | Required | Description                                                                                          |\n| ---------------------- | ---------------------------- | -------- | ---------------------------------------------------------------------------------------------------- |\n| `item_id`              | `string`                     | Yes      | The item + variant identifier (style + color) that serves as the base for recommendations            |\n| `methods`              | `RelatedItemsMethod[]`       | No       | Array specifying which recommendation types to fetch (`outfits`, `partner_outfits`, `similar_items`) |\n| `response_format`      | `ResponseFormat`             | No       | Response format (defaults to `Detailed`) - controls the level of detail in the response              |\n| `try_all_methods`      | `boolean`                    | No       | Whether to try all available methods if the specified methods don't return results                   |\n| `outfits_per_occasion` | `number`                     | No       | Maximum number of outfits to return per occasion (e.g., work, casual, evening)                       |\n| `max_similar_items`    | `number`                     | No       | Maximum number of similar items to return in the response                                            |\n| `max_reduced_by`       | `number`                     | No       | Maximum discount percentage to include in results (filters out heavily discounted items)             |\n| `identifier_type`      | `RelatedItemsIdentifierType` | No       | Type of identifier being used (affects how the item_id is interpreted)                               |\n\n#### Response Data (RelatedItemsMappedResponse)\n\nThe `relatedItems` object contains the following properties:\n\n- **`response_id`**: `string` - Unique identifier for this specific response (useful for tracking and analytics)\n- **`outfits`**: `Outfit[] | undefined` - Array of complete outfit recommendations organized by occasion, each containing coordinated items\n- **`partner_outfits`**: `Outfit[] | undefined` - Array of partner-specific outfit recommendations with specialized styling\n- **`similar_items`**: `{ content_id: string; items: DetailedItem[]; } | undefined` - Object containing items similar to the requested product\n\n#### Example\n\n```tsx\nimport {\n  useRelatedItems,\n  RelatedItemsMethod,\n} from 'mapp-fashion-react-native-sdk';\n\nfunction ProductPage({ productId }: { productId: string }) {\n  const { relatedItems, loading, error } = useRelatedItems({\n    item_id: productId,\n    methods: [RelatedItemsMethod.Outfits, RelatedItemsMethod.SimilarItems],\n    outfits_per_occasion: 3,\n    max_similar_items: 10,\n  });\n\n  if (loading) return \u003cText\u003eLoading recommendations...\u003c/Text\u003e;\n  if (error) return \u003cText\u003eError: {error.message}\u003c/Text\u003e;\n  if (!relatedItems) return \u003cText\u003eNo recommendations available\u003c/Text\u003e;\n\n  return (\n    \u003cView\u003e\n      {/* Render outfits */}\n      {relatedItems.outfits?.map(outfit =\u003e (\n        \u003cView key={outfit.content_id}\u003e\n          \u003cText\u003eOccasion: {outfit.occasion}\u003c/Text\u003e\n          {outfit.items.map(item =\u003e (\n            \u003cText key={item.id}\u003e\n              {item.name} - {item.price}\n            \u003c/Text\u003e\n          ))}\n        \u003c/View\u003e\n      ))}\n\n      {/* Render similar items */}\n      {relatedItems.similar_items \u0026\u0026 (\n        \u003cView\u003e\n          \u003cText\u003eSimilar Items:\u003c/Text\u003e\n          {relatedItems.similar_items.items.map(item =\u003e (\n            \u003cText key={item.id}\u003e\n              {item.name} by {item.brand_name}\n            \u003c/Text\u003e\n          ))}\n        \u003c/View\u003e\n      )}\n    \u003c/View\u003e\n  );\n}\n```\n\n---\n\n### useFacettedSearch\n\nA hook for performing facetted search queries with filters and pagination.\n\n#### Parameters\n\n`request: FacettedSearchApiRequest` (optional, defaults to `{}`) - Configuration object for the search request.\n\n#### Returns\n\n`FacettedSearchState` - An object containing the search results and request state.\n\n| Property  | Type                                   | Description                                                                                                              |\n| --------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |\n| `items`   | `FacettedSearchMappedResponse \\| null` | The processed search results containing filtered items and pagination info. `null` when no data is available or loading. |\n| `loading` | `boolean`                              | Indicates whether the search request is currently in progress. `true` during API calls, `false` when completed or idle.  |\n| `error`   | `Error \\| null`                        | Contains error information if the search request fails. `null` when no error has occurred.                               |\n\n#### Request Parameters (FacettedSearchApiRequest)\n\n| Property          | Type             | Required | Description                                                                               |\n| ----------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------- |\n| `facets`          | `Facet[]`        | No       | Array of search filters to apply (categories, brands, price ranges, etc.)                 |\n| `response_format` | `ResponseFormat` | No       | Response format (defaults to `Detailed`) - controls the level of detail in returned items |\n| `page`            | `number`         | No       | Page number for pagination (1-based indexing)                                             |\n| `per_page`        | `number`         | No       | Number of items to return per page (controls pagination size)                             |\n\n#### Facet Types\n\n**Single Filter:**\n\n```typescript\n{\n  name: 'garment_category',\n  value: ['dresses', 'tops']\n}\n```\n\n**Multiple Filters:**\n\n```typescript\n{\n  name: 'price',\n  filters: [\n    { from: 50, to: 100 },\n    { value: ['sale'] }\n  ]\n}\n```\n\n#### Available Facet Dimensions\n\n- `garment_category`: Product categories (e.g., 'dresses', 'tops')\n- `brand`: Brand names\n- `occasion`: Occasions (e.g., 'work', 'evening')\n- `must_have`: Must-have items\n- `retailer_labels`: Retailer-specific labels\n- `store`: Store identifiers\n- `feature_ids`: Include specific features\n- `not_feature_ids`: Exclude specific features\n- `price`: Price ranges\n- `reduced_by`: Discount percentages\n\n#### Response Data (FacettedSearchMappedResponse)\n\nThe `items` object contains the following properties:\n\n- **`response_id`**: `string` - Unique identifier for this specific search response (useful for tracking and analytics)\n- **`content_id`**: `string` - Content identifier for tracking purposes and correlation with other API calls\n- **`items`**: `DetailedItem[]` - Array of filtered products matching the search criteria with complete item information\n- **`pagination`**: `object` - Pagination information with the following structure:\n  - `current_page`: `number` - Current page number (1-based)\n  - `last_page`: `number` - Total number of pages available\n  - `total_items`: `number` - Total number of items matching the search criteria across all pages\n\n#### Example\n\n```tsx\nimport { useFacettedSearch } from 'mapp-fashion-react-native-sdk';\n\nfunction SearchResults() {\n  const { items, loading, error } = useFacettedSearch({\n    facets: [\n      {\n        name: 'garment_category',\n        value: ['dresses'],\n      },\n      {\n        name: 'brand',\n        value: ['Zara', 'H\u0026M'],\n      },\n      {\n        name: 'price',\n        filters: [{ from: 30, to: 100 }],\n      },\n    ],\n    per_page: 20,\n    page: 1,\n  });\n\n  if (loading) return \u003cText\u003eSearching...\u003c/Text\u003e;\n  if (error) return \u003cText\u003eSearch error: {error.message}\u003c/Text\u003e;\n  if (!items) return \u003cText\u003eNo results found\u003c/Text\u003e;\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003e\n        Page {items.pagination.current_page} of {items.pagination.last_page}(\n        {items.pagination.total_items} total items)\n      \u003c/Text\u003e\n\n      \u003cFlatList\n        data={items.items}\n        renderItem={({ item }) =\u003e (\n          \u003cView\u003e\n            \u003cText\u003e{item.name}\u003c/Text\u003e\n            \u003cText\u003e{item.brand_name}\u003c/Text\u003e\n            \u003cText\u003e{item.price}\u003c/Text\u003e\n            \u003cText\u003eStatus: {item.status}\u003c/Text\u003e\n          \u003c/View\u003e\n        )}\n        keyExtractor={item =\u003e item.id}\n      /\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n### Tracking\n\nThe SDK provides comprehensive tracking capabilities through specialized hooks that automatically send analytics events to Dressipi's tracking system. These hooks enable you to track user interactions, shopping behaviors, and page views for better insights and personalization.\n\n---\n\n#### useDressipiAddToBasketTracking\n\nTracks when a user adds an item to their shopping basket.\n\n**Event Tracked:** `add_to_basket` - Records product additions to the shopping cart for conversion tracking and recommendation optimization.\n\n**Parameters:**\n\n- `item: AddToBasketEventPayload` - The item being added to the basket\n\n**Usage:**\n\n```tsx\nimport { useDressipiAddToBasketTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductCard({ product }) {\n  // Track add to basket when component mounts with item data\n  useDressipiAddToBasketTracking({\n    sku: '603081121',\n    name: 'Product 603081121',\n    category: '',\n    unitPrice: 0.0,\n    quantity: 1,\n    currency: 'GBP',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003e{product.name}\u003c/Text\u003e\n      \u003cTouchableOpacity onPress={handleAddToBasket}\u003e\n        \u003cText\u003eAdd to Basket\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n**AddToBasketEventPayload Type:**\n\n```typescript\ntype AddToBasketEventPayload = {\n  /**\n   * The SKU of the item.\n   */\n  sku: string;\n  /**\n   * The name of the item.\n   */\n  name?: string;\n  /**\n   * The category of the item.\n   */\n  category?: string;\n  /**\n   * The price of the item.\n   */\n  unitPrice?: number;\n  /**\n   * The quantity of the item.\n   */\n  quantity: number;\n  /**\n   * The currency of the item.\n   */\n  currency?: string;\n};\n```\n\n---\n\n#### useDressipiRemoveFromBasketTracking\n\nTracks when a user removes an item from their shopping basket.\n\n**Event Tracked:** `remove_from_basket` - Records product removals from the shopping cart for understanding user behavior and cart abandonment patterns.\n\n**Parameters:**\n\n- `item: RemoveFromBasketEventPayload` - The item being removed from the basket\n\n**Usage:**\n\n```tsx\nimport { useDressipiRemoveFromBasketTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction BasketItem({ item, onRemove }) {\n  // Track remove from basket when component mounts with item data\n  useDressipiRemoveFromBasketTracking({\n    sku: '603081121',\n    name: 'Product 603081121',\n    category: '',\n    unitPrice: 0.0,\n    quantity: 1,\n    currency: 'GBP',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003e{item.name}\u003c/Text\u003e\n      \u003cTouchableOpacity onPress={() =\u003e onRemove(item.id)}\u003e\n        \u003cText\u003eRemove\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n**RemoveFromBasketEventPayload Type:**\n\n```typescript\ntype RemoveFromBasketEventPayload = {\n  /**\n   * The SKU of the item.\n   */\n  sku: string;\n  /**\n   * The name of the item.\n   */\n  name?: string;\n  /**\n   * The category of the item.\n   */\n  category?: string;\n  /**\n   * The price of the item.\n   */\n  unitPrice?: number;\n  /**\n   * The quantity of the item.\n   */\n  quantity: number;\n  /**\n   * The currency of the item.\n   */\n  currency?: string;\n};\n```\n\n---\n\n#### useDressipiOrderTracking\n\nTracks when a user completes an order or makes a purchase.\n\n**Event Tracked:** `order` - Records completed transactions for revenue tracking, conversion analysis, and personalization improvements.\n\n**Parameters:**\n\n- `order: OrderEventPayload` - The completed order details including items, total value, and customer information\n\n**Usage:**\n\n```tsx\nimport { useDressipiOrderTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction OrderConfirmation({ orderData }) {\n  // Track order completion when component mounts\n  useDressipiOrderTracking({\n    orderId: '1234567890',\n    currency: 'GBP',\n    totalValue: 0.0,\n    items: [\n      {\n        sku: '603081121',\n        price: 0.0,\n        quantity: 1,\n        name: 'Product 603081121',\n      },\n    ],\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eOrder #{orderData.id} confirmed!\u003c/Text\u003e\n      \u003cText\u003eTotal: ${orderData.total}\u003c/Text\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n**OrderEventPayload Type:**\n\n```typescript\ntype OrderEventPayload = EcommerceTransactionProps;\n```\n\nNote: `OrderEventPayload` is an alias for `EcommerceTransactionProps` from the `@snowplow/react-native-tracker` library, which includes properties like `orderId`, `totalValue`, `items`, `currency`, and other e-commerce transaction details.\n\n---\n\n#### useDressipiPageViewTracking\n\nTracks when a user views a page or navigates to a new screen.\n\n**Event Tracked:** `page_view` - Records page navigation and screen views for understanding user browsing behavior, measuring page performance, and tracking user journeys through the application.\n\n**Parameters:**\n\n- `pageViewPayload: PageViewEventPayload` - The page view event data including URL and page details\n\n**Usage:**\n\n```tsx\nimport { useDressipiPageViewTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductListPage() {\n  // Track page view when component mounts\n  useDressipiPageViewTracking({\n    pageUrl: 'https://www.example.com/products',\n    pageTitle: 'Product Listing',\n    referrer: 'https://www.example.com/home',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eProduct List\u003c/Text\u003e\n      {/* Page content */}\n    \u003c/View\u003e\n  );\n}\n\n// Or track page view for different screen transitions\nfunction HomePage() {\n  useDressipiPageViewTracking({\n    pageUrl: 'https://www.example.com/home',\n    pageTitle: 'Home Page',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eWelcome to our store!\u003c/Text\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n**PageViewEventPayload Type:**\n\n```typescript\ntype PageViewEventPayload = PageViewProps;\n```\n\nNote: `PageViewEventPayload` is an alias for `PageViewProps` from the `@snowplow/react-native-tracker` library, which includes properties such as:\n\n- `pageUrl`: The URL of the page being viewed\n- `pageTitle`: The title of the page (optional)\n- `referrer`: The referrer URL (optional)\n\n---\n\n#### useDressipiIdentifyTracking\n\nTracks user identification events such as login, registration, or profile updates.\n\n**Event Tracked:** `identify` - Records user identification information to enhance personalization and link user sessions across devices.\n\n**Parameters:**\n\n- `identification: IdentifyEventPayload` - User identification details including customer ID and email\n\n**Usage:**\n\n```tsx\nimport { useDressipiIdentifyTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction UserProfile({ user }) {\n  // Track user identification when component mounts\n  useDressipiIdentifyTracking({\n    customerId: '1234567890',\n    email: 'test@test.com',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eWelcome, {user.name}!\u003c/Text\u003e\n      \u003cText\u003e{user.email}\u003c/Text\u003e\n    \u003c/View\u003e\n  );\n}\n\n// Or track identification after login\nfunction LoginScreen() {\n  const handleLogin = async credentials =\u003e {\n    const user = await loginUser(credentials);\n\n    // Track user identification after successful login\n    useDressipiIdentifyTracking({\n      customerId: '1234567890',\n      email: 'test@test.com',\n    });\n  };\n\n  return \u003cView\u003e{/* Login form */}\u003c/View\u003e;\n}\n```\n\n**IdentifyEventPayload Type:**\n\n```typescript\ntype IdentifyEventPayload = {\n  /**\n   * The customer ID.\n   */\n  customerId?: string;\n  /**\n   * The email address of the user.\n   */\n  email?: string;\n};\n```\n\n---\n\n#### useDressipiProductDisplayPageTracking\n\nTracks when a user views a product detail page (PDP).\n\n**Event Tracked:** `product_display_page` - Records product page views for understanding user interest, improving recommendations, and measuring engagement.\n\n**Parameters:**\n\n- `item: ProductDetailPageEventPayload` - The product being viewed on the detail page\n\n**Usage:**\n\n```tsx\nimport { useDressipiProductDisplayPageTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductDetailPage({ product }) {\n  // Track product page view when component mounts\n  useDressipiProductDisplayPageTracking({\n    product_code: '603081121',\n    sku: '603081121',\n  });\n\n  return (\n    \u003cScrollView\u003e\n      \u003cImage source={{ uri: product.image }} /\u003e\n      \u003cText\u003e{product.name}\u003c/Text\u003e\n      \u003cText\u003e{product.description}\u003c/Text\u003e\n      \u003cText\u003e${product.price}\u003c/Text\u003e\n    \u003c/ScrollView\u003e\n  );\n}\n```\n\n**ProductDetailPageEventPayload Type:**\n\n```typescript\ntype ProductDetailPageEventPayload = ProductPayload;\n```\n\n**ProductPayload Type:**\n\n```typescript\ntype ProductPayload = {\n  /**\n   * This is an identifier that is unique to the style and\n   * color/pattern of the item.\n   */\n  product_code: string;\n  /**\n   * This is an identifier that is unique to the style, color/pattern and size of the item.\n   */\n  sku: string;\n  /**\n   * This is an identifier.\n   */\n  dressipi_item_id?: string;\n  /**\n   * The name of the item.\n   */\n  item_name?: string;\n  /**\n   * The barcode for this variant.\n   */\n  barcode?: string;\n  /**\n   * The size of the item/garment being viewed.\n   */\n  size?: string;\n  /**\n   * A product affiliation to designate a supplying company or brick and mortar store location.\n   */\n  affiliation?: string;\n  /**\n   * The coupon name or code associated with the item.\n   */\n  coupon?: string;\n  /**\n   * The currency of the item.\n   */\n  currency?: string;\n  /**\n   * The monetary discount value associated with the item.\n   */\n  discount?: number;\n  /**\n   * The brand of the item.\n   */\n  item_brand?: string;\n  /**\n   * The category of the item.\n   */\n  item_category?: string;\n  /**\n   * The second category hierarchy or additional taxonomy for the item.\n   */\n  item_category2?: string;\n  /**\n   * The third category hierarchy or additional taxonomy for the item.\n   */\n  item_category3?: string;\n  /**\n   * The fourth category hierarchy or additional taxonomy for the item.\n   */\n  item_category4?: string;\n  /**\n   * The fifth category hierarchy or additional taxonomy for the item.\n   */\n  item_category5?: string;\n  /**\n   * The location associated with the item.\n   */\n  location_id?: string;\n  /**\n   * The price of the item.\n   */\n  price?: number;\n  /**\n   * The quantity of the item.\n   */\n  quantity?: number;\n};\n```\n\n---\n\n#### useDressipiProductListPageTracking\n\nTracks when a user views a product listing page (PLP) such as category pages or search results.\n\n**Event Tracked:** `product_list_page` - Records product list page views with information about displayed items, applied filters, and pagination for understanding browsing patterns.\n\n**Parameters:**\n\n- `data: ProductListPageEventPayload` - The product list page data including items, filters, and pagination information\n\n**Usage:**\n\n```tsx\nimport { useDressipiProductListPageTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductListPage({ products, filters, currentPage }) {\n  // Track product list page view when component mounts\n  useDressipiProductListPageTracking({\n    page: {\n      number: 1,\n    },\n    items: [\n      {\n        sku: '603081121',\n        product_code: '603081121',\n      },\n    ],\n    filters: [\n      {\n        selected: ['selected'],\n        name: 'garment_category',\n      },\n    ],\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eProducts ({products.length})\u003c/Text\u003e\n      \u003cFlatList\n        data={products}\n        renderItem={({ item }) =\u003e \u003cProductCard key={item.id} product={item} /\u003e}\n      /\u003e\n    \u003c/View\u003e\n  );\n}\n\n// Example with search results\nfunction SearchResults({ searchQuery, results, appliedFilters, page }) {\n  useDressipiProductListPageTracking({\n    page: {\n      number: 1,\n    },\n    items: [\n      {\n        sku: '603081121',\n        product_code: '603081121',\n      },\n    ],\n    filters: [\n      {\n        selected: ['selected'],\n        name: 'garment_category',\n      },\n    ],\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eSearch results for \"{searchQuery}\"\u003c/Text\u003e\n      {/* Results display */}\n    \u003c/View\u003e\n  );\n}\n```\n\n**ProductListPageEventPayload Type:**\n\n```typescript\ntype ProductListPageEventPayload = {\n  /**\n   * The page object.\n   */\n  page?: {\n    /**\n     * The page number currently visible.\n     */\n    number?: number;\n  };\n  /**\n   * A list of products.\n   */\n  items: ProductPayload[];\n  /**\n   * A list of filters applied to the product list page.\n   */\n  filters?: ProductListPageFilterItem[];\n};\n```\n\n**ProductListPageFilterItem Type:**\n\n```typescript\ntype ProductListPageFilterItem = {\n  name: string;\n  selected: any[];\n};\n```\n\n---\n\n#### useDressipiTabClickTracking\n\nTracks when a user clicks on a tab in the interface.\n\n**Event Tracked:** `tab_click` - Records tab interactions for understanding user navigation patterns and content engagement.\n\n**Parameters:**\n\n- `tabClickPayload: TabClickEventPayload` - The tab click event data\n\n**Usage:**\n\n```tsx\nimport { useDressipiTabClickTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction TabComponent({ activeTab }) {\n  // Track tab click when component mounts\n  useDressipiTabClickTracking({\n    request_id: '1234567890',\n    tab_name: 'tab1',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cTouchableOpacity\u003e\n        \u003cText\u003eTab 1\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n**TabClickEventPayload Type:**\n\n```typescript\ntype TabClickEventPayload = {\n  /**\n   * The id of request to the server that generated the content,\n   * returned in the response as event_id.\n   */\n  request_id: string;\n  /**\n   * The name of the tab that was clicked on.\n   */\n  tab_name: string;\n};\n```\n\n---\n\n#### useDressipiItemClickQuickViewTracking\n\nTracks when a user clicks on an item in a quick view interface.\n\n**Event Tracked:** `item_click_quick_view` - Records item clicks in quick view contexts for understanding user engagement with product previews.\n\n**Parameters:**\n\n- `itemClickQuickViewPayload: ItemClickQuickViewEventPayload` - The item click quick view event data\n\n**Usage:**\n\n```tsx\nimport { useDressipiItemClickQuickViewTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction QuickViewModal({ item }) {\n  // Track item click in quick view when component mounts\n  useDressipiItemClickQuickViewTracking({\n    request_id: '1234567890',\n    dressipi_item_id: 1,\n    related_items_set_id: '1234567890',\n  });\n\n  return (\n    \u003cModal\u003e\n      \u003cText\u003e{item.name}\u003c/Text\u003e\n      \u003cText\u003e${item.price}\u003c/Text\u003e\n    \u003c/Modal\u003e\n  );\n}\n```\n\n**ItemClickQuickViewEventPayload Type:**\n\n```typescript\ntype ItemClickQuickViewEventPayload = {\n  /**\n   * The id of request to the server that generated the content,\n   * returned in the response as event_id.\n   */\n  request_id: string;\n  /**\n   * The id of the set containing the item that was clicked on,\n   * returned in the API request as content_id.\n   */\n  related_items_set_id?: string;\n  /**\n   * The id of the item that was clicked on,\n   * returned in the request as raw_garment_id.\n   */\n  dressipi_item_id: number;\n};\n```\n\n---\n\n#### useDressipiItemClickPdpTracking\n\nTracks when a user clicks on an item on a product detail page (PDP).\n\n**Event Tracked:** `item_click_pdp` - Records item clicks on product detail pages for understanding user interaction with related products and recommendations.\n\n**Parameters:**\n\n- `itemClickPdpPayload: ItemClickPdpEventPayload` - The item click PDP event data\n\n**Usage:**\n\n```tsx\nimport { useDressipiItemClickPdpTracking } from 'mapp-fashion-react-native-sdk';\n\nfunction RelatedItemsSection({ relatedItems }) {\n  // Track item click on PDP when component mounts\n  useDressipiItemClickPdpTracking({\n    request_id: '1234567890',\n    dressipi_item_id: 1,\n    related_items_set_id: '1234567890',\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eRelated Items\u003c/Text\u003e\n      {relatedItems.map(item =\u003e (\n        \u003cTouchableOpacity key={item.id}\u003e\n          \u003cText\u003e{item.name}\u003c/Text\u003e\n        \u003c/TouchableOpacity\u003e\n      ))}\n    \u003c/View\u003e\n  );\n}\n```\n\n**ItemClickPdpEventPayload Type:**\n\n```typescript\ntype ItemClickPdpEventPayload = {\n  /**\n   * The id of request to the server that generated the content,\n   * returned in the response as event_id.\n   */\n  request_id: string;\n  /**\n   * The id of the set containing the item that was clicked on,\n   * returned in the API request as content_id.\n   */\n  related_items_set_id?: string;\n  /**\n   * The id of the item that was clicked on,\n   * returned in the request as raw_garment_id.\n   */\n  dressipi_item_id: number;\n};\n```\n\n---\n\n### useCompliance\n\nA hook for managing user data tracking consent and compliance with privacy regulations like GDPR. This hook provides access to the user's consent status and functions to update their preferences. The SDK automatically respects the consent status, enabling or disabling data collection and API authentication based on the user's choice.\n\n#### Parameters\n\nThis hook takes no parameters.\n\n#### Returns\n\n`ComplianceConfiguration` - An object containing the user's consent state and management functions.\n\n| Property       | Type                                  | Description                                                                                                                                   |\n| -------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| `hasConsented` | `boolean \\| null`                     | The user's current consent status. `true` = consented, `false` = rejected, `null` = no choice made yet                                        |\n| `setConsent`   | `(consent: boolean) =\u003e Promise\u003cvoid\u003e` | Function to update the user's consent status. Accepts `true` for consent or `false` for rejection. The value is securely stored and persisted |\n| `isLoading`    | `boolean`                             | Indicates whether a consent operation is in progress. `true` during storage operations, `false` when idle                                     |\n\n#### Consent Behavior\n\nThe consent status directly affects how the SDK operates:\n\n- **`true` (Consented)**: Full SDK functionality is enabled, including authentication, API calls, and tracking\n- **`false` (Rejected)**: API calls are disabled, no authentication occurs, and no tracking data is sent\n- **`null` (Not Set)**: Behavior depends on the `defaultConsent` prop set in `DressipiProvider`\n\n#### Storage\n\nUser consent preferences are securely stored using the same storage adapter configured for the SDK (React Native Keychain or Expo SecureStore). The consent status persists across app restarts and device reboots, ensuring users don't need to re-consent on every session.\n\n#### Example Usage\n\n**Basic Compliance Management:**\n\n```tsx\nimport React, { useState } from 'react';\nimport { View, Text, TouchableOpacity, Alert } from 'react-native';\nimport { useCompliance } from 'mapp-fashion-react-native-sdk';\n\nfunction PrivacySettings() {\n  const { hasConsented, setConsent, isLoading } = useCompliance();\n\n  const handleConsentUpdate = async (consent: boolean) =\u003e {\n    try {\n      await setConsent(consent);\n      Alert.alert(\n        'Settings Updated',\n        `Data tracking ${consent ? 'enabled' : 'disabled'} successfully.`\n      );\n    } catch (error) {\n      Alert.alert('Error', 'Failed to update privacy settings.');\n      console.error('Failed to set compliance:', error);\n    }\n  };\n\n  return (\n    \u003cView style={{ padding: 20 }}\u003e\n      \u003cText style={{ fontSize: 18, marginBottom: 10 }}\u003ePrivacy Settings\u003c/Text\u003e\n\n      \u003cText style={{ marginBottom: 20 }}\u003e\n        Current Status:{' '}\n        {hasConsented === null\n          ? 'Not Set'\n          : hasConsented\n            ? 'Data Tracking Enabled'\n            : 'Data Tracking Disabled'}\n      \u003c/Text\u003e\n\n      \u003cTouchableOpacity\n        onPress={() =\u003e handleConsentUpdate(true)}\n        disabled={isLoading}\n        style={{\n          backgroundColor: hasConsented === true ? '#4CAF50' : '#E0E0E0',\n          padding: 15,\n          marginBottom: 10,\n          borderRadius: 8,\n        }}\n      \u003e\n        \u003cText\u003eEnable Data Tracking\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n\n      \u003cTouchableOpacity\n        onPress={() =\u003e handleConsentUpdate(false)}\n        disabled={isLoading}\n        style={{\n          backgroundColor: hasConsented === false ? '#F44336' : '#E0E0E0',\n          padding: 15,\n          borderRadius: 8,\n        }}\n      \u003e\n        \u003cText\u003eDisable Data Tracking\u003c/Text\u003e\n      \u003c/TouchableOpacity\u003e\n\n      {isLoading \u0026\u0026 \u003cText\u003eUpdating settings...\u003c/Text\u003e}\n    \u003c/View\u003e\n  );\n}\n```\n\n**Compliance Popup for First-Time Users:**\n\n```tsx\nimport React, { useState, useEffect } from 'react';\nimport { View, Text, TouchableOpacity, Modal } from 'react-native';\nimport { useCompliance } from 'mapp-fashion-react-native-sdk';\n\nfunction CompliancePopup() {\n  const [showPopup, setShowPopup] = useState(false);\n  const { hasConsented, setConsent, isLoading } = useCompliance();\n\n  // Show popup if user hasn't made a choice yet\n  useEffect(() =\u003e {\n    if (hasConsented === null) {\n      setShowPopup(true);\n    }\n  }, [hasConsented]);\n\n  const handleAccept = async () =\u003e {\n    try {\n      await setConsent(true);\n      setShowPopup(false);\n    } catch (error) {\n      console.error('Failed to accept compliance:', error);\n    }\n  };\n\n  const handleReject = async () =\u003e {\n    try {\n      await setConsent(false);\n      setShowPopup(false);\n    } catch (error) {\n      console.error('Failed to reject compliance:', error);\n    }\n  };\n\n  return (\n    \u003cModal visible={showPopup} transparent animationType=\"fade\"\u003e\n      \u003cView\n        style={{\n          flex: 1,\n          backgroundColor: 'rgba(0,0,0,0.5)',\n          justifyContent: 'center',\n          alignItems: 'center',\n        }}\n      \u003e\n        \u003cView\n          style={{\n            backgroundColor: 'white',\n            padding: 20,\n            borderRadius: 10,\n            margin: 20,\n          }}\n        \u003e\n          \u003cText style={{ fontSize: 18, fontWeight: 'bold', marginBottom: 15 }}\u003e\n            Privacy \u0026 Data Usage\n          \u003c/Text\u003e\n\n          \u003cText style={{ marginBottom: 20, lineHeight: 20 }}\u003e\n            We use your data to provide personalized fashion recommendations and\n            improve your shopping experience. You can change this setting at any\n            time in your privacy preferences.\n          \u003c/Text\u003e\n\n          \u003cView\n            style={{ flexDirection: 'row', justifyContent: 'space-between' }}\n          \u003e\n            \u003cTouchableOpacity\n              onPress={handleReject}\n              disabled={isLoading}\n              style={{\n                backgroundColor: '#E0E0E0',\n                padding: 15,\n                borderRadius: 8,\n                flex: 1,\n                marginRight: 10,\n              }}\n            \u003e\n              \u003cText style={{ textAlign: 'center' }}\u003eDecline\u003c/Text\u003e\n            \u003c/TouchableOpacity\u003e\n\n            \u003cTouchableOpacity\n              onPress={handleAccept}\n              disabled={isLoading}\n              style={{\n                backgroundColor: '#2196F3',\n                padding: 15,\n                borderRadius: 8,\n                flex: 1,\n                marginLeft: 10,\n              }}\n            \u003e\n              \u003cText style={{ color: 'white', textAlign: 'center' }}\u003e\n                Accept\n              \u003c/Text\u003e\n            \u003c/TouchableOpacity\u003e\n          \u003c/View\u003e\n\n          {isLoading \u0026\u0026 (\n            \u003cText style={{ textAlign: 'center', marginTop: 10 }}\u003e\n              Processing...\n            \u003c/Text\u003e\n          )}\n        \u003c/View\u003e\n      \u003c/View\u003e\n    \u003c/Modal\u003e\n  );\n}\n```\n\n**Conditional Feature Rendering Based on Consent:**\n\n```tsx\nimport React from 'react';\nimport { View, Text } from 'react-native';\nimport { useCompliance, useRelatedItems } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductPage({ productId }: { productId: string }) {\n  const { hasConsented } = useCompliance();\n\n  // Only fetch recommendations if user has consented\n  const { relatedItems, loading } = useRelatedItems({\n    item_id: productId,\n    methods: ['outfits', 'similar_items'],\n  });\n\n  return (\n    \u003cView\u003e\n      \u003cText\u003eProduct Details\u003c/Text\u003e\n\n      {hasConsented === true ? (\n        // Show personalized content when user has consented\n        \u003cView\u003e\n          {loading ? (\n            \u003cText\u003eLoading personalized recommendations...\u003c/Text\u003e\n          ) : (\n            relatedItems \u0026\u0026 (\n              \u003cView\u003e\n                \u003cText\u003eRecommended for You\u003c/Text\u003e\n                {/* Render recommendations */}\n              \u003c/View\u003e\n            )\n          )}\n        \u003c/View\u003e\n      ) : hasConsented === false ? (\n        // Show generic message when user declined\n        \u003cText\u003e\n          Enable data tracking in settings to see personalized recommendations.\n        \u003c/Text\u003e\n      ) : (\n        // Show loading state while consent status is being determined\n        \u003cText\u003eLoading...\u003c/Text\u003e\n      )}\n    \u003c/View\u003e\n  );\n}\n```\n\n---\n\n## Debug Logging\n\nThe Dressipi SDK includes comprehensive internal logging for debugging purposes. By default, these logs are disabled to prevent sensitive information from appearing in production applications.\n\n### Enabling Debug Logs\n\nTo enable debug logging during development or troubleshooting, set the following configuration on your DressipiProvider:\n\n```tsx\n\u003cDressipiProvider\n  namespaceId=\"your-namespace-id\"\n  domain=\"your-domain.com\"\n  clientId=\"your-client-id\"\n  enableLogging={true}\n\u003e\n  \u003cApp /\u003e\n\u003c/DressipiProvider\u003e\n```\n\n### What Gets Logged\n\nWhen debug logging is enabled, you'll see detailed information about:\n\n- **API Requests**: URLs, parameters, and request timing\n- **Authentication Flow**: OAuth token acquisition and refresh processes\n- **Response Data**: API responses and data mapping operations\n- **Error Details**: Detailed error messages and stack traces\n- **Storage Operations**: Keychain/SecureStore read/write operations\n\n### Security Note\n\nDebug logs may contain sensitive information such as:\n\n- API endpoints and request parameters\n- Authentication tokens and user identifiers\n- Product data and search queries\n\n**Important**: Only enable debug logging in development environments. Never enable this in production builds distributed to end users.\n\n### Example Debug Output\n\nWith debug logging enabled, you'll see console output like:\n\n```\n[25-06-2025 14:30:15] [auth.ts] Fetching OAuth authorization from Dressipi API.\n[25-06-2025 14:30:16] [auth.ts] Received OAuth authorization from Dressipi API.\n[25-06-2025 14:30:17] [related-items.ts] Fetching Related Items from Dressipi API\n[25-06-2025 14:30:18] [related-items.ts] Received related items from Dressipi API\n```\n\n## Types\n\n### Core Types\n\n#### DetailedItem\n\nRepresents a product item with complete information:\n\n```typescript\ntype DetailedItem = {\n  id: string; // Unique item identifier\n  dressipi_item_id: number; // Dressipi's internal ID\n  name: string; // Product name\n  price?: string; // Current price\n  old_price?: string; // Original price (if on sale)\n  brand_name: string; // Brand name\n  url: string; // Product URL\n  category_name?: string; // Product category\n  category_id?: number; // Category ID\n  images: string[]; // Array of image URLs\n  image_url: string; // Primary image URL\n  best_model_image?: string; // Best model image URL\n  best_product_image?: string; // Best product image URL\n  has_outfits: boolean; // Whether item has outfit recommendations\n  status: 'in stock' | 'out of stock'; // Availability status\n  style_id?: string; // Style identifier\n};\n```\n\n#### Outfit\n\nRepresents a complete outfit recommendation:\n\n```typescript\ntype Outfit = {\n  content_id: string; // Unique outfit identifier\n  occasion: string; // Occasion (e.g., 'work', 'casual')\n  items: DetailedItem[]; // Items in the outfit\n};\n```\n\n#### RelatedItemsMethod\n\nEnum for specifying which types of recommendations to fetch:\n\n```typescript\nenum RelatedItemsMethod {\n  Outfits = 'outfits',\n  PartnerOutfits = 'partner_outfits',\n  SimilarItems = 'similar_items',\n}\n```\n\n#### RelatedItemsApiRequest\n\nType for configuring related items API requests:\n\n```typescript\ntype RelatedItemsApiRequest = {\n  item_id?: string; // Item identifier\n  response_format?: ResponseFormat; // Response detail level\n  methods?: RelatedItemsMethod | RelatedItemsMethod[]; // Recommendation types\n  try_all_methods?: boolean; // Fallback to all methods\n  outfits_per_occasion?: number; // Max outfits per occasion\n  max_similar_items?: number; // Max similar items\n  max_reduced_by?: number; // Max discount percentage\n  identifier_type?: RelatedItemsIdentifierType; // Identifier type\n};\n```\n\n#### RelatedItemsMappedResponse\n\nType for the processed related items response:\n\n```typescript\ntype RelatedItemsMappedResponse = {\n  response_id: string; // Unique response identifier\n  outfits?: Outfit[]; // Outfit recommendations\n  partner_outfits?: Outfit[]; // Partner outfit recommendations\n  similar_items?: {\n    // Similar items group\n    content_id: string; // Content identifier\n    items: DetailedItem[]; // Array of similar items\n  };\n};\n```\n\n#### FacettedSearchApiRequest\n\nType for configuring facetted search API requests:\n\n```typescript\ntype FacettedSearchApiRequest = {\n  facets?: (FacetSingleFilter | FacetMultipleFilter)[]; // Search filters\n  response_format?: ResponseFormat; // Response detail level\n  page?: number; // Page number\n  per_page?: number; // Items per page\n};\n```\n\n#### FacettedSearchMappedResponse\n\nType for the processed facetted search response:\n\n```typescript\ntype FacettedSearchMappedResponse = {\n  response_id: string; // Unique response identifier\n  content_id: string; // Content identifier\n  items: DetailedItem[]; // Filtered product items\n  pagination: {\n    // Pagination information\n    last_page: number; // Total pages\n    current_page: number; // Current page\n    total_items: number; // Total items count\n  };\n};\n```\n\n## Examples\n\n### Error Handling Example\n\n```tsx\nimport { useRelatedItems } from 'mapp-fashion-react-native-sdk';\n\nfunction ProductWithErrorHandling({ productId }: { productId: string }) {\n  const { relatedItems, loading, error } = useRelatedItems({\n    item_id: productId,\n    methods: [RelatedItemsMethod.Outfits],\n  });\n\n  if (loading) {\n    return \u003cActivityIndicator size=\"large\" /\u003e;\n  }\n\n  if (error) {\n    return (\n      \u003cView\u003e\n        \u003cText\u003eFailed to load recommendations\u003c/Text\u003e\n        \u003cText\u003e{error.message}\u003c/Text\u003e\n        \u003cTouchableOpacity onPress={() =\u003e window.location.reload()}\u003e\n          \u003cText\u003eRetry\u003c/Text\u003e\n        \u003c/TouchableOpacity\u003e\n      \u003c/View\u003e\n    );\n  }\n\n  if (!relatedItems || !relatedItems.outfits?.length) {\n    return \u003cText\u003eNo recommendations available for this item\u003c/Text\u003e;\n  }\n\n  return (\n    \u003cView\u003e\n      {relatedItems.outfits.map(outfit =\u003e (\n        \u003cOutfitCard key={outfit.content_id} outfit={outfit} /\u003e\n      ))}\n    \u003c/View\u003e\n  );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapp-digital%2Fmapp-fashion-reactnative-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmapp-digital%2Fmapp-fashion-reactnative-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapp-digital%2Fmapp-fashion-reactnative-plugin/lists"}