diff --git a/assets/fonts/OpenSans-SemiBold.ttf b/assets/fonts/OpenSans-SemiBold.ttf new file mode 100644 index 0000000..66acb20 Binary files /dev/null and b/assets/fonts/OpenSans-SemiBold.ttf differ diff --git a/react/Pix.tsx b/react/Pix.tsx new file mode 100644 index 0000000..52ecbb2 --- /dev/null +++ b/react/Pix.tsx @@ -0,0 +1,3 @@ +import Pix from "./components/Pix/Pix"; + +export default Pix; diff --git a/react/components/Pix/Pix.tsx b/react/components/Pix/Pix.tsx new file mode 100644 index 0000000..d6e114b --- /dev/null +++ b/react/components/Pix/Pix.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { useProduct } from "vtex.product-context"; +import styles from "./style.module.css"; + +const Pix = () => { + const productValue = useProduct(); + + const priceProduct = + productValue?.product?.priceRange?.sellingPrice?.lowPrice; + + const descountValue = (Number(priceProduct) * 10) / 100; + + const totalValue = Number(priceProduct) - Number(descountValue); + + return ( +
+
+
+ 10% de desconto no Pix +
+
+

+ R$ {totalValue.toFixed(2).replace(".", ",")} +

+

10 % de desconto

+
+
+
+ ); +}; + +export default Pix; diff --git a/react/components/Pix/style.module.css b/react/components/Pix/style.module.css new file mode 100644 index 0000000..ba3c6ad --- /dev/null +++ b/react/components/Pix/style.module.css @@ -0,0 +1,28 @@ +/* .pix-container { + +} */ + +.pix-content { + display: flex; + align-items: center; + gap: 26px; + margin: 8px 0 16px; +} + +.pix-image { + height: fit-content; +} + +.pix-value { + font-weight: 700; + font-size: 18px; + color: rgba(0, 0, 0, 0.58); + margin: 0; +} + +.pix-text { + font-weight: 300; + font-size: 13px; + color: #929292; + margin: 0; +} diff --git a/react/typings/css.d.ts b/react/typings/css.d.ts new file mode 100644 index 0000000..c5862b6 --- /dev/null +++ b/react/typings/css.d.ts @@ -0,0 +1,4 @@ +declare module "*.css" { + const css: any; + export default css; +} diff --git a/react/typings/global.d.ts b/react/typings/global.d.ts new file mode 100644 index 0000000..17b4165 --- /dev/null +++ b/react/typings/global.d.ts @@ -0,0 +1,7 @@ +export interface TimeSplit { + hours: string + minutes: string + seconds: string +} + +type GenericObject = Record diff --git a/react/typings/graphql.d.ts b/react/typings/graphql.d.ts new file mode 100644 index 0000000..84017d3 --- /dev/null +++ b/react/typings/graphql.d.ts @@ -0,0 +1,6 @@ +declare module "*.graphql" { + import { DocumentNode } from "graphql"; + + const value: DocumentNode; + export default value; +} diff --git a/react/typings/storefront.d.ts b/react/typings/storefront.d.ts new file mode 100644 index 0000000..4689dc6 --- /dev/null +++ b/react/typings/storefront.d.ts @@ -0,0 +1,15 @@ +import { FunctionComponent } from "react"; + +declare global { + interface StorefrontFunctionComponent

+ extends FunctionComponent

{ + getSchema?(props: P): GenericObject + schema?: GenericObject + } + + interface StorefrontComponent

+ extends Component { + getSchema?(props: P): GenericObject + schema: GenericObject + } +} diff --git a/react/typings/vtex.css-handles.ts b/react/typings/vtex.css-handles.ts new file mode 100644 index 0000000..4f191a0 --- /dev/null +++ b/react/typings/vtex.css-handles.ts @@ -0,0 +1 @@ +declare module "vtex.css-handles" diff --git a/react/typings/vtex.order-manager.d.ts b/react/typings/vtex.order-manager.d.ts new file mode 100644 index 0000000..b563ce5 --- /dev/null +++ b/react/typings/vtex.order-manager.d.ts @@ -0,0 +1,103 @@ +/* eslint-disable no-inner-declarations */ +declare module "vtex.order-manager/OrderQueue" { + export * from "vtex.order-manager/react/OrderQueue"; + export { default } from "vtex.order-manager/react/OrderQueue"; + + export const QueueStatus = { + PENDING: "Pending", + FULFILLED: "Fulfilled", + } as const; +} + +declare module "vtex.order-manager/OrderForm" { + import { createContext, useContext } from "react"; + import type { DEFAULT_ORDER_FORM } from "@vtex/order-manager/src/constants"; + import type { Context, OrderForm } from "@vtex/order-manager/src/typings"; + + type DefaultOrderForm = typeof DEFAULT_ORDER_FORM; + type DefaultOrderFormOmited = Omit; + type DefaultOrderFormUpdated = DefaultOrderFormOmited & { + items: OrderFormItem[] | null; + }; + + export const OrderFormContext = createContext>({ + orderForm: DefaultOrderFormUpdated, + setOrderForm: noop, + error: undefined, + loading: false, + }); + + function useOrderForm() { + const context = useContext(OrderFormContext); + + if (context === undefined) { + throw new Error( + "useOrderForm must be used within a OrderFormProvider" + ); + } + return context as Context; + } + + export type OrderFormItem = { + additionalInfo: { + brandName: string; + __typename: string; + }; + attachments: Array; + attachmentOfferings: Array; + bundleItems: Array; + parentAssemblyBinding: any; + parentItemIndex: any; + sellingPriceWithAssemblies: any; + options: any; + availability: string; + detailUrl: string; + id: string; + imageUrls: Record; + listPrice: number; + manualPrice: any; + measurementUnit: string; + modalType: any; + name: string; + offerings: Array; + price: number; + priceTags: Array; + productCategories: Record; + productCategoryIds: string; + productRefId: string; + productId: string; + quantity: number; + seller: string; + sellingPrice: number; + skuName: string; + skuSpecifications: Array; + unitMultiplier: number; + uniqueId: string; + refId: string; + isGift: boolean; + priceDefinition: { + calculatedSellingPrice: number; + total: number; + sellingPrices: Array<{ + quantity: number; + value: number; + __typename: string; + }>; + __typename: string; + }; + __typename: string; + }; + + export { OrderFormProvider, useOrderForm }; + declare const _default: { + OrderFormProvider: import("react").FC>; + useOrderForm: typeof useOrderForm; + }; + export default _default; +} + +declare module "vtex.order-manager/constants" { + export * from "vtex.order-manager/react/constants"; +} + + diff --git a/react/typings/vtex.render-runtime.d.ts b/react/typings/vtex.render-runtime.d.ts new file mode 100644 index 0000000..bfb1e97 --- /dev/null +++ b/react/typings/vtex.render-runtime.d.ts @@ -0,0 +1,38 @@ +/* Typings for `render-runtime` */ +declare module "vtex.render-runtime" { + import { ComponentType, ReactElement, ReactType } from "react"; + + export interface NavigationOptions { + page: string + params?: any + } + + export interface RenderContextProps { + runtime: { + navigate: (options: NavigationOptions) => void + } + } + + interface ExtensionPointProps { + id: string + [key: string]: any + } + + export const ExtensionPoint: ComponentType; + + interface ChildBlockProps { + id: string + } + + export const ChildBlock: ComponentType; + export const useChildBlock = () => GenericObject; + + export const Helmet: ReactElement; + export const Link: ReactType; + export const NoSSR: ReactElement; + export const RenderContextConsumer: ReactElement; + export const canUseDOM: boolean; + export const withRuntimeContext: ( + Component: ComponentType + ) => ComponentType; +} diff --git a/react/typings/vtex.styleguide.d.ts b/react/typings/vtex.styleguide.d.ts new file mode 100644 index 0000000..6f1f00a --- /dev/null +++ b/react/typings/vtex.styleguide.d.ts @@ -0,0 +1,9 @@ +declare module "vtex.styleguide" { + import { ComponentType } from "react"; + + export const Input: ComponentType; + + interface InputProps { + [key: string]: any + } +} diff --git a/store/blocks/pdp/product.jsonc b/store/blocks/pdp/product.jsonc index ed98ae1..9210559 100644 --- a/store/blocks/pdp/product.jsonc +++ b/store/blocks/pdp/product.jsonc @@ -110,6 +110,7 @@ "product-identifier.product", "flex-layout.row#selling-price", "product-installments", + "Pix", "sku-selector", "html#buy-button", "product-gifts", diff --git a/store/interfaces.json b/store/interfaces.json index c4b2ac4..2d07e38 100644 --- a/store/interfaces.json +++ b/store/interfaces.json @@ -5,5 +5,8 @@ "html": { "component": "html", "composition": "children" + }, + "Pix": { + "component": "Pix" } } diff --git a/styles/configs/font-faces.css b/styles/configs/font-faces.css index 6d4199a..a8c0c05 100644 --- a/styles/configs/font-faces.css +++ b/styles/configs/font-faces.css @@ -10,6 +10,12 @@ font-weight: 300; } +@font-face { + font-family: "Open Sans"; + src: url("assets/fonts/OpenSans-SemiBold.ttf"); + font-weight: 600; +} + @font-face { font-family: "Open Sans"; src: url("assets/fonts/OpenSans-Bold.ttf"); diff --git a/styles/css/vtex.flex-layout.css b/styles/css/vtex.flex-layout.css index 75f1a05..e523ef0 100644 --- a/styles/css/vtex.flex-layout.css +++ b/styles/css/vtex.flex-layout.css @@ -7,6 +7,10 @@ */ /* Media Query M3 */ /* Grid breakpoints */ +.flexRowContent { + margin: 0; +} + .flexRowContent--menu-link, .flexRowContent--main-header { padding: 0 0.5rem; diff --git a/styles/css/vtex.store-components.css b/styles/css/vtex.store-components.css index 2e9c75b..5151187 100644 --- a/styles/css/vtex.store-components.css +++ b/styles/css/vtex.store-components.css @@ -325,6 +325,32 @@ font-size: 12px; line-height: 16px; } +.subscriberContainer .form :global(.vtex-store-components-3-x-content) { + display: grid; + grid-template-areas: "name email" "submit submit"; +} +.subscriberContainer .form :global(.vtex-store-components-3-x-content) .inputName { + grid-area: name; +} +.subscriberContainer .form :global(.vtex-store-components-3-x-content) .inputEmail { + grid-area: email; +} +.subscriberContainer .form :global(.vtex-store-components-3-x-content) :global(.vtex-button) { + grid-area: submit; + background-color: #000000; + border: none; + border-radius: 0; +} +.subscriberContainer .form :global(.vtex-store-components-3-x-content) :global(.vtex-button__label) { + font-size: 0; +} +.subscriberContainer .form :global(.vtex-store-components-3-x-content) :global(.vtex-button__label)::after { + content: "AVISE-ME"; + font-weight: 600; + font-size: 18px; + line-height: 25px; + color: #fff; +} .newsletter { display: block; diff --git a/styles/css/vtex.tab-layout.css b/styles/css/vtex.tab-layout.css index a777015..814cab3 100644 --- a/styles/css/vtex.tab-layout.css +++ b/styles/css/vtex.tab-layout.css @@ -29,10 +29,10 @@ line-height: 18px; color: #bfbfbf; text-transform: capitalize; - padding: 0; + padding: 0.25em 10px 0.32em; } :global(.vtex-tab-layout-0-x-container) .listContainer--tabList .listItem :global(.vtex-button__label):hover { - padding: 0; + padding: 0.25em 10px 0.32em; } :global(.vtex-tab-layout-0-x-container) .listContainer--tabList .listItemActive :global(.vtex-button) { background-color: white; @@ -42,10 +42,11 @@ color: #000000; background-color: #fff; border-bottom: 2px solid #000000; - padding: 0; + padding: 0.25em 10px 0.32em; } :global(.vtex-tab-layout-0-x-container) .listContainer--tabList .listItemActive :global(.vtex-button__label):hover { border-bottom: 2px solid #000000; + padding: 0.25em 10px 0.32em; } :global(.vtex-tab-layout-0-x-container) :global(.vtex-tab-layout-0-x-contentContainer) .contentItem { display: flex; diff --git a/styles/sass/pages/product/vtex.flex-layout.scss b/styles/sass/pages/product/vtex.flex-layout.scss index b93fe1e..af79240 100644 --- a/styles/sass/pages/product/vtex.flex-layout.scss +++ b/styles/sass/pages/product/vtex.flex-layout.scss @@ -1,3 +1,7 @@ +.flexRowContent { + margin: 0; +} + .flexRowContent--menu-link, .flexRowContent--main-header { padding: 0 0.5rem; diff --git a/styles/sass/pages/product/vtex.store-components.scss b/styles/sass/pages/product/vtex.store-components.scss index e1a6ecd..7e5b351 100644 --- a/styles/sass/pages/product/vtex.store-components.scss +++ b/styles/sass/pages/product/vtex.store-components.scss @@ -369,6 +369,40 @@ line-height: 16px; } } + + :global(.vtex-store-components-3-x-content) { + display: grid; + grid-template-areas: + "name email" + "submit submit"; + + .inputName { + grid-area: name; + } + + .inputEmail { + grid-area: email; + } + + :global(.vtex-button) { + grid-area: submit; + background-color: $black; + border: none; + border-radius: 0; + } + + :global(.vtex-button__label) { + font-size: 0; + + &::after { + content: "AVISE-ME"; + font-weight: 600; + font-size: 18px; + line-height: 25px; + color: $white; + } + } + } } } diff --git a/styles/sass/pages/product/vtex.tab-layout.scss b/styles/sass/pages/product/vtex.tab-layout.scss index eb01625..358e9dd 100644 --- a/styles/sass/pages/product/vtex.tab-layout.scss +++ b/styles/sass/pages/product/vtex.tab-layout.scss @@ -8,9 +8,7 @@ padding: 0 70px; .listItem { - :global(.vtex-button) { - &:hover { height: 43px; border: none; @@ -26,16 +24,15 @@ line-height: 18px; color: $gray-100; text-transform: capitalize; - padding: 0; + padding: 0.25em 10px 0.32em; &:hover { - padding: 0; + padding: 0.25em 10px 0.32em; } } } .listItemActive { - :global(.vtex-button) { background-color: white; border: none; @@ -44,10 +41,11 @@ color: $black; background-color: $white; border-bottom: 2px solid $black; - padding: 0; + padding: 0.25em 10px 0.32em; &:hover { border-bottom: 2px solid $black; + padding: 0.25em 10px 0.32em; } } }