[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/id-ID.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Detail Produk",
  "admin/editor.product-details.description": "Komponen Detail Komponen",
  "admin/editor.product-details.maxImages.title": "Gambar mini maksimal",
  "admin/editor.product-details.displayVertically.title": "Tampilkan gambar mini secara vertikal",
  "admin/editor.product-details.highlights.default": "Pilih sorotan default",
  "store/button-label": "Beli",
  "store/addToCartButton.label": "Tambah item ke troli",
  "store/share.title": "{product} {sku} di {store}: ",
  "admin/editor.product-details.highlights.title": "Ketik grup spesifikasi di bawah ini",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Ketik spesifikasi di bawah ini",
  "admin/editor.product-details.showHighlight.title": "Tampilkan sorotan",
  "admin/editor.product-details.highlights.allSpecifications": "Semua Spesifikasi",
  "admin/editor.product-details.highlights.chooseDefault": "Spesifikasi Grup",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Spesifikasi Bidang",
  "admin/editor.product-details.thumbnailsPosition.title": "Posisi gambar mini",
  "admin/editor.product-details.thumbnailsPosition.left": "Kiri",
  "admin/editor.product-details.thumbnailsPosition.right": "Kanan",
  "store/product-details.quantity": "Jumlah",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# tersedia} other {# tersedia}}",
  "admin/editor.product-quantity-selector.title": "Komponen Pemilih Jumlah Produk",
  "admin/editor.product-quantity-selector.description": "Komponen yang memungkinkan pengguna untuk memilih jumlah item untuk ditambahkan ke troli",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Ambang batas peringatan jumlah yang tersedia",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Hanya tampilkan jumlah item yang stoknya tersedia jika jumlah item yang tersedia kurang atau sama dengan nilai yang diteruskan dalam properti ini",
  "admin/editor.product-specifications.displaySpecification.title": "Tampilkan Spesifikasi Produk berdasarkan:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Mode lihat tab",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Mode lihat tabel",
  "admin/editor.product-details.product-specifications.default": "Pilih spesifikasi default",
  "admin/editor.product-details.product-specifications.allSpecifications": "Semua Spesifikasi",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Spesifikasi Bidang",
  "admin/editor.product-details.product-specifications.typeHelper": "Ketik nilai pisahkan dengan koma",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Ketik spesifikasi di bawah ini"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/pt.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Detalhes do produto",
  "admin/editor.product-details.description": "Componente de detalhes do produto",
  "admin/editor.product-details.maxImages.title": "Número máximo de imagens em miniatura",
  "admin/editor.product-details.displayVertically.title": "Exibir miniaturas na vertical",
  "admin/editor.product-details.highlights.default": "Escolha o destaque padrão ",
  "store/button-label": "Comprar",
  "store/addToCartButton.label": "Adicionar ao carrinho",
  "store/share.title": "{product} {sku} na {store}: ",
  "admin/editor.product-details.highlights.title": "Insira o grupo de especificações abaixo",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Insira as especificações abaixo",
  "admin/editor.product-details.showHighlight.title": "Mostrar destaques",
  "admin/editor.product-details.highlights.allSpecifications": "Todas as especificações",
  "admin/editor.product-details.highlights.chooseDefault": "Especificações personalizadas",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Especificações personalizadas",
  "admin/editor.product-details.thumbnailsPosition.title": "Posição das miniaturas",
  "admin/editor.product-details.thumbnailsPosition.left": "Esquerda",
  "admin/editor.product-details.thumbnailsPosition.right": "Direita",
  "store/product-details.quantity": "Quantidade",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# disponível} other {# disponíveis}}",
  "admin/editor.product-quantity-selector.title": "Seletor de quantidade do produto",
  "admin/editor.product-quantity-selector.description": "Um componente que permite ao usuário selecionar a quantidade de items para adicionar ao carrinho.",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Limite de aviso de quantidade disponível",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Somente mostrar a quantidade de itens em estoque se a quantidade de itens disponíveis for menor que o valor passado nessa propriedade.",
  "admin/editor.product-specifications.displaySpecification.title": "Exibir especificações do produto por:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Visualização em abas",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Visualização em tabela",
  "admin/editor.product-details.product-specifications.default": "Escolha o destaque padrão",
  "admin/editor.product-details.product-specifications.allSpecifications": "Todas as especificações",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Especificações personalizadas",
  "admin/editor.product-details.product-specifications.typeHelper": "Os valores devem ser separados por vírgula",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Insira as especificações abaixo"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/en.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Product Details",
  "admin/editor.product-details.description": "Product details component",
  "admin/editor.product-details.maxImages.title": "Max thumbnail images",
  "admin/editor.product-details.displayVertically.title": "Display thumbnails vertically",
  "admin/editor.product-details.highlights.default": "Choose default highlight",
  "store/button-label": "Buy",
  "store/addToCartButton.label": "Add item to cart",
  "store/share.title": "{product} {sku} at {store}: ",
  "admin/editor.product-details.highlights.title": "Enter specification groups below",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Enter specifications below",
  "admin/editor.product-details.showHighlight.title": "Show highlights",
  "admin/editor.product-details.highlights.allSpecifications": "All Specifications",
  "admin/editor.product-details.highlights.chooseDefault": "Group Specifications",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Field Specifications",
  "admin/editor.product-details.thumbnailsPosition.title": "Thumbnail Position",
  "admin/editor.product-details.thumbnailsPosition.left": "Left",
  "admin/editor.product-details.thumbnailsPosition.right": "Right",
  "store/product-details.quantity": "Quantity",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# available} other {# available}}",
  "admin/editor.product-quantity-selector.title": "Product quantity selector component",
  "admin/editor.product-quantity-selector.description": "Component that allows the user to select the amount of items to be added to the cart",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Threshold of available quantity warning",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Only show the quantity of remaining items in stock if available item quantity is less than or equal to the value passed in this property",
  "admin/editor.product-specifications.displaySpecification.title": "Display product specifications by:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Tab view mode",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Table view mode",
  "admin/editor.product-details.product-specifications.default": "Choose default specifications",
  "admin/editor.product-details.product-specifications.allSpecifications": "All Specifications",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Field Specifications",
  "admin/editor.product-details.product-specifications.typeHelper": "Enter the values separate by commas",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Enter specifications below"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/ro-RO.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Detalii produs",
  "admin/editor.product-details.description": "Componentă detalii produs",
  "admin/editor.product-details.maxImages.title": "Max imagini în miniatură",
  "admin/editor.product-details.displayVertically.title": "Afișează imaginile în miniatură vertical",
  "admin/editor.product-details.highlights.default": "Alege evidențierea implicită",
  "store/button-label": "Cumpără",
  "store/addToCartButton.label": "Adaugă articolul în coș",
  "store/share.title": "{product} {sku} la {store}: ",
  "admin/editor.product-details.highlights.title": "Introdu grupurile de specificații mai jos",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Introdu specificațiile mai jos",
  "admin/editor.product-details.showHighlight.title": "Arată-le pe cele mai remarcabile",
  "admin/editor.product-details.highlights.allSpecifications": "Toate specificațiile",
  "admin/editor.product-details.highlights.chooseDefault": "Specificații grupuri",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Specificații câmpuri",
  "admin/editor.product-details.thumbnailsPosition.title": "Poziție miniaturi",
  "admin/editor.product-details.thumbnailsPosition.left": "Stânga",
  "admin/editor.product-details.thumbnailsPosition.right": "Dreapta",
  "store/product-details.quantity": "Cantitate",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# disponibil} other {# disponibile}}",
  "admin/editor.product-quantity-selector.title": "Componentă Selector Cantitate Produs",
  "admin/editor.product-quantity-selector.description": "O componentă care îi permite utilizatorului să selecteze cantitatea de articole de adăugat în coș",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Atenționare prag cantitate disponibilă",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Arată doar cantitatea articolelor rămase în stoc dacă cantitatea articolelor disponibile este mai mică sau egală cu valoarea introdusă în această proprietate",
  "admin/editor.product-specifications.displaySpecification.title": "Afișează specificațiile de produs în funcție de:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Mod de vizualizare tab",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Mod de vizualizare tabel",
  "admin/editor.product-details.product-specifications.default": "Alege specificațiile prestabilite",
  "admin/editor.product-details.product-specifications.allSpecifications": "Toate specificațiile",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Specificații câmpuri",
  "admin/editor.product-details.product-specifications.typeHelper": "Introdu valorile separate prin virgulă",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Introdu specificațiile mai jos"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/da-DK.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Produktdetaljer",
  "admin/editor.product-details.description": "Produktdetaljer komponent",
  "admin/editor.product-details.maxImages.title": "Maks. miniaturebilleder",
  "admin/editor.product-details.displayVertically.title": "Vis miniaturebilleder vertikalt",
  "admin/editor.product-details.highlights.default": "Vælg standard fremhævning",
  "store/button-label": "Køb",
  "store/addToCartButton.label": "Føj vare til kurv",
  "store/share.title": "{product} {sku} i {store}: ",
  "admin/editor.product-details.highlights.title": "Type specifikationsgrupper under",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Typespecifikationer under",
  "admin/editor.product-details.showHighlight.title": "Vis fremhævelser",
  "admin/editor.product-details.highlights.allSpecifications": "Alle specifikationer",
  "admin/editor.product-details.highlights.chooseDefault": "Gruppespecifikationer",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Feltspecifikationer",
  "admin/editor.product-details.thumbnailsPosition.title": "Miniaturebilleders position",
  "admin/editor.product-details.thumbnailsPosition.left": "Venstre",
  "admin/editor.product-details.thumbnailsPosition.right": "Højre",
  "store/product-details.quantity": "Antal",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# tilgængelig} other {# tilgængelig}}",
  "admin/editor.product-quantity-selector.title": "Produktmængde vælgerkomponent",
  "admin/editor.product-quantity-selector.description": "En komponent, der giver brugeren mulighed for at vælge den mængde varer, der skal tilføjes i indkøbskurven",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Tærskel for tilgængelig mængdeadvarsel",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Vis kun mængden af resterende varer på lager, hvis den disponible varemængde er mindre end eller lig med den værdi, der er videregivet i denne egenskab",
  "admin/editor.product-specifications.displaySpecification.title": "Vis produktspecifikationer efter:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Fanevisningstilstand",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Tabelvisningstilstand",
  "admin/editor.product-details.product-specifications.default": "Vælg standardspecifikationer",
  "admin/editor.product-details.product-specifications.allSpecifications": "Alle specifikationer",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Feltspecifikationer",
  "admin/editor.product-details.product-specifications.typeHelper": "Indtast værdierne adskilt med komma",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Skriv specifikationerne under"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/context.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "admin/editor.product-details.title",
  "admin/editor.product-details.description": "admin/editor.product-details.description",
  "admin/editor.product-details.highlights": "admin/editor.product-details.highlights",
  "admin/editor.product-details.highlights.title": "admin/editor.product-details.highlights.title",
  "admin/editor.product-details.showHighlight": "admin/editor.product-details.showHighlight",
  "admin/editor.product-details.showHighlight.title": "admin/editor.product-details.showHighlight.title",
  "admin/editor.product-details.highlights.default": "admin/editor.product-details.highlights.default",
  "admin/editor.product-details.highlights.allSpecifications": "admin/editor.product-details.highlights.allSpecifications",
  "admin/editor.product-details.highlights.chooseDefault": "admin/editor.product-details.highlights.chooseDefault",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "admin/editor.product-details.highlights.chooseDefaultSpecification",
  "admin/editor.product-details.highlights.typeSpecifications.title": "admin/editor.product-details.highlights.typeSpecifications.title",
  "admin/editor.product-details.maxImages.title": "admin/editor.product-details.maxImages.title",
  "admin/editor.product-details.displayVertically.title": "admin/editor.product-details.displayVertically.title",
  "store/button-label": "store/button-label",
  "store/addToCartButton.label": "store/addToCartButton.label",
  "store/share.title": "store/share.title",
  "admin/editor.product-details.thumbnailsPosition.title": "admin/editor.product-details.thumbnailsPosition.title",
  "admin/editor.product-details.thumbnailsPosition.left": "admin/editor.product-details.thumbnailsPosition.left",
  "admin/editor.product-details.thumbnailsPosition.right": "admin/editor.product-details.thumbnailsPosition.right",
  "store/product-details.quantity": "Item quantity",
  "store/product-details.quantity-available": "Tells user how many items are available in stock",
  "admin/editor.product-quantity-selector.title": "Title of Product Quantity Selector component",
  "admin/editor.product-quantity-selector.description": "Description of Product Quantity Selector component",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Title of warningQuantityThreshold property",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Description of warningQuantityThreshold property",
  "admin/editor.product-specifications.displaySpecification.title": "admin/editor.product-specifications.displaySpecification.title",
  "admin/editor.product-specifications.displaySpecification.tabMode": "admin/editor.product-specifications.displaySpecification.tabMode",
  "admin/editor.product-specifications.displaySpecification.tableMode": "admin/editor.product-specifications.displaySpecification.tableMode",
  "admin/editor.product-details.product-specifications.default": "admin/editor.product-details.product-specifications.default",
  "admin/editor.product-details.product-specifications.allSpecifications": "admin/editor.product-details.product-specifications.allSpecifications",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "admin/editor.product-details.product-specifications.chooseDefaultSpecification",
  "admin/editor.product-details.product-specifications.typeHelper": "admin/editor.product-details.product-specifications.typeHelper",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "admin/editor.product-details.product-specifications.typeSpecifications.title"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/fi-FI.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Tuotteen tiedot",
  "admin/editor.product-details.description": "Tuotetietokomponentti",
  "admin/editor.product-details.maxImages.title": "Pikkukuvien maksimimäärä",
  "admin/editor.product-details.displayVertically.title": "Näytä pikkukuvat vaakatasossa",
  "admin/editor.product-details.highlights.default": "Valitse oletuskorostus",
  "store/button-label": "Osta",
  "store/addToCartButton.label": "Lisää tuote ostoskoriin",
  "store/share.title": "{product} {sku} myymälässä {store}: ",
  "admin/editor.product-details.highlights.title": "Kirjoita tietoryhmät alle",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Kirjoita tiedot alle",
  "admin/editor.product-details.showHighlight.title": "Näytä korostukset",
  "admin/editor.product-details.highlights.allSpecifications": "Kaikki tiedot",
  "admin/editor.product-details.highlights.chooseDefault": "Ryhmien tiedot",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Kenttien tiedot",
  "admin/editor.product-details.thumbnailsPosition.title": "Pikkukuvien sijainti",
  "admin/editor.product-details.thumbnailsPosition.left": "Vasemmalla",
  "admin/editor.product-details.thumbnailsPosition.right": "Oikealla",
  "store/product-details.quantity": "Lukumäärä",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# saatavilla} other {# saatavilla}}",
  "admin/editor.product-quantity-selector.title": "Tuotemäärän valintakomponentti",
  "admin/editor.product-quantity-selector.description": "Komponentti, jonka avulla käyttäjä voi valita ostoskoriin lisättävien tuotteiden määrän",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Saatavilla olevan määrän rajavaroitus",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Näytä vain varastossa jäljellä olevien tuotteiden määrä, jos tuotteen saatavilla oleva määrä on alle tai yhtä kujin tässä ominaisuudessa oleva arvo",
  "admin/editor.product-specifications.displaySpecification.title": "Tuotetietojen näyttöperuste:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Välilehtinäkymä-tila",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Taulukkonäkymä-tila",
  "admin/editor.product-details.product-specifications.default": "Valitse oletustiedot",
  "admin/editor.product-details.product-specifications.allSpecifications": "Kaikki tiedot",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Kenttien tiedot",
  "admin/editor.product-details.product-specifications.typeHelper": "Kirjoita arvot pilkuilla eroteltuna",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Kirjoita tiedot alle"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/es.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "Detalles del producto",
  "admin/editor.product-details.description": "Componente de detalles del producto",
  "admin/editor.product-details.maxImages.title": "Número máximo de imágenes en miniatura",
  "admin/editor.product-details.displayVertically.title": "Mostrar miniaturas verticalmente",
  "admin/editor.product-details.highlights.default": "Elegir destaque predeterminado ",
  "store/button-label": "Comprar",
  "store/addToCartButton.label": "Incluir items en el carrito",
  "store/share.title": "{product} {sku} en la {store}: ",
  "admin/editor.product-details.highlights.title": "Escriva de especificación de los grupos de abajo",
  "admin/editor.product-details.highlights.typeSpecifications.title": "Escriva las especificaciones abajo",
  "admin/editor.product-details.showHighlight.title": "Mostrar lo más destacados",
  "admin/editor.product-details.highlights.allSpecifications": "Todas las especificaciones",
  "admin/editor.product-details.highlights.chooseDefault": "Grupo del especificaciones personalizadas",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "Especificaciones personalizadas",
  "admin/editor.product-details.thumbnailsPosition.title": "Posición de miniaturas",
  "admin/editor.product-details.thumbnailsPosition.left": "Izquierda",
  "admin/editor.product-details.thumbnailsPosition.right": "Derecha",
  "store/product-details.quantity": "Cantidad",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# disponible} other {# disponibles}}",
  "admin/editor.product-quantity-selector.title": "Selector de Cantidad de Producto",
  "admin/editor.product-quantity-selector.description": "Un componente que permite al usuario a seleccionar la cantidad de elementos para añadir al carrito.",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "Cantidad de umbral disponible",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "Sólo muestra la cantidad de elementos en stock si la cantidad de elementos disponibles es menor que el valor pasado en esa propiedad.",
  "admin/editor.product-specifications.displaySpecification.title": "Mostrar la Especificaciones del Product por:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "Modo de vista de tab",
  "admin/editor.product-specifications.displaySpecification.tableMode": "Modo de vista de tabela",
  "admin/editor.product-details.product-specifications.default": "Elegir destaque predeterminado",
  "admin/editor.product-details.product-specifications.allSpecifications": "Todas las especificaciones",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "Especificaciones personalizadas",
  "admin/editor.product-details.product-specifications.typeHelper": "Escriba los valores separados por coma",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "Escriva las especificaciones abajo"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/messages/ar.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.product-details.title": "تفاصيل المنتج",
  "admin/editor.product-details.description": "مكون تفاصيل المنتج",
  "admin/editor.product-details.maxImages.title": "أقصى تصغير للصور",
  "admin/editor.product-details.displayVertically.title": "عرض الصور المصغرة أفقيًا",
  "admin/editor.product-details.highlights.default": "اختر التحديد الافتراضي",
  "store/button-label": "شراء",
  "store/addToCartButton.label": "إضافة عنصر إلى العربة",
  "store/share.title": "{product} {sku} في {store}: ",
  "admin/editor.product-details.highlights.title": "اكتب مجموعات المواصفات أدناه",
  "admin/editor.product-details.highlights.typeSpecifications.title": "اكتب المواصفات أدناه",
  "admin/editor.product-details.showHighlight.title": "عرض المواصفات",
  "admin/editor.product-details.highlights.allSpecifications": "كل المواصفات",
  "admin/editor.product-details.highlights.chooseDefault": "مواصفات المجموعات",
  "admin/editor.product-details.highlights.chooseDefaultSpecification": "مواصفات الحقول",
  "admin/editor.product-details.thumbnailsPosition.title": "موضع الصور المصغرة",
  "admin/editor.product-details.thumbnailsPosition.left": "اليسار",
  "admin/editor.product-details.thumbnailsPosition.right": "اليمين",
  "store/product-details.quantity": "الكمية",
  "store/product-details.quantity-available": "{availableQuantity, plural, one {# متاح} other {# متاحة}}",
  "admin/editor.product-quantity-selector.title": "مكون محدد كمية المنتج",
  "admin/editor.product-quantity-selector.description": "مكون يسمح للمستخدم بتحديد كمية العناصر لإضافتها إلى سلة التسوق",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.title": "تحذير بعتبة الكمية المتاحة",
  "admin/editor.product-quantity-selector.warningQuantityThreshold.description": "اعرض فقط كمية العناصر المتبقية في المخزون إذا كانت الكمية المتاحة للعنصر أقل من القيمة التي تم تمريرها في هذه الخاصية أو تساويها",
  "admin/editor.product-specifications.displaySpecification.title": "عرض مواصفات المنتج من خلال:",
  "admin/editor.product-specifications.displaySpecification.tabMode": "وضع عرض علامة التبويب",
  "admin/editor.product-specifications.displaySpecification.tableMode": "وضع عرض الجدول",
  "admin/editor.product-details.product-specifications.default": "اختر المواصفات الافتراضية",
  "admin/editor.product-details.product-specifications.allSpecifications": "كل المواصفات",
  "admin/editor.product-details.product-specifications.chooseDefaultSpecification": "مواصفات الحقول",
  "admin/editor.product-details.product-specifications.typeHelper": "اكتب القيم مفصولة بفاصلة",
  "admin/editor.product-details.product-specifications.typeSpecifications.title": "اكتب المواصفات أدناه"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/docs/README.md from the product-details VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX Product Details
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

## Description

The VTEX Category Menu app shows the details of a product like image, name and price. THis app is used by store theme.

:loudspeaker: **Disclaimer:** Don't fork this project. Use, contribute, or open issue with your feature request.

## Release schedule

| Release |       Status        | Initial Release | Maintenance LTS Start | End-of-life | Dreamstore Compatibility |
| :-----: | :-----------------: | :-------------: | :-------------------: | :---------: | :----------------------: |
|  [1.x]  | **Current Release** |   2018-11-28    |                       |             |           2.x            |
|  [0.x]  | **Maintenance LTS** |   2018-05-29    |      2018-11-28       | March 2019  |           1.x            |

See our [LTS policy](https://github.com/vtex-apps/awesome-io#lts-policy) for more information.

## Table of Contents

- [Usage](#usage)
  - [Blocks API](#blocks-api)
    - [Configuration](#configuration)
  - [Styles API](#styles-api)
    - [CSS namespaces](#css-namespaces)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [Tests](#tests)

## Usage

This app uses our store builder with the blocks architecture. To know more about Store Builder [click here.](https://help.vtex.com/en/tutorial/understanding-storebuilder-and-stylesbuilder#structuring-and-configuring-our-store-with-object-object)

We add the product-details as a block in our [Store Header](https://github.com/vtex-apps/store-header/blob/master/store/interfaces.json).

To configure or customize this app, you need to import it in your dependencies in `manifest.json`.

```json
  dependencies: {
    "vtex.product-details": "1.x"
  }
```

Then, add `product-details` block into your app theme, like we do in our [Store theme app](https://github.com/vtex-apps/store-theme/blob/master/store/blocks.json).

Now, you can change the behavior of the `product-details` block that is in the store header. See an example of how to configure:

```json
  "product-details": {
      "blocks": [
        "breadcrumb",
        "product-name",
        "product-images",
        "product-price",
        "product-description",
        "product-specifications",
        "buy-button",
        "sku-selector",
        "shipping-simulator",
        "availability-subscriber",
        "share"
      ],
      "props": {
        "displayVertically": true,
        "share": {
          "social": {
            "Facebook": true,
            "WhatsApp": true,
            "Twitter": false
          }
        },
        "price": {
          "labelSellingPrice": null,
          "showListPrice": true,
          "showLabels": true,
          "showInstallments": true,
          "showSavings": true
        },
        "name": {
          "showBrandName": false,
          "showSku": false,
          "showProductReference": false
        }
      }
    }
```

### Blocks API

When implementing this app as a block, various inner blocks may be available. The following interface lists the available blocks within `product-details` and describes if they are required or optional.

```json
{
  "product-details": {
    "required": [
      "product-images",
      "product-name",
      "product-price",
      "sku-selector",
      "buy-button",
      "product-description",
      "product-specifications"
    ],
    "allowed": [
      "breadcrumb",
      "shipping-simulator",
      "availability-subscriber",
      "share",
      "addon-details-btn"
    ],
    "component": "ProductDetails"
  },
  "addon-details-btn": {
    "component": "*"
  }
}
```

The `ProductDetails` has the required blocks: `product-images`, `product-name`, `product-price`, `sku-selector`, `buy-button`, `product-description` and `product-specifications`. So, any `ProductDetails` block implementation created must add these blocks.

#### Configuration

Through the Storefront you can change the behavior and interface of `ProductDetails`. But, you can also make adjusts in your theme app, like Store does.

| Prop name               | Type      | Description                                                       | Default Value |
| ----------------------- | --------- | ----------------------------------------------------------------- | ------------- |
| `price`                 | `Object`  | Configures the product price area (More info on the table bellow) | false         |
| `name`                  | `Object`  | Configures the product name area (More info on the table bellow)  | false         |
| `displayVertically`     | `Boolean` | Whether to display the preview images on the vertical or not      | false         |
| `showSpecificationsTab` | `Boolean` | Whether to display the product specification on tab mode or not   | false         |

Price:

| Prop name           | Type      | Description                                    |
| ------------------- | --------- | ---------------------------------------------- |
| `showListPrice`     | `Boolean` | Shows the list prices                          | true |
| `showLabels`        | `Boolean` | Shows the labels in the price and installments | true |
| `showInstallments`  | `Boolean` | Shows the installments information             | true |
| `showSavings`       | `Boolean` | Shows the savings information                  | true |
| `labelSellingPrice` | `String`  | Text of the label before the price             | `null` |

Name:

| Prop name              | Type      | Description                          |
| ---------------------- | --------- | ------------------------------------ |
| `showProductReference` | `Boolean` | Shows the product reference          | false |
| `showBrandName`        | `Boolean` | Shows the brand name of the product  | false |
| `showSku`              | `Boolean` | Shows the sku value for this product | false |

Highlight:

| Prop name          | Type      | Description                                                                                |
| ------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------- |
| `defaultHighlight` | `boolean` | Indicates whether the group chosen as the highlight will contain all the properties in product or a group typed entry. |
| true               |
| `showHighlights`   | `Boolean` | Shows the highlights of the product                                                                                | true |
| `highlightGroup`   |

Specification:

 | Prop name             | Type      | Description                                                                                |
| --------------------- | --------- | -------------------------------------------------------------------------------------------------- |
| `showSpecifications`  | `boolean` | Show the specifications of the product                                                             |
| `specificationGroups` | `object`  | Define if will be displayed all the specifications of the product or a set of this specifications. |
| `viewMode`            | `string`  | Define what is the current view mode for the specifications.                                       |
| `typeSpecifications`  | `string`  | indicates which specifications will be displayed                                                   |

Also, you can configure the `share` that is defined on `ProductDetails`. See [here](https://github.com/vtex-apps/store-components/blob/master/react/components/Share/README.md) the `Share` API.

### Styles API

This app provides some CSS classes as an API for style customization.

To use this CSS API, you must add the `styles` builder and create an app styling CSS file.

1. Add the `styles` builder to your `manifest.json`:

```json
  "builders": {
    "styles": "1.x"
  }
```

2. Create a file called `vtex.product-details.css` inside the `styles/css` folder. Add your custom styles:

```css
.container {
  margin-top: 10px;
}
```

#### CSS namespaces

Below, we describe the namespaces that is define in the `ProductDetails`.

| Class name              | Description                              | Component Source                                            |
| ----------------------- | ---------------------------------------- | ----------------------------------------------------------- |
| `container`             | The main container of Product Details    | [productDetails](/react/productDetails.js)                  |
| `nameContainer`         | The container of the name area           | [productDetails](/react/productDetails.js)                  |
| `detailsContainer`      | The container of the details area        | [productDetails](/react/productDetails.js)                  |
| `priceContainer`        | The container of the price area          | [productDetails](/react/productDetails.js)                  |
| `informationsContainer` | The container of the information area    | [productDetails](/react/productDetails.js)                  |
| `fixedButton`           | The product buy button                   | [FixedButton/index](/react/components/FixedButton/index.js) |
| `highlightsContainer`   | The container of product highlights area | [productDetails](/react/productDetails.js)                  |

## Troubleshooting

You can check if others are passing through similar issues [here](https://github.com/vtex-apps/product-details/issues). Also feel free to [open issues](https://github.com/vtex-apps/product-details/issues/new) or contribute with pull requests.

## Contributing

Check it out [how to contribute](https://github.com/vtex-apps/awesome-io#contributing) with this project.

## Tests

To execute our tests go to `react/` folder and run `yarn test`

### Travis CI

[![Build Status](https://travis-ci.org/vtex-apps/product-details.svg?branch=master)](https://travis-ci.org/vtex-apps/product-details)

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/ProductDetails.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { any, path, prop, propOr, pathOr } from 'ramda'
import { injectIntl, intlShape, FormattedMessage } from 'react-intl'

import classNames from 'classnames'

import { ExtensionPoint, withRuntimeContext } from 'vtex.render-runtime'
import { Container } from 'vtex.store-components'

import { changeImageUrlSize } from './utils/generateUrl'
import FixedButton from './components/FixedButton'
import { productShape } from './propTypes'

import { schema } from './utils/schema'

import productDetails from './productDetails.css'

const productNameLoaderStyles = {
  'vtex-product-name__brand--loader': {
    x: 0,
    width: '100%',
    height: '1.631em',
  },
  'vtex-product-name__sku--loader': {
    x: 0,
    y: '2.569em',
    width: '10.311em',
    height: '1.045em',
  },
}

const productPriceLoaderStyles = {
  'vtex-price-list__container--loader': {
    x: 0,
    width: '7.219em',
    height: '0.56em',
  },
  'vtex-price-selling__label--loader': {
    x: 0,
    y: '2em',
    width: '2.85em',
    height: '1.08em',
  },
  'vtex-price-selling--loader': {
    x: '3.25em',
    y: '0.86em',
    width: '14.572em',
    height: '2.176em',
  },
  'vtex-price-installments--loader': {
    x: 0,
    y: '3.75em',
    width: '12em',
    height: '0.825em',
  },
  'vtex-price-savings--loader': {
    x: 0,
    y: '5em',
    width: '10em',
    height: '0.686em',
  },
}
const thresholds = [640]
const imageSizes = [1280, 1920]
const thumbnailSize = 160

const hasSellerWithAvailableItems = (item) => {
  return item.sellers && any((s) => s.commertialOffer && s.commertialOffer.AvailableQuantity > 0, item.sellers)
}

class ProductDetails extends Component {
  static defaultProps = {
    price: {
      showListPrice: true,
      showLabels: true,
      showInstallments: true,
      showSavings: true,
    },
    name: {
      showProductReference: false,
      showBrandName: false,
      showSku: false,
    },
    displayVertically: false,
    showSpecificationsTab: false,
  }

  static propTypes = {
    categories: PropTypes.arrayOf(PropTypes.string),
    /** Whether to display the preview images on the vertical or not */
    displayVertically: PropTypes.bool,
    intl: intlShape,
    /** Product name schema configuration */
    name: PropTypes.object,
    /** Query */
    productQuery: PropTypes.shape({
      product: productShape,
      loading: PropTypes.bool.isRequired,
    }),
    /** Product price schema configuration */
    price: PropTypes.object,
    /** URL query parameters */
    query: PropTypes.shape({
      skuId: PropTypes.string,
    }),
    runtime: PropTypes.object,
    /** Share Schema properties */
    share: PropTypes.shape({
      /** Social Networks configuration */
      social: PropTypes.object.isRequired,
    }),
    /** Product slug */
    slug: PropTypes.string.isRequired,
    /** Product specifications tab mode */
    showSpecificationsTab: PropTypes.bool,

    /** Define the highlight group select to display  */
    highlightGroup: PropTypes.string,
  }

  state = { selectedQuantity: 1 }

  get skuItems() {
    return pathOr([], ['productQuery', 'product', 'items'], this.props)
  }

  get selectedItem() {
    const items = path(['productQuery', 'product', 'items'], this.props) || []
    if (!this.props.query || !this.props.query.skuId) {
      return items.find(hasSellerWithAvailableItems) || items[0]
    }
    return items.find(sku => sku.itemId === this.props.query.skuId)
  }

  get commertialOffer() {
    return path(['sellers', 0, 'commertialOffer'], this.selectedItem)
  }

  get sellerId() {
    return path(['sellers', 0, 'sellerId'], this.selectedItem)
  }

  getImages() {
    const images = path(['images'], this.selectedItem)

    return images
      ? images.map(image => ({
          imageUrls: imageSizes.map(size =>
            changeImageUrlSize(image.imageUrl, size)
          ),
          thresholds,
          thumbnailUrl: changeImageUrlSize(image.imageUrl, thumbnailSize),
          imageText: image.imageText,
        }))
      : []
  }

  getSpecifications() {
    const { productQuery, specificationsDefault } = this.props

    const product = productQuery ? productQuery.product : {}

    const option = path(
      ['specificationGroups', 'specification'],
      specificationsDefault
    )
    const allSpecifications = propOr([], 'properties', product)
    const getFromProperties = () => {
      const typedSpecifications = pathOr(
        '',
        ['specificationGroups', 'typeSpecifications'],
        specificationsDefault
      )
      const specificationNames = typedSpecifications.trim().split(',')
      const specifications = specificationNames.reduce((acc, item) => {
        const specification = allSpecifications.filter(
          spec => spec.name.toLowerCase() === item.trim().toLowerCase()
        )
        return acc.concat(specification)
      }, [])
      return specifications
    }

    switch (option) {
      case 'admin/editor.product-details.product-specifications.chooseDefaultSpecification':
        return getFromProperties()
      default:
        return allSpecifications
    }
  }

  filterSpecifications() {
    const highlights = this.getHighlights()
    const specifications = this.getSpecifications()
    return {
      specifications,
      highlights,
    }
  }

  getHighlights() {
    const { productQuery, highlightGroupDefault } = this.props

    const { product } = productQuery || { product: {} }

    const option = pathOr(
      '',
      ['highlightGroupDefault', 'highlight'],
      highlightGroupDefault
    )
    const highlightsFromGroup = () => {
      const typeHighlight = pathOr(
        '',
        ['highlightGroupDefault', 'typeHighlight'],
        highlightGroupDefault
      )
      const highlightName = typeHighlight.trim()
      const names = highlightName.split(',')
      const specificationGroups = propOr([], 'specificationGroups', product)
      const highlights = names.reduce((acc, item) => {
        const highlightSpecificationGroup = specificationGroups.filter(
          x => x.name.toLowerCase() === item.trim().toLowerCase()
        )[0]
        const highlight = propOr(
          [],
          'specifications',
          highlightSpecificationGroup
        )
        return acc.concat(highlight)
      }, [])
      return highlights
    }
    const highlightsFromSpecifications = () => {
      const typeSpecifications = pathOr(
        '',
        ['highlightGroupDefault', 'typeSpecifications'],
        highlightGroupDefault
      )
      const specificationNames = typeSpecifications.trim().split(',')
      const allSpecifications = propOr([], 'properties', product)
      const highlights = specificationNames.reduce((acc, item) => {
        const highlight = allSpecifications.filter(
          x => x.name.toLowerCase() === item.trim().toLowerCase()
        )
        return acc.concat(highlight)
      }, [])
      return highlights
    }

    const highlightsFromAllSpecifications = () => {
      return propOr([], 'properties', product)
    }

    switch (option) {
      case 'admin/editor.product-details.highlights.chooseDefault':
        return highlightsFromGroup()
      case 'admin/editor.product-details.highlights.chooseDefaultSpecification':
        return highlightsFromSpecifications()
      case 'admin/editor.product-details.highlights.allSpecifications':
        return highlightsFromAllSpecifications()
    }
  }

  render() {
    const {
      productQuery,
      categories,
      categoryTree,
      runtime: {
        account,
        culture: { country },
        hints: { mobile },
      },
      intl,
      thumbnailPosition,
      highlightGroupDefault,
      specificationsDefault,
      showSpecificationsTab: showSpecificationsTabProp,
    } = this.props

    const { product } = productQuery || { product: {} }

    const { selectedQuantity } = this.state
    const showHighlight = prop('showHighlights', highlightGroupDefault)

    const showSpecificationsTab =
      showSpecificationsTabProp == null
        ? propOr(true, 'showSpecifications', specificationsDefault)
        : showSpecificationsTabProp

    const viewMode = prop('viewMode', specificationsDefault) || 'tab'

    const viewSpecificationsMode = viewMode === 'tab'

    const showBuyButton =
      Number.isNaN(+path(['AvailableQuantity'], this.commertialOffer)) || // Show the BuyButton loading information
      path(['AvailableQuantity'], this.commertialOffer) > 0

    const skuName = path(['name'], this.selectedItem)
    const description = path(['description'], product)
    const { specifications, highlights } = this.filterSpecifications()
    const buyButtonProps = {
      skuItems: this.selectedItem &&
        this.sellerId && [
          {
            skuId: this.selectedItem.itemId,
            quantity: selectedQuantity,
            seller: this.sellerId,
            name: this.selectedItem.nameComplete,
            price: this.commertialOffer.Price,
            variant: this.selectedItem.name,
            brand: product.brand,
            index: 0,
            detailUrl: `/${product.linkText}/p`,
            imageUrl: path(['images', '0', 'imageUrl'], this.selectedItem),
            listPrice: path(
              ['sellers', '0', 'commertialOffer', 'ListPrice'],
              this.selectedItem
            ),
          },
        ],
      large: true,
      available: showBuyButton,
    }

    const productNameProps = {
      styles: productNameLoaderStyles,
      name: path(['productName'], product),
      skuName: path(['name'], this.selectedItem),
      brandName: path(['brand'], product),
      productReference: path(['productReference'], product),
      className: 't-heading-4',
      tag: 'h1',
      ...this.props.name,
    }

    const productPriceProps = {
      styles: productPriceLoaderStyles,
      listPriceContainerClass: 't-small-s t-small-ns c-muted-2 mb2',
      sellingPriceLabelClass: 't-heading-6-s t-heading-5-ns dib',
      listPriceLabelClass: 'dib strike',
      listPriceClass: 'ph2 dib strike',
      sellingPriceContainerClass: 'pv1 b c-on-base',
      sellingPriceClass: 't-heading-2-s dib ph2',
      installmentContainerClass: 't-mini-s t-small-ns c-on-base',
      installmentClass: 't-body',
      interestRateClass: 'dib ph2',
      savingsContainerClass: 'c-success mt3',
      savingsClass: 'dib t-small',
      loaderClass: 'h4-s mw6-s pt2-s',
      listPrice: path(['ListPrice'], this.commertialOffer),
      sellingPrice: path(['Price'], this.commertialOffer),
      installments: path(['Installments'], this.commertialOffer),
      ...this.props.price,
    }
    const productImageUrl = path(['items', 0, 'images', 0, 'imageUrl'], product)

    const availableQuantity = path(['AvailableQuantity'], this.commertialOffer)
    const showProductPrice =
      Number.isNaN(+availableQuantity) || availableQuantity > 0

    const addonDetailsClasses = classNames('absolute z-3 left-0', {
      'ml-20-ns':
        this.getImages().length > 1 &&
        (!thumbnailPosition || thumbnailPosition === 'left'),
    })

    return (
      <Container
        className={`${productDetails.container} pt6 pb8 justify-center flex`}
      >
        <div className="w-100 mw9">
          <article className="mb7">
            <ExtensionPoint id="breadcrumb" />
            <div
              className={`${productDetails.nameContainer} c-on-base mb4 dn-l`}
            >
              <ExtensionPoint id="product-name" {...productNameProps} />
            </div>
            <div className="flex flex-wrap">
              <div className="w-60-l w-100">
                <div className="fr-ns w-100 h-100">
                  <div className="relative flex justify-center z-3">
                    <ExtensionPoint
                      id="product-images"
                      images={this.getImages()}
                      position={thumbnailPosition}
                    />
                    <div className={addonDetailsClasses}>
                      <ExtensionPoint
                        id="addon-details-btn"
                        large={!mobile}
                        product={{
                          quantity: 1,
                          skuId: path(['itemId'], this.selectedItem),
                          productId: path(['productId'], product),
                        }}
                      />
                    </div>
                  </div>
                </div>
              </div>
              <aside
                className={`${
                  productDetails.detailsContainer
                } pl8-l w-40-l w-100`}
              >
                <div
                  className={`${
                    productDetails.nameContainer
                  } c-on-base dn db-l mb4`}
                >
                  <ExtensionPoint id="product-name" {...productNameProps} />
                </div>
                {highlights && showHighlight && (
                  <div className={productDetails.highlightsContainer}>
                    <ExtensionPoint
                      id="product-highlights"
                      highlights={highlights}
                    />
                  </div>
                )}
                {showProductPrice && (
                  <div
                    className={`${productDetails.priceContainer} pt1 dn db-l`}
                  >
                    <ExtensionPoint id="product-price" {...productPriceProps} />
                  </div>
                )}
                <div className="mv2 mt5 dn db-l">
                  <hr className="o-30" size="1" />
                </div>
                <div className="mt6">
                  {product &&
                    this.selectedItem &&
                    this.selectedItem.variations &&
                    this.selectedItem.variations.length > 0 && (
                      <ExtensionPoint
                        id="sku-selector"
                        skuItems={this.skuItems}
                        skuSelected={this.selectedItem}
                        productSlug={product.linkText}
                        variations={this.selectedItem.variations}
                      />
                    )}
                  {showProductPrice && (
                    <div
                      className={`${
                        productDetails.priceContainer
                      } pt1 mt mt7 mt4-l dn-l`}
                    >
                      <ExtensionPoint
                        id="product-price"
                        {...productPriceProps}
                      />
                    </div>
                  )}
                  {showBuyButton ? (
                    <div className="pv2 dn db-l mt8">
                      <ExtensionPoint
                        id="product-quantity-selector"
                        selectedQuantity={selectedQuantity}
                        onChange={value =>
                          this.setState({ selectedQuantity: value })
                        }
                        availableQuantity={availableQuantity}
                      />
                      <ExtensionPoint id="buy-button" {...buyButtonProps}>
                        <FormattedMessage id="store/addToCartButton.label" />
                      </ExtensionPoint>
                    </div>
                  ) : (
                    <div className="pv4">
                      <ExtensionPoint
                        id="availability-subscriber"
                        skuId={this.selectedItem.itemId}
                        available={showBuyButton}
                      />
                    </div>
                  )}
                  <FixedButton>
                    <div className="dn-l bg-base w-100 ph5 pv3">
                      <ExtensionPoint id="buy-button" {...buyButtonProps}>
                        <FormattedMessage id="store/addToCartButton.label" />
                      </ExtensionPoint>
                    </div>
                  </FixedButton>
                  <div className="mt8">
                    <ExtensionPoint
                      id="shipping-simulator"
                      skuId={path(['itemId'], this.selectedItem)}
                      seller={this.sellerId}
                      country={country}
                    />
                  </div>
                  <div className="flex w-100 mt7">
                    <ExtensionPoint
                      id="share"
                      shareLabelClass="c-muted-2 t-small mb3"
                      className="db"
                      imageUrl={productImageUrl}
                      {...this.props.share}
                      loading={!path(['name'], this.selectedItem)}
                      title={intl.formatMessage(
                        { id: 'store/share.title' },
                        {
                          product: path(['productName'], product),
                          sku: path(['name'], this.selectedItem),
                          store: account,
                        }
                      )}
                    />
                  </div>
                </div>
              </aside>
            </div>
          </article>
          <footer
            className={`${productDetails.informationsContainer} ph5 ph0-ns`}
          >
            <div className="mv4">
              <hr className="o-30 db" size="1" />
            </div>
            <div
              className={`flex ${
                viewSpecificationsMode ? 'flex-wrap' : 'justify-between'
              }`}
            >
              {description && (
                <div className="pv2 mt8 h-100 w-100">
                  <ExtensionPoint
                    id="product-description"
                    skuName={skuName}
                    description={description}
                  />
                </div>
              )}
              {specifications && showSpecificationsTab && (
                <div className="pv2 mt8 h-100 w-100">
                  <ExtensionPoint
                    id="product-specifications"
                    tabsMode={viewSpecificationsMode}
                    specifications={specifications}
                  />
                </div>
              )}
            </div>
          </footer>
        </div>
      </Container>
    )
  }
}

ProductDetails.schema = schema

export default withRuntimeContext(injectIntl(ProductDetails))

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/ProductAddToListButton.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { useMemo, useContext } from 'react'
import { ExtensionPoint, useRuntime } from 'vtex.render-runtime'
import { ProductContext } from 'vtex.product-context'
import { path } from 'ramda'
import classNames from 'classnames'

const getSkuId = path(['selectedItem', 'itemId'])
const getProductId = path(['product', 'productId'])
const getImages = path(['selectedItem', 'images'])

const ProductAddToListButton = () => {
  const {
    hints: { mobile },
  } = useRuntime()
  const productContext = useContext(ProductContext)

  const skuId = getSkuId(productContext)
  const productId = getProductId(productContext)

  const productProp = useMemo(() => ({
    skuId, productId, quantity: 1
  }), [skuId, productId])

  const images = getImages(productContext)
  const isMoreThanOneImage = images && images.length > 1

  const addonDetailsClasses = classNames('', {
    'ml-20-ns': isMoreThanOneImage
  })

  return (
    <div className={addonDetailsClasses}>
      <ExtensionPoint id="addon-details-btn" large={!mobile} product={productProp} />
    </div>
  )
}

export default ProductAddToListButton

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/package.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "product-details",
  "version": "1.22.0",
  "scripts": {
    "pretest": "yarn",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "dependencies": {
    "prop-types": "^15.6.2",
    "ramda": "^0.26.1",
    "react-content-loader": "^3.1.2",
    "react-intl": "^2.8.0"
  },
  "devDependencies": {
    "@babel/core": "^7.3.3",
    "@babel/preset-env": "^7.3.1",
    "babel-jest": "^24.1.0",
    "babel-preset-react-app": "^7.0.1",
    "classnames": "^2.2.6",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^24.1.0",
    "jest-dom": "^3.1.2",
    "jest-transform-graphql": "^2.1.0",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-testing-library": "^5.9.0",
    "regenerator-runtime": "^0.13.1"
  },
  "jest": {
    "verbose": true,
    "setupFilesAfterEnv": [
      "<rootDir>/testUtils/setupTests.js"
    ],
    "modulePaths": [
      "<rootDir>/testUtils"
    ],
    "moduleNameMapper": {
      "\\.(css|less|scss)$": "identity-obj-proxy"
    },
    "transform": {
      "\\.(gql|graphql)$": "jest-transform-graphql",
      "^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
    ]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/propTypes.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'

export const productShape = PropTypes.shape({
  /** Product's id */
  productId: PropTypes.string.isRequired,
  /** Product's name */
  productName: PropTypes.string.isRequired,
  /** Product's description */
  description: PropTypes.string,
  /** Product's technical specification */
  properties: PropTypes.arrayOf(
    PropTypes.shape({
      /** The property name */
      name: PropTypes.string,
      /** The specification description */
      values: PropTypes.arrayOf(PropTypes.string),
    })
  ),
  /** Product reference */
  productReference: PropTypes.string,
  /** Product's brand */
  brand: PropTypes.string,
  /** Product's SKUs */
  items: PropTypes.arrayOf(
    PropTypes.shape({
      /** SKU id */
      itemId: PropTypes.string.isRequired,
      /** SKU name */
      name: PropTypes.string.isRequired,
      /** SKU Images to be shown */
      images: PropTypes.arrayOf(
        PropTypes.shape({
          /** Image id */
          imageId: PropTypes.string.isRequired,
          /** Image label */
          imageLabel: PropTypes.string,
          /** Image tag as string */
          imageTag: PropTypes.string,
          /** Image URL */
          imageUrl: PropTypes.string.isRequired,
          /** Image text */
          imageText: PropTypes.string.isRequired,
        })
      ).isRequired,
      /** SKU sellers */
      sellers: PropTypes.arrayOf(
        PropTypes.shape({
          /** Seller id */
          sellerId: PropTypes.string.isRequired,
          /** Seller comertial offer */
          commertialOffer: PropTypes.shape({
            /** SKU installments */
            Installments: PropTypes.arrayOf(
              PropTypes.shape({
                /** Installment value */
                Value: PropTypes.number.isRequired,
                /** Interest rate (zero if interest-free) */
                InterestRate: PropTypes.number.isRequired,
                /** Calculated total value */
                TotalValuePlusInterestRate: PropTypes.number,
                /** Number of installments */
                NumberOfInstallments: PropTypes.number.isRequired,
                /** Installments offer name */
                Name: PropTypes.string,
              })
            ),
            /** Selling Price */
            Price: PropTypes.number.isRequired,
            /** List Price */
            ListPrice: PropTypes.number.isRequired,
            /** available item quantity */
            AvailableQuantity: PropTypes.number,
          }).isRequired,
        })
      ).isRequired,
    })
  ).isRequired,
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/productDetails.css from the product-details VTEX app.

[Assistant]
Here's the implementation:

```css
/**
  Product Details CSS Modules
*/

.container {}
.nameContainer {}
.detailsContainer {}
.priceContainer {}
.fixedButton {}
.informationsContainer{}
.highlightsContainer{}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/ProductQuantitySelector.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductQuantitySelector from './components/ProductQuantitySelector/index'
export default ProductQuantitySelector

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/store/blocks.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "product-details": {
    "blocks": [
      "breadcrumb",
      "product-name",
      "product-images",
      "product-price",
      "product-description",
      "buy-button",
      "sku-selector",
      "shipping-simulator",
      "availability-subscriber",
      "share",
      "product-specifications",
      "product-highlights"
    ]
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/store/interfaces.json from the product-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "product-details": {
    "required": [
      "product-images",
      "product-name",
      "product-price",
      "sku-selector",
      "buy-button",
      "product-description",
      "product-specifications"
    ],
    "allowed": [
      "breadcrumb",
      "shipping-simulator",
      "availability-subscriber",
      "share",
      "product-highlights",
      "product-quantity-selector",
      "addon-details-btn"
    ],
    "component": "ProductDetails"
  },
  "product-quantity-selector": {
    "component": "ProductQuantitySelector"
  },
  "product-add-to-list-button": {
    "component": "ProductAddToListButton",
    "allowed": ["addon-details-btn"]
  },
  "addon-details-btn": {
    "component": "*"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/utils/generateUrl.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const DEFAULT_WIDTH = 'auto'
export const DEFAULT_HEIGHT = 'auto'
export const MAX_WIDTH = 3000
export const MAX_HEIGHT = 4000

/**
 * Having the url below as base for the LEGACY file manager,
 * https://storecomponents.vteximg.com.br/arquivos/ids/155472/Frame-3.jpg?v=636793763985400000
 * the following regex will match https://storecomponents.vteximg.com.br/arquivos/ids/155472
 *
 * Also matches urls with defined sizes like:
 * https://storecomponents.vteximg.com.br/arquivos/ids/155473-160-auto
 * @type {RegExp}
 *
 * On the new vtex.file-manager isn't necessary replace the URL, just add the param on the querystring, like:
 * "?width=WIDTH&height=HEIGHT&aspect=true"
 *
 */
const baseUrlRegex = new RegExp(/.+ids\/(\d+)/)

export function cleanImageUrl(imageUrl) {
  const result = baseUrlRegex.exec(imageUrl)
  if (result.length > 0) return result[0]
}

function replaceLegacyFileManagerUrl(imageUrl, width, height) {
  const legacyUrlPattern = '/arquivos/ids/'
  const isLegacyUrl = imageUrl.includes(legacyUrlPattern)
  if (!isLegacyUrl) return imageUrl
  return `${cleanImageUrl(imageUrl)}-${width}-${height}`
}

export function changeImageUrlSize(
  imageUrl,
  width = DEFAULT_WIDTH,
  height = DEFAULT_HEIGHT,
) {
  if (!imageUrl) return
  typeof width === 'number' && (width = Math.min(width, MAX_WIDTH))
  typeof height === 'number' && (height = Math.min(height, MAX_HEIGHT))

  const normalizedImageUrl = replaceLegacyFileManagerUrl(imageUrl, width, height)
  const queryStringSeparator = normalizedImageUrl.includes('?') ? '&' : '?'

  return `${normalizedImageUrl}${queryStringSeparator}width=${width}&height=${height}&aspect=true`
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/utils/thumbnailPositionEnum.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { values, map } from 'ramda'

const thumbnailsPosition = {
  DISPLAY_LEFT: {
    name: 'admin/editor.product-details.thumbnailsPosition.left',
    value: 'left',
  },
  DISPLAY_RIGHT: {
    name: 'admin/editor.product-details.thumbnailsPosition.right',
    value: 'right',
  },
}

export function getThumbnailsPositionNames() {
  return map(opt => opt.name, values(thumbnailsPosition))
}

export function getThumbnailsPositionValues() {
  return map(opt => opt.value, values(thumbnailsPosition))
}

export default thumbnailsPosition

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/utils/schema.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import thumbnailsPosition, {
  getThumbnailsPositionNames,
  getThumbnailsPositionValues,
} from './thumbnailPositionEnum'

export const schema = {
  title: 'admin/editor.product-details.title',
  description: 'admin/editor.product-details.description',
  type: 'object',
  widget: {
    'ui:options': {
      inline: false,
    },
    'ui:widget': 'radio',
  },
  definitions: {
    highlightsDefault: {
      title: 'highlightsDefault',
      type: 'object',
      properties: {
        showHighlights: {
          title: 'Show highlights',
          type: 'boolean',
          enum: [true, false],
          default: true,
        },
      },
      required: ['showHighlights'],
      dependencies: {
        showHighlights: {
          oneOf: [
            {
              properties: {
                showHighlights: {
                  enum: [true],
                },
                highlightGroupDefault: {
                  title: 'Person',
                  type: 'object',
                  properties: {
                    highlight: {
                      title: 'admin/editor.product-details.highlights.default',
                      type: 'string',
                      enum: [
                        'admin/editor.product-details.highlights.allSpecifications',
                        'admin/editor.product-details.highlights.chooseDefault',
                        'admin/editor.product-details.highlights.chooseDefaultSpecification',
                      ],
                      default:
                        'admin/editor.product-details.highlights.allSpecifications',
                    },
                  },
                  required: ['highlight'],
                  dependencies: {
                    highlight: {
                      oneOf: [
                        {
                          properties: {
                            highlight: {
                              enum: [
                                'admin/editor.product-details.highlights.allSpecifications',
                              ],
                            },
                          },
                        },
                        {
                          properties: {
                            highlight: {
                              enum: [
                                'admin/editor.product-details.highlights.chooseDefault',
                              ],
                            },
                            typeHighlight: {
                              type: 'string',
                              title:
                                'admin/editor.product-details.highlights.title',
                              description:
                                'admin/editor.product-details.product-specifications.typeHelper',
                            },
                          },
                          required: [''],
                        },
                        {
                          properties: {
                            highlight: {
                              enum: [
                                'admin/editor.product-details.highlights.chooseDefaultSpecification',
                              ],
                            },
                            typeSpecifications: {
                              type: 'string',
                              title:
                                'admin/editor.product-details.highlights.typeSpecifications.title',
                              description:
                                'admin/editor.product-details.product-specifications.typeHelper',
                            },
                          },
                          required: [''],
                        },
                      ],
                    },
                  },
                },
              },
            },
          ],
        },
      },
    },

    specificationsDefault: {
      title: 'specificationsDefault',
      type: 'object',
      properties: {
        showSpecifications: {
          title: 'Show specifications',
          type: 'boolean',
          enum: [true, false],
          default: true,
        },
      },
      required: ['showSpecifications'],
      dependencies: {
        showSpecifications: {
          oneOf: [
            {
              properties: {
                showSpecifications: {
                  enum: [true],
                },
                specificationGroups: {
                  title: 'specificationGroups',
                  type: 'object',
                  properties: {
                    specification: {
                      title:
                        'admin/editor.product-details.product-specifications.default',
                      type: 'string',
                      enum: [
                        'admin/editor.product-details.product-specifications.allSpecifications',
                        'admin/editor.product-details.product-specifications.chooseDefaultSpecification',
                      ],
                      default:
                        'admin/editor.product-details.product-specifications.allSpecifications',
                    },
                  },
                  required: ['specification'],
                  dependencies: {
                    specification: {
                      oneOf: [
                        {
                          properties: {
                            specification: {
                              enum: [
                                'admin/editor.product-details.product-specifications.allSpecifications',
                              ],
                            },
                          },
                        },
                        {
                          properties: {
                            specification: {
                              enum: [
                                'admin/editor.product-details.product-specifications.chooseDefaultSpecification',
                              ],
                            },
                            typeSpecifications: {
                              type: 'string',
                              title:
                                'admin/editor.product-details.product-specifications.typeSpecifications.title',
                              description:
                                'admin/editor.product-details.product-specifications.typeHelper',
                            },
                          },
                          required: [''],
                        },
                      ],
                    },
                  },
                },
                viewMode: {
                  type: 'string',
                  title:
                    'admin/editor.product-specifications.displaySpecification.title',
                  enum: ['tab', 'table'],
                  enumNames: [
                    'admin/editor.product-specifications.displaySpecification.tabMode',
                    'admin/editor.product-specifications.displaySpecification.tableMode',
                  ],
                  default:
                    'admin/editor.product-specifications.displaySpecification.tabMode',
                  widget: {
                    'ui:options': {
                      inline: false,
                    },
                    'ui:widget': 'radio',
                  },
                },
              },
              required: [''],
            },
          ],
        },
      },
    },
  },

  properties: {
    highlightGroupDefault: {
      title: 'Conditional',
      $ref: '#/definitions/highlightsDefault',
    },
    specificationsDefault: {
      title: 'specification',
      $ref: '#/definitions/specificationsDefault',
    },
    thumbnailPosition: {
      title: 'admin/editor.product-details.thumbnailsPosition.title',
      type: 'string',
      enum: getThumbnailsPositionValues(),
      enumNames: getThumbnailsPositionNames(),
      default: thumbnailsPosition.DISPLAY_LEFT.value,
      isLayout: false,
    },
  },
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/__tests__/ProductQuantitySelector.test.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { renderWithIntl } from 'intl-utils'

import ProductQuantitySelector from '../ProductQuantitySelector'

describe('<ProductQuantitySelector /> component', () => {
  it('should render and not show available quantity view', () => {
    const component = renderWithIntl(<ProductQuantitySelector selectedQuantity={1} availableQuantity={50} warningQuantityThreshold={10}/>)
    expect(component).toBeDefined()
    expect(component.asFragment()).toMatchSnapshot()
  })
  it('should render and show available quantity view', () => {
    const component = renderWithIntl(<ProductQuantitySelector selectedQuantity={1} availableQuantity={5} warningQuantityThreshold={10}/>)
    expect(component).toBeDefined()
    expect(component.asFragment()).toMatchSnapshot()
  })
})
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/__tests__/ProductDetails.test.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { renderWithIntl } from 'intl-utils'
import { getProduct } from 'product-mock'

import ProductDetails from '../ProductDetails'

describe('<ProductDetails /> component', () => {
  const getComponentRender = customProps => {
    const props = {
      slug: 'productSlug',
      query: {
        skuId: 'id',
      },
      ...customProps,
    }

    return renderWithIntl(<ProductDetails {...props} />)
  }

  it('should match the loading snapshot', () => {
    const props = {
      productQuery: {
        loading: true,
      },
    }

    const render = getComponentRender(props)
    const fragment = render.asFragment()
    expect(fragment).toMatchSnapshot()
  })

  it('should match the snapshot with product', () => {
    const props = {
      categories: ['Shirt', 'Shoes'],
      productQuery: {
        loading: false,
        product: getProduct(),
      },
    }

    const render = getComponentRender(props)
    const fragment = render.asFragment()
    expect(fragment).toMatchSnapshot()
  })

  it('should render breadcrumbs', () => {
    const props = {
      categories: ['Shirt', 'Shoes'],
      productQuery: {
        loading: false,
        product: getProduct(),
      },
    }

    const { container } = getComponentRender(props)
    const productName = container.querySelector(
      '.extensionPoint-mock-breadcrumb'
    )
    expect(productName).toBeTruthy()
  })

  it('should render fixed button', () => {
    const props = {
      productQuery: {
        loading: false,
        product: getProduct(),
      },
    }

    const { container } = getComponentRender(props)
    const productName = container.querySelector('.fixedButton')
    expect(productName).toBeTruthy()
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/testUtils/setupTests.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
// react-testing-library renders your components to document.body,
// this will ensure they're removed after each test.
import 'react-testing-library/cleanup-after-each'

// this adds jest-dom's custom assertions
import 'jest-dom/extend-expect'

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/testUtils/intl-utils.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { render } from 'react-testing-library'
import { IntlProvider } from 'react-intl'
import defaultMessages from '../../messages/en.json'

export const renderWithIntl = (node, options) => {
  const rendered = render(
    <IntlProvider messages={defaultMessages} locale="en-US">
      {node}
    </IntlProvider>,
    options
  )

  return {
    ...rendered,
    rerender: newUi =>
      renderWithIntl(newUi, {
        container: rendered.container,
        baseElement: rendered.baseElement,
      }),
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/components/ProductQuantitySelector/quantitySelector.css from the product-details VTEX app.

[Assistant]
Here's the implementation:

```css
.quantitySelectorContainer {}
.availableQuantityContainer {}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/components/ProductQuantitySelector/index.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import { NumericStepper } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'

import styles from './quantitySelector.css'

const ProductQuantitySelector = ({ selectedQuantity, onChange, availableQuantity, warningQuantityThreshold }) => {
  const showAvailable = availableQuantity <= warningQuantityThreshold
  return (
    <div className={`${styles.quantitySelectorContainer} flex flex-column mb4`}>
      <div className="mb3 c-muted-2 t-body">
        <FormattedMessage id="store/product-details.quantity" />
      </div>
      <NumericStepper
        size="small"
        value={selectedQuantity}
        minValue={1}
        maxValue={availableQuantity ? availableQuantity : undefined}
        onChange={useCallback(e => onChange(e.value), [])}
      />
      {showAvailable &&
        <div className={`${styles.availableQuantityContainer} mv4 c-muted-2 t-small`}>
          <FormattedMessage id="store/product-details.quantity-available" values={{ availableQuantity }} />
        </div>}
    </div>
  )
}

ProductQuantitySelector.defaultProps = {
  warningQuantityThreshold: 0,
  onChange: () => {},
}

ProductQuantitySelector.propTypes = {
  selectedQuantity: PropTypes.number.isRequired,
  availableQuantity: PropTypes.number,
  onChange: PropTypes.func,
  warningQuantityThreshold: PropTypes.number.isRequired
}

ProductQuantitySelector.schema = {
  title: 'admin/editor.product-quantity-selector.title',
  description: 'admin/editor.product-quantity-selector.description',
  type: 'object',
  properties: {
    warningQuantityThreshold: {
      title: 'admin/editor.product-quantity-selector.warningQuantityThreshold.title',
      description: 'admin/editor.product-quantity-selector.warningQuantityThreshold.title',
      type: 'number',
      default: 0,
    },
  },
}

export default ProductQuantitySelector
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/components/ProductQuantitySelector/README.md from the product-details VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX Product Quantity Selector

## Description

The VTEX Product Quantity Selector allows the user to add to cart the specified amount of the displayed product

## Table of Contents

- [Usage](#usage)
  - [Blocks API](#blocks-api)
    - [Configuration](#configuration)
  - [Styles API](#styles-api)
    - [CSS Namespaces](#css-namespaces)

## Usage

This app uses our store builder with the blocks architecture. To know more about Store Builder [click here.](https://help.vtex.com/en/tutorial/understanding-storebuilder-and-stylesbuilder#structuring-and-configuring-our-store-with-object-object)

To use this app or override the default CSS you need import it in your dependencies on `manifest.json` file.

```json
  "dependencies": {
    "vtex.product-details": "1.x"
  }
```

This block may be used inside the `product-details` block.

To use it, you must declare its use in your `product-details` block array. An example of usage in a `blocks.json`:

```json
"product-details#default": {
    "blocks": [
      "breadcrumb",
      "product-name",
      "product-images",
      "product-price",
      "product-description",
      "product-specifications",
      "buy-button",
      "sku-selector",
      "shipping-simulator",
      "availability-subscriber",
      "share",
      "product-quantity-selector"
    ],
    "props": {
      "displayVertically": true,
      "share": {
        "social": {
          "Facebook": true,
          "WhatsApp": true,
          "Twitter": false
        }
      },
      "price": {
        "labelSellingPrice": null,
        "showListPrice": true,
        "showLabels": true,
        "showInstallments": true,
        "showSavings": true
      },
      "name": {
        "showBrandName": false,
        "showSku": false,
        "showProductReference": false
      }
    }
  },
"product-quantity-selector": {
    "props": {
      "warningQuantityThreshold": 9999999
    }
  },
```

### Blocks API

This is the defined interface for this block:

```json
{
  "product-quantity-selector": {
    "component": "ProductQuantitySelector"
  }
}
```

For now this block does not have any required or optional blocks.

#### Configuration

Through the Storefront, you can change the Product Quantity Selector's behavior and interface. However, you also can make in your theme app, as Store theme does.

| Prop name           | Type      | Description                                                                                |
| ------------------- | --------- | ------------------------------------------------------------------------------------------- |
| `warningQuantityThreshold`     | `Number` | Only show the quantity of remaining items in stock if item available quantity is less than or equal to the value passed in this property. Default: 0 (does not appear).    |

### Styles API

This app provides some CSS classes as an API for style customization.

To use this CSS API, you must add the `styles` builder and create an app styling CSS file.

1. Add the `styles` builder to your `manifest.json`:

```json
  "builders": {
    "styles": "1.x"
  }
```

2. Create a file called `vtex.product-details.css` inside the `styles/css` folder. Add your custom styles:

```css
.quantitySelectorContainer {
  margin-top: 10px;
}
```

#### CSS Namespaces

Below, we describe the namespaces that are defined in the Product Quantity Selector.

| Token name                 | Component                                                                                | Description                                                   |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `quantitySelectorContainer`                | [index](https://github.com/vtex-apps/product-details/blob/master/react/components/ProductQuantitySelector/index.js) | The main container of `Product Quantity Selector`                        |
| `availableQuantityContainer`                | [index](https://github.com/vtex-apps/product-details/blob/master/react/components/ProductQuantitySelector/index.js) | The container that wraps the available quantity view.                        |
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/components/FixedButton/index.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment } from 'react'
import BottomExtraSpace from './BottomExtraSpace'
import { NoSSR } from 'vtex.render-runtime'

import productDetails from '../../productDetails.css'

export default props => (
  <Fragment>
    <div
      className={`${
        productDetails.fixedButton
      } fixed bottom-0 left-0 w-100 z-999`}
    >
      {props.children}
    </div>
    <NoSSR>
      <BottomExtraSpace>{props.children}</BottomExtraSpace>
    </NoSSR>
  </Fragment>
)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-details/react/components/FixedButton/BottomExtraSpace.js from the product-details VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'

class BottomExtraSpace extends Component {
  constructor(props) {
    super(props)

    this.ref = React.createRef()
    this.state = { mounted: false }
    this.el = document.createElement('div')
  }

  componentDidMount() {
    this.fixedRoot = this.ref.current

    while (this.fixedRoot &&
    window.getComputedStyle(this.fixedRoot)
      .getPropertyValue('overflow') !== 'auto') { this.fixedRoot = this.fixedRoot.parentElement }

    if (!this.fixedRoot)this.fixedRoot = document.body

    this.fixedRoot && this.fixedRoot.appendChild(this.el)
    this.setState({ mounted: true })
  }

  componentWillUnmount() {
    this.fixedRoot && this.fixedRoot.removeChild(this.el)
  }

  render() {
    const { mounted } = this.state

    if (!mounted) return <div ref={this.ref} />

    const children = this.props.children

    return ReactDOM.createPortal(
      <div className="o-0" tabIndex="-1">
        {children}
      </div>,
      this.el,
    )
  }
}

BottomExtraSpace.propTypes = {
  children: PropTypes.node,
}

export default BottomExtraSpace

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/types/index.d.ts from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare namespace NodeJS {
  interface ProcessEnv {
    [key: string]: string | undefined
    NODE_ENV: 'development' | 'production',
    USE_LOCAL_SERVER?: 'true' | any
  }
}

declare var __DEV__: boolean;

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/test/thing.test.tsx from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react';
import * as ReactDOM from 'react-dom';
import { Default as Thing } from '../stories/Thing.stories';

describe('Thing', () => {
  it('renders without crashing', () => {
    const div = document.createElement('div');
    ReactDOM.render(<Thing />, div);
    ReactDOM.unmountComponentAtNode(div);
  });
});

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/.storybook/preview.js from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
// https://storybook.js.org/docs/react/writing-stories/parameters#global-parameters
export const parameters = {
  // https://storybook.js.org/docs/react/essentials/actions#automatically-matching-args
  actions: { argTypesRegex: '^on.*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
    },
  },
};

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/.storybook/main.js from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
module.exports = {
  stories: ['../stories/**/*.stories.@(ts|tsx|js|jsx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  // https://storybook.js.org/docs/react/configure/typescript#mainjs-configuration
  typescript: {
    check: true, // type-check stories during Storybook build
  }
};

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/stories/Thing.stories.tsx from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { Thing, Props } from '../src/components/Things';

const meta: Meta = {
  title: 'Welcome',
  component: Thing,
  argTypes: {
    children: {
      control: {
        type: 'text',
      },
    },
  },
  parameters: {
    controls: { expanded: true },
  },
};

export default meta;

const Template: Story<Props> = args => <Thing {...args} />;

// By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
// https://storybook.js.org/docs/react/workflows/unit-testing
export const Default = Template.bind({});

Default.args = {};

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/stories/Hello.stories.tsx from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Hello } from '../src';
import { HelloProps } from '../src/components/Hello';

export default {
  component: Hello,
  title: 'Components/Hello',
} as Meta;

const Template: Story<HelloProps> = (args) => <Hello {...args} />;

export const Aracaju = Template.bind({});
Aracaju.args = { name: 'Aracaju' };

export const Brasilia = Template.bind({});
Brasilia.args = { name: 'Brasilia' };

export const Rio = Template.bind({});
Rio.args = { name: 'Rio de Janeiro' };

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of starter.store-react-components/pages/index.tsx from the starter.store-react-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import 'react-app-polyfill/ie11';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Hello, Thing } from '../.';

const App = () => {
  return (
    <div>
      <Thing />
      <Hello name={'VTEX'} />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

```