feat: Cria bloco de desconto Pix
This commit is contained in:
parent
d631739c78
commit
38ce16fbf5
BIN
assets/fonts/OpenSans-SemiBold.ttf
Normal file
BIN
assets/fonts/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
3
react/Pix.tsx
Normal file
3
react/Pix.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Pix from "./components/Pix/Pix";
|
||||||
|
|
||||||
|
export default Pix;
|
35
react/components/Pix/Pix.tsx
Normal file
35
react/components/Pix/Pix.tsx
Normal file
@ -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 (
|
||||||
|
<div className={styles["pix-container"]}>
|
||||||
|
<div className={styles["pix-content"]}>
|
||||||
|
<div className={styles["pix-image"]}>
|
||||||
|
<img
|
||||||
|
src="https://agenciamagma.vtexassets.com/arquivos/pix-eleonoraotz.png"
|
||||||
|
alt="10% de desconto no Pix"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles["pix-descount"]}>
|
||||||
|
<p className={styles["pix-value"]}>
|
||||||
|
R$ {totalValue.toFixed(2).replace(".", ",")}
|
||||||
|
</p>
|
||||||
|
<p className={styles["pix-text"]}>10 % de desconto</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Pix;
|
28
react/components/Pix/style.module.css
Normal file
28
react/components/Pix/style.module.css
Normal file
@ -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;
|
||||||
|
}
|
4
react/typings/css.d.ts
vendored
Normal file
4
react/typings/css.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
declare module "*.css" {
|
||||||
|
const css: any;
|
||||||
|
export default css;
|
||||||
|
}
|
7
react/typings/global.d.ts
vendored
Normal file
7
react/typings/global.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export interface TimeSplit {
|
||||||
|
hours: string
|
||||||
|
minutes: string
|
||||||
|
seconds: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GenericObject = Record<string, any>
|
6
react/typings/graphql.d.ts
vendored
Normal file
6
react/typings/graphql.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
declare module "*.graphql" {
|
||||||
|
import { DocumentNode } from "graphql";
|
||||||
|
|
||||||
|
const value: DocumentNode;
|
||||||
|
export default value;
|
||||||
|
}
|
15
react/typings/storefront.d.ts
vendored
Normal file
15
react/typings/storefront.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FunctionComponent } from "react";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface StorefrontFunctionComponent<P = GenericObject>
|
||||||
|
extends FunctionComponent<P> {
|
||||||
|
getSchema?(props: P): GenericObject
|
||||||
|
schema?: GenericObject
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StorefrontComponent<P = GenericObject, S = GenericObject>
|
||||||
|
extends Component<P, S> {
|
||||||
|
getSchema?(props: P): GenericObject
|
||||||
|
schema: GenericObject
|
||||||
|
}
|
||||||
|
}
|
1
react/typings/vtex.css-handles.ts
Normal file
1
react/typings/vtex.css-handles.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
declare module "vtex.css-handles"
|
103
react/typings/vtex.order-manager.d.ts
vendored
Normal file
103
react/typings/vtex.order-manager.d.ts
vendored
Normal file
@ -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<DefaultOrderForm, "items">;
|
||||||
|
type DefaultOrderFormUpdated = DefaultOrderFormOmited & {
|
||||||
|
items: OrderFormItem[] | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OrderFormContext = createContext<Context<OrderForm>>({
|
||||||
|
orderForm: DefaultOrderFormUpdated,
|
||||||
|
setOrderForm: noop,
|
||||||
|
error: undefined,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
function useOrderForm<O extends OrderForm = DefaultOrderFormUpdated>() {
|
||||||
|
const context = useContext(OrderFormContext);
|
||||||
|
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
"useOrderForm must be used within a OrderFormProvider"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context as Context<O>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OrderFormItem = {
|
||||||
|
additionalInfo: {
|
||||||
|
brandName: string;
|
||||||
|
__typename: string;
|
||||||
|
};
|
||||||
|
attachments: Array<any>;
|
||||||
|
attachmentOfferings: Array<any>;
|
||||||
|
bundleItems: Array<any>;
|
||||||
|
parentAssemblyBinding: any;
|
||||||
|
parentItemIndex: any;
|
||||||
|
sellingPriceWithAssemblies: any;
|
||||||
|
options: any;
|
||||||
|
availability: string;
|
||||||
|
detailUrl: string;
|
||||||
|
id: string;
|
||||||
|
imageUrls: Record<string, string>;
|
||||||
|
listPrice: number;
|
||||||
|
manualPrice: any;
|
||||||
|
measurementUnit: string;
|
||||||
|
modalType: any;
|
||||||
|
name: string;
|
||||||
|
offerings: Array<any>;
|
||||||
|
price: number;
|
||||||
|
priceTags: Array<any>;
|
||||||
|
productCategories: Record<string, string>;
|
||||||
|
productCategoryIds: string;
|
||||||
|
productRefId: string;
|
||||||
|
productId: string;
|
||||||
|
quantity: number;
|
||||||
|
seller: string;
|
||||||
|
sellingPrice: number;
|
||||||
|
skuName: string;
|
||||||
|
skuSpecifications: Array<any>;
|
||||||
|
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<Record<string, never>>;
|
||||||
|
useOrderForm: typeof useOrderForm;
|
||||||
|
};
|
||||||
|
export default _default;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "vtex.order-manager/constants" {
|
||||||
|
export * from "vtex.order-manager/react/constants";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
38
react/typings/vtex.render-runtime.d.ts
vendored
Normal file
38
react/typings/vtex.render-runtime.d.ts
vendored
Normal file
@ -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<ExtensionPointProps>;
|
||||||
|
|
||||||
|
interface ChildBlockProps {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ChildBlock: ComponentType<ChildBlockProps>;
|
||||||
|
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: <TOriginalProps extends GenericObject>(
|
||||||
|
Component: ComponentType<TOriginalProps & RenderContextProps>
|
||||||
|
) => ComponentType<TOriginalProps>;
|
||||||
|
}
|
9
react/typings/vtex.styleguide.d.ts
vendored
Normal file
9
react/typings/vtex.styleguide.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
declare module "vtex.styleguide" {
|
||||||
|
import { ComponentType } from "react";
|
||||||
|
|
||||||
|
export const Input: ComponentType<InputProps>;
|
||||||
|
|
||||||
|
interface InputProps {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
}
|
@ -110,6 +110,7 @@
|
|||||||
"product-identifier.product",
|
"product-identifier.product",
|
||||||
"flex-layout.row#selling-price",
|
"flex-layout.row#selling-price",
|
||||||
"product-installments",
|
"product-installments",
|
||||||
|
"Pix",
|
||||||
"sku-selector",
|
"sku-selector",
|
||||||
"html#buy-button",
|
"html#buy-button",
|
||||||
"product-gifts",
|
"product-gifts",
|
||||||
|
@ -5,5 +5,8 @@
|
|||||||
"html": {
|
"html": {
|
||||||
"component": "html",
|
"component": "html",
|
||||||
"composition": "children"
|
"composition": "children"
|
||||||
|
},
|
||||||
|
"Pix": {
|
||||||
|
"component": "Pix"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,12 @@
|
|||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
src: url("assets/fonts/OpenSans-SemiBold.ttf");
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Open Sans";
|
font-family: "Open Sans";
|
||||||
src: url("assets/fonts/OpenSans-Bold.ttf");
|
src: url("assets/fonts/OpenSans-Bold.ttf");
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
/* Media Query M3 */
|
/* Media Query M3 */
|
||||||
/* Grid breakpoints */
|
/* Grid breakpoints */
|
||||||
|
.flexRowContent {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.flexRowContent--menu-link,
|
.flexRowContent--menu-link,
|
||||||
.flexRowContent--main-header {
|
.flexRowContent--main-header {
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
|
@ -325,6 +325,32 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 16px;
|
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 {
|
.newsletter {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
color: #bfbfbf;
|
color: #bfbfbf;
|
||||||
text-transform: capitalize;
|
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 {
|
: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) {
|
:global(.vtex-tab-layout-0-x-container) .listContainer--tabList .listItemActive :global(.vtex-button) {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -42,10 +42,11 @@
|
|||||||
color: #000000;
|
color: #000000;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-bottom: 2px solid #000000;
|
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 {
|
:global(.vtex-tab-layout-0-x-container) .listContainer--tabList .listItemActive :global(.vtex-button__label):hover {
|
||||||
border-bottom: 2px solid #000000;
|
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 {
|
:global(.vtex-tab-layout-0-x-container) :global(.vtex-tab-layout-0-x-contentContainer) .contentItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
.flexRowContent {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.flexRowContent--menu-link,
|
.flexRowContent--menu-link,
|
||||||
.flexRowContent--main-header {
|
.flexRowContent--main-header {
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
|
@ -369,6 +369,40 @@
|
|||||||
line-height: 16px;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
padding: 0 70px;
|
padding: 0 70px;
|
||||||
|
|
||||||
.listItem {
|
.listItem {
|
||||||
|
|
||||||
:global(.vtex-button) {
|
:global(.vtex-button) {
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
height: 43px;
|
height: 43px;
|
||||||
border: none;
|
border: none;
|
||||||
@ -26,16 +24,15 @@
|
|||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
color: $gray-100;
|
color: $gray-100;
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
padding: 0;
|
padding: 0.25em 10px 0.32em;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
padding: 0;
|
padding: 0.25em 10px 0.32em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItemActive {
|
.listItemActive {
|
||||||
|
|
||||||
:global(.vtex-button) {
|
:global(.vtex-button) {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: none;
|
border: none;
|
||||||
@ -44,10 +41,11 @@
|
|||||||
color: $black;
|
color: $black;
|
||||||
background-color: $white;
|
background-color: $white;
|
||||||
border-bottom: 2px solid $black;
|
border-bottom: 2px solid $black;
|
||||||
padding: 0;
|
padding: 0.25em 10px 0.32em;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-bottom: 2px solid $black;
|
border-bottom: 2px solid $black;
|
||||||
|
padding: 0.25em 10px 0.32em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user