diff --git a/src/components/PurchaseSummary/PurchaseSummary.stories.tsx b/src/components/PurchaseSummary/PurchaseSummary.stories.tsx new file mode 100644 index 0000000..17f9859 --- /dev/null +++ b/src/components/PurchaseSummary/PurchaseSummary.stories.tsx @@ -0,0 +1,136 @@ +import { Meta, StoryObj } from '@storybook/react' +import { PurchaseSummary } from './index' +import { PurchaseSummaryProps } from './type' +import { PurchaseSummaryAccordion } from './PurchaseSummaryAccordion' + +export default { + title: 'Components/PurchaseSummary', + component: PurchaseSummary, + tags: ['autodocs'], + argTypes: { + title: { + control: 'text', + description: 'Title of the component', + }, + totalitems: { + control: 'text', + description: 'Total number of items', + }, + productsPrice: { + control: 'number', + description: 'Price of the products', + }, + deliveryCost: { + control: 'number', + description: 'Price of the delivery Cost', + }, + totalDiscount: { + control: 'number', + description: 'Total value of all discounts applied', + }, + totalPrice: { + control: 'Total value of the purchase summary', + description: 'Total value of the purchase summary', + }, + installmentPayment: { + control: 'text', + description: 'Number of installments and monthly amount', + }, + discounts: { + control: 'object', + description: 'Array of discounts applied to the purchase', + label: { + options: ['Cupom de desconto', 'Cashback'], + mapping: { + 'Cupom de desconto': { + title: 'Cupom de desconto', + price: '31,00', + }, + Cashback: { + title: 'Cashback', + price: '11,50', + }, + }, + }, + }, + deliveryValue: { + control: 'text', + description: 'Label for the delivery value', + }, + productsLabel: { + control: 'text', + description: 'Label for the products value', + }, + totalItems: { + control: 'number', + description: 'Total number of items', + }, + labelItensText: { + control: 'text', + description: 'Label for the items', + }, + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} as Meta + +type Story = StoryObj + +export const WithDiscounts: Story = { + name: 'WithDiscounts', + args: { + title: '', + productsLabel: 'Valor dos produtos', + deliveryValue: 'Valor da entrega', + discountLabel: 'Total de descontos', + totalItems: 1, + labelItensText: 'item', + productsPrice: 178.6, + deliveryCost: 15.0, + totalDiscount: 29.35, + totalPrice: 90, + installmentPayment: '2x de 59,85 sem juros', + discounts: [ + { + id: 1, + title: 'Cupom de desconto', + price: '31,00', + }, + { + id: 2, + title: 'Cashback', + price: '11,50', + }, + ], + }, + render: (args) => ( + + + + ), +} + +export const WithoutDiscounts: Story = { + args: { + productsLabel: 'Valor dos produtos', + deliveryValue: 'Valor da entrega', + totalItems: 2, + labelItensText: 'itens', + productsPrice: 178.6, + deliveryCost: 15.0, + totalDiscount: 29.35, + totalPrice: 90, + installmentPayment: '2x de 59,85 sem juros', + discounts: [], + }, + render: (args) => , +} diff --git a/src/components/PurchaseSummary/PurchaseSummaryAccordion/index.tsx b/src/components/PurchaseSummary/PurchaseSummaryAccordion/index.tsx new file mode 100644 index 0000000..3b40d0b --- /dev/null +++ b/src/components/PurchaseSummary/PurchaseSummaryAccordion/index.tsx @@ -0,0 +1,64 @@ +import { useState } from 'react' +import { ChevronDown, ChevronUp } from 'semillon' +import { + PurchaseSummaryAccordionAccordionContainer, + PurchaseSummaryAccordionAccordionHeader, + PurchaseSummaryAccordionAccordionContent, + PurchaseSummaryAccordionAccordionItem, + PurchaseSummaryAccordionPriceHeader, + PurchaseSummaryAccordionchevronIcon, + PurchaseSummaryAccordionItemValue, + PurchaseSummaryAccordionAccordionTitle, + PurchaseSummaryAccordionAccordionSpanTitle, + PurchaseSummaryAccordionAccordionUlItens, +} from './style' +import { PurchaseSummaryAccordionProps } from './type' + +export function PurchaseSummaryAccordion({ + title, + total, + listDiscount, +}: PurchaseSummaryAccordionProps) { + const [isOpen, setIsOpen] = useState(false) + + const toggleAccordion = () => { + setIsOpen(!isOpen) + } + + return ( + + + + {title} + + + {isOpen ? ( + + ) : ( + + )} + + + {total} + + + + {isOpen && listDiscount && listDiscount.length > 0 && ( + + + {listDiscount.map((item) => ( + + + {item.title} + + + {item.price} + + + ))} + + + )} + + ) +} diff --git a/src/components/PurchaseSummary/PurchaseSummaryAccordion/style.tsx b/src/components/PurchaseSummary/PurchaseSummaryAccordion/style.tsx new file mode 100644 index 0000000..dca4610 --- /dev/null +++ b/src/components/PurchaseSummary/PurchaseSummaryAccordion/style.tsx @@ -0,0 +1,103 @@ +import styled from 'styled-components' +import { Colors, mediaQueries } from '../../../tokens' + +const PurchaseSummaryAccordionAccordionContainer = styled.div` + margin: 0; + padding: 0; + box-sizing: border-box; + font-size: 14px; +` + +const PurchaseSummaryAccordionAccordionHeader = styled.div` + width: 100%; + background-color: ${Colors.light.neutral.neutral100}; + color: ${Colors.light.neutral.neutral500}; + + display: flex; + justify-content: space-between; + cursor: pointer; + margin-bottom: 8px !important; +` + +const PurchaseSummaryAccordionAccordionContent = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + ul { + padding: 0 0 0 8px; + font-size: 12px; + + li { + font-size: 12px; + } + } + } +` + +const PurchaseSummaryAccordionAccordionItem = styled.li` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + padding-left: 16px; + + .itemValue { + color: ${Colors.light.action.action100}; + } +` + +const PurchaseSummaryAccordionPriceHeader = styled.span` + margin-left: auto; + cursor: pointer; + color: ${Colors.light.feedback.feedbackInfo100}; +` + +const PurchaseSummaryAccordionTitle = styled.span` + font-size: 14px; + color: ${Colors.light.neutral.neutral500}; + font-weight: 400; +` + +const PurchaseSummaryAccordionchevronIcon = styled.span` + color: ${Colors.light.neutral.neutral100}; + font-size: 14px; + cursor: pointer; + display: flex; + align-items: center; + margin-left: 7px; +` + +const PurchaseSummaryAccordionAccordionTitle = styled.li` + font-size: 14px; + color: ${Colors.light.neutral.neutral500}; + padding-left: 8px; +` + +const PurchaseSummaryAccordionItemValue = styled.span` + color: ${Colors.light.action.action100}; +` + +const PurchaseSummaryAccordionAccordionSpanTitle = styled.span` + color: ${Colors.light.neutral.neutral500}; +` + +const PurchaseSummaryAccordionAccordionUlItens = styled.ul` + padding: 0 0 0 11px; + margin: 0; +` + +export { + PurchaseSummaryAccordionAccordionContainer, + PurchaseSummaryAccordionAccordionHeader, + PurchaseSummaryAccordionAccordionContent, + PurchaseSummaryAccordionAccordionItem, + PurchaseSummaryAccordionPriceHeader, + PurchaseSummaryAccordionTitle, + PurchaseSummaryAccordionchevronIcon, + PurchaseSummaryAccordionItemValue, + PurchaseSummaryAccordionAccordionTitle, + PurchaseSummaryAccordionAccordionSpanTitle, + PurchaseSummaryAccordionAccordionUlItens, +} diff --git a/src/components/PurchaseSummary/PurchaseSummaryAccordion/type.ts b/src/components/PurchaseSummary/PurchaseSummaryAccordion/type.ts new file mode 100644 index 0000000..aa14c2b --- /dev/null +++ b/src/components/PurchaseSummary/PurchaseSummaryAccordion/type.ts @@ -0,0 +1,9 @@ +import { PurchaseSummaryDiscountItemProps } from '../type' + +type PurchaseSummaryAccordionProps = { + title: string + total: number | string + listDiscount?: Array +} + +export type { PurchaseSummaryAccordionProps } diff --git a/src/components/PurchaseSummary/index.tsx b/src/components/PurchaseSummary/index.tsx new file mode 100644 index 0000000..6b1db89 --- /dev/null +++ b/src/components/PurchaseSummary/index.tsx @@ -0,0 +1,78 @@ +import React from 'react' +import { PurchaseSummaryProps } from './type' +import { + PurchaseSummaryContainer, + PurchaseSummaryTitle, + PurchaseSummaryItemContainer, + PurchaseSummaryItemText, + PurchaseSummaryProductsPrice, + PurchaseSummaryDeliveryPrice, + PurchaseSummaryItemsTitle, + PurchaseSummaryLineDivider, + PurchaseSummaryFooter, + PurchaseSummaryFooterItems, + PurchaseSummaryFooterTitle, + PurchaseSummaryTotal, + PurchaseSummaryPaymentInstallments, +} from './style' + +const PurchaseSummary: React.FC = ({ + title, + productsLabel, + deliveryValue, + totalItems, + labelItensText, + productsPrice, + deliveryCost, + totalPrice, + installmentPayment, + children, +}) => { + return ( + + {title && {title}} + + + {productsLabel} + + ({totalItems} {labelItensText}) + + + {productsPrice} + + + + + {deliveryValue && ( + + + {deliveryValue} + + {deliveryCost} + + + + )} + + {children && ( + {children} + )} + + + + + Total + + {totalPrice} + {installmentPayment && ( + + {installmentPayment} + + )} + + + + ) +} + +export { PurchaseSummary } diff --git a/src/components/PurchaseSummary/style.tsx b/src/components/PurchaseSummary/style.tsx new file mode 100644 index 0000000..360e817 --- /dev/null +++ b/src/components/PurchaseSummary/style.tsx @@ -0,0 +1,136 @@ +import styled from 'styled-components' +import { Colors, mediaQueries, BorderRadius } from '../../tokens' + +const PurchaseSummaryContainer = styled.div` + display: flex; + flex-direction: column; + background-color: ${Colors.light.neutral.neutral100}; + flex-wrap: wrap; + padding: 16px; + max-width: 420px; + width: 100%; + border: 1px solid ${Colors.light.neutral.neutral200}; + border-radius: ${BorderRadius[3]}; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + p, + span { + font-size: 12px; + } + } +` + +const PurchaseSummaryTitle = styled.h1` + font-size: 20px; + margin: 0 0 16px 0; + color: ${Colors.dark.neutral.neutral600}; +` + +const PurchaseSummaryItemContainer = styled.div` + margin-bottom: 16px; +` + +const PurchaseSummaryItemText = styled.p` + display: flex; + justify-content: space-between; + margin: 0; + color: ${Colors.light.neutral.neutral500}; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + width: 100%; + font-size: 14px; + } +` + +const PurchaseSummaryProductsPrice = styled.span` + font-size: 14px; + color: ${Colors.light.neutral.neutral500}; +` +const PurchaseSummaryDeliveryPrice = styled.span` + font-size: 14px; + color: ${Colors.light.neutral.neutral500}; +` + +const PurchaseSummaryLineDivider = styled.hr` + border: 0; + border-top: 1px solid ${Colors.light.neutral.neutral200}; + margin: 0 0 16px 0; +` + +const PurchaseSummaryTotalContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +` + +const PurchaseSummaryTotalText = styled.p` + margin: 0; +` +const PurchaseSummaryItemsTitle = styled.span` + color: ${Colors.light.neutral.neutral500}; + font-weight: bold; + margin-right: auto; + margin-left: 3px; +` + +const PurchaseSummaryFooter = styled.div` + width: 100%; + display: flex; + justify-content: space-between; + border-bottom-left-radius: ${BorderRadius[3]}; + border-bottom-right-radius: ${BorderRadius[3]}; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + display: flex; + flex-direction: row; + } +` + +const PurchaseSummaryFooterTitle = styled.span` + font-weight: bold; + color: ${Colors.light.neutral.neutral500}; +` + +const PurchaseSummaryFooterItems = styled.div` + display: flex; + flex-direction: column; + margin: 0; + padding: 0; +` + +const PurchaseSummaryTotal = styled.span` + font-size: 16px; + font-weight: bold; + color: ${Colors.light.neutral.neutral500}; + text-align: right; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + font-size: 12px; + } +` +const PurchaseSummaryPaymentInstallments = styled.div` + text-decoration: underline; + text-underline-offset: 4px; + color: ${Colors.light.neutral.neutral500}; + + @media screen and (max-width: ${mediaQueries.screenXxs}) { + font-size: 12px; + } +` +export { + PurchaseSummaryContainer, + PurchaseSummaryTitle, + PurchaseSummaryItemContainer, + PurchaseSummaryItemText, + PurchaseSummaryProductsPrice, + PurchaseSummaryDeliveryPrice, + PurchaseSummaryLineDivider, + PurchaseSummaryTotalContainer, + PurchaseSummaryTotalText, + PurchaseSummaryItemsTitle, + PurchaseSummaryFooter, + PurchaseSummaryFooterTitle, + PurchaseSummaryFooterItems, + PurchaseSummaryTotal, + PurchaseSummaryPaymentInstallments, +} diff --git a/src/components/PurchaseSummary/type.ts b/src/components/PurchaseSummary/type.ts new file mode 100644 index 0000000..e73bf2e --- /dev/null +++ b/src/components/PurchaseSummary/type.ts @@ -0,0 +1,23 @@ +type PurchaseSummaryProps = { + title?: string + productsLabel: string + labelItensText: string + deliveryValue?: string + totalItems: number + productsPrice: number + deliveryCost: number + totalDiscount: number + totalPrice: number + installmentPayment?: string + discounts: Array + children?: React.ReactNode + discountLabel: string +} + +type PurchaseSummaryDiscountItemProps = { + id: number + title: string + price: string +} + +export type { PurchaseSummaryProps, PurchaseSummaryDiscountItemProps } diff --git a/src/tokens/colors.ts b/src/tokens/colors.ts index 904ef6a..5592e85 100644 --- a/src/tokens/colors.ts +++ b/src/tokens/colors.ts @@ -69,6 +69,7 @@ const Colors: ThemeColors = { neutral300: '#B8B8B8', neutral400: '#707070', neutral500: '#292929', + neutral600: '#000000', }, action: { action100: '#3AD883',