Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: [Refinements] Creates ShippingSimulation #183

Merged
merged 27 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c71b478
Tweaks PDP grid
eduardoformiga Jul 27, 2022
4f23cef
Creates shipping simulation component
eduardoformiga Jul 27, 2022
9b5757c
Adds ShippingSimulation parts and styles
eduardoformiga Jul 27, 2022
14aa177
Tweaks PDP grid
eduardoformiga Jul 28, 2022
9440c50
Updates input text clear button control
eduardoformiga Jul 28, 2022
2b9aec2
Adds conditional rendering and session checking
eduardoformiga Jul 28, 2022
b3a181c
Renames from Zip code to Postal Code
eduardoformiga Jul 28, 2022
988b21a
Makes Postal Code link text uniform
eduardoformiga Jul 28, 2022
bfba7ac
Themification ShippingSimulation
eduardoformiga Jul 28, 2022
d5cdfe9
Organizes ShippingSimulation component
eduardoformiga Jul 28, 2022
3db162a
Manages simulation state using single object
eduardoformiga Jul 28, 2022
5fd821b
Adds CHANGELOG entry
eduardoformiga Jul 28, 2022
4c97ef3
Creates Stories
eduardoformiga Jul 28, 2022
9e4d37d
Merge branch 'main' into feat/fs-475-shipping-simulation
eduardoformiga Jul 28, 2022
e32e892
removes stories folder
eduardoformiga Jul 28, 2022
ef62685
Fixes sonarQube
eduardoformiga Jul 28, 2022
21fd149
Trigger CI
eduardoformiga Jul 29, 2022
551a7be
Merge branch 'main' into feat/fs-475-shipping-simulation
eduardoformiga Aug 15, 2022
3ccae86
Extracts code into new hook that uses useReducer
eduardoformiga Aug 15, 2022
b1c1185
Merge branch 'main' into feat/fs-475-shipping-simulation
eduardoformiga Aug 15, 2022
3e02ec1
Removes -tablet from tokens
eduardoformiga Aug 16, 2022
da23293
Tweaks border radius
eduardoformiga Aug 16, 2022
cac3156
Tweaks font-size token
eduardoformiga Aug 16, 2022
2eef085
Removes too specific token
eduardoformiga Aug 16, 2022
c67e72e
Merge branch 'main' into feat/fs-475-shipping-simulation
eduardoformiga Aug 16, 2022
015bab6
Tweaks tokens spaces
eduardoformiga Aug 16, 2022
64c74f6
Removes SessionProvider from stories
eduardoformiga Aug 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/regionalization/Regionalization.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Regionalization uses a behavior from VTEX Intelligent Search called [Availabilit

Stores that have more than one registered white label seller usually have specific inventories for each region. This is the case for supermarkets, for example.

With the Regionalization feature enabled, if a customer enters their ZIP code while browsing the store (before checkout), only products available in the corresponding region will be displayed in the search results.
With the Regionalization feature enabled, if a customer enters their Postal Code while browsing the store (before checkout), only products available in the corresponding region will be displayed in the search results.

### Steps

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function RegionInput({ closeModal }: Props) {

closeModal()
} catch (error) {
setErrorMessage('You entered an invalid Zip Code')
setErrorMessage('You entered an invalid Postal Code')
}
}

Expand All @@ -44,7 +44,7 @@ function RegionInput({ closeModal }: Props) {
inputRef={inputRef}
id="postal-code-input"
error={errorMessage}
label="Zip Code"
label="Postal Code"
actionable
value={input}
onInput={(e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function RegionalizationModalContent({
<RegionalizationInput closeModal={() => onClose?.()} />
</div>
<Link href="/" data-fs-regionalization-modal-link>
{"Don't know my Postal Code"}
{"I don't know my Postal Code"}
<Icon name="ArrowSquareOut" width={18} height={18} />
</Link>
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/components/sections/ProductDetails/ProductDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ImageGallery } from 'src/components/ui/ImageGallery'
import Price from 'src/components/ui/Price'
import ProductTitle from 'src/components/ui/ProductTitle'
import QuantitySelector from 'src/components/ui/QuantitySelector'
import ShippingSimulation from 'src/components/ui/ShippingSimulation'
import { useBuyButton } from 'src/sdk/cart/useBuyButton'
import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice'
import { useProduct } from 'src/sdk/product/useProduct'
Expand Down Expand Up @@ -183,6 +184,8 @@ function ProductDetails({ product: staleProduct }: Props) {
)}
</section>

<ShippingSimulation />

<section className="product-details__content">
<article className="product-details__description">
<h2 className="text__title-subsection">Description</h2>
Expand Down
6 changes: 3 additions & 3 deletions src/components/sections/ProductDetails/product-details.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@include media(">=tablet") {
display: grid;
grid-template-rows: repeat(4, minmax(0, max-content));
grid-template-rows: repeat(2, minmax(0, min-content)) 270px minmax(0, max-content);
grid-template-columns: repeat(12, 1fr);
row-gap: 0;
column-gap: var(--fs-spacing-4);
Expand Down Expand Up @@ -66,12 +66,12 @@
}

@include media(">=tablet") {
grid-row: 2 / span 3;
grid-row: 2;
grid-column: 8 / span 5;
height: 100%;
padding: var(--fs-spacing-5);
border: var(--fs-border-width) solid var(--fs-border-color-light);
border-top: 0;
border-radius: 0 0 var(--fs-border-radius) var(--fs-border-radius);
}

@include media(">=notebook") { grid-column: 9 / span 4; }
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/ImageGallery/image-gallery.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

@include media(">=tablet") {
left: 0;
grid-row: 1 / span 2;
grid-row: 1 / span 3;
grid-column: span 7;
width: 100%;
margin-bottom: var(--fs-spacing-7);
Expand Down
8 changes: 7 additions & 1 deletion src/components/ui/InputText/InputText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type ActionableInputText =
onSubmit?: never
onClear?: never
buttonActionText?: string
displayClearButton?: never
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL never

}
| {
/**
Expand All @@ -54,6 +55,10 @@ type ActionableInputText =
* The text displayed on the Button. Suggestion: maximum 9 characters.
*/
buttonActionText?: string
/**
* Boolean that controls the clear button.
*/
displayClearButton?: boolean
}

export type InputTextProps = DefaultProps &
Expand All @@ -65,6 +70,7 @@ const InputText = ({
label,
type = 'text',
error,
displayClearButton,
actionable,
buttonActionText = 'Apply',
onSubmit,
Expand Down Expand Up @@ -97,7 +103,7 @@ const InputText = ({
<UILabel htmlFor={id}>{label}</UILabel>

{shouldDisplayButton &&
(error ? (
(displayClearButton || error ? (
<Button
variant="tertiary"
data-fs-button-icon
Expand Down
153 changes: 153 additions & 0 deletions src/components/ui/ShippingSimulation/ShippingSimulation.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { Meta, Canvas, Story, ArgsTable } from '@storybook/addon-docs'
import ShippingSimulation from '.'
import {
TokenTable,
TokenRow,
TokenDivider,
} from 'src/../.storybook/components'

<Meta
title="Features/ShippingSimulation"
component={ShippingSimulation}
argTypes={{
testId: {
table: {
disable: true,
},
},
}}
/>

export const TemplateProvider = (args) => {
return <ShippingSimulation {...args} style={{ border: 0 }} />
}

<header>

# Shipping Simulation

This feature lets customers set the `PostalCode` and see the shipping options in the `PDP`.

</header>

## Overview

The `ShippingSimulation` component uses [FastStore UI Table](https://www.faststore.dev/reference/ui/molecules/Table), and [InputText](/docs/atoms-inputtext-⚠%EF%B8%8F--default) as base.

### Steps

1. First, the available `ShippingSimulation` loads if any `PostalCode` is set using the [Regionalization](/docs/features-regionalization-overview--default-button).
2. If there is no `PostalCode` in the [Regionalization](/docs/features-regionalization-overview--default-button), the user can set the desired shipping `PostalCode`.
3. Updates `ShippingSimulation`.
4. Gets notified if there are no available options.

---

## Usage

`import ShippingSimulation from 'src/components/ui/ShippingSimulation'`

<Canvas>
<Story name="default">{TemplateProvider.bind({})}</Story>
</Canvas>

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-font-size"
value="var(--fs-text-size-legend)"
/>
<TokenDivider />
<TokenRow
token="--fs-shipping-simulation-padding"
value="var(--fs-spacing-5)"
/>
<TokenRow
token="--fs-shipping-simulation-border-width"
value="var(--fs-border-width)"
/>
<TokenRow
token="--fs-shipping-simulation-border-color"
value="var(--fs-border-color-light)"
isColor
/>
<TokenRow
token="--fs-shipping-simulation-border-radius-bottom"
value="var(--fs-border-radius)"
/>
</TokenTable>

---

## Nested Elements

### Title

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-title-padding-bottom"
value="var(--fs-spacing-2)"
/>
</TokenTable>

### Link

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-link-padding-top"
value="var(--fs-spacing-1)"
/>
<TokenRow
token="--fs-shipping-simulation-link-padding-bottom"
value="var(--fs-spacing-4)"
/>
</TokenTable>

### Subtitle

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-subtitle-text-size"
value="var(--fs-text-size-2)"
/>
<TokenRow
token="--fs-shipping-simulation-subtitle-text-weight"
value="var(--fs-text-weight-bold)"
/>
<TokenRow token="--fs-shipping-simulation-subtitle-line-height" value="1.5" />
</TokenTable>

### Location

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-location-padding-bottom"
value="var(--fs-spacing-2)"
/>
</TokenTable>

### Table

<TokenTable>
<TokenRow
token="--fs-shipping-simulation-table-row-bkg-color"
value="var(--fs-color-main-0)"
isColor
/>
<TokenRow
token="--fs-shipping-simulation-table-row-even-bkg-color"
value="transparent"
/>
<TokenDivider />
<TokenRow
token="--fs-shipping-simulation-table-cell-padding"
value="var(--fs-spacing-2)"
/>
<TokenRow
token="--fs-shipping-simulation-table-cell-text-size"
value="var(--fs-text-size-2)"
/>
<TokenRow
token="--fs-shipping-simulation-table-cell-border-radius"
value=".25rem"
/>
</TokenTable>
107 changes: 107 additions & 0 deletions src/components/ui/ShippingSimulation/ShippingSimulation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Table, TableBody, TableCell, TableRow } from '@faststore/ui'
import type { HTMLAttributes } from 'react'

import Price from 'src/components/ui/Price'
import { usePriceFormatter } from 'src/sdk/product/useFormattedPrice'

import Icon from '../Icon'
import InputText from '../InputText'
import Link from '../Link'
import styles from './shipping-simulation.module.scss'
import { useShippingSimulation } from './useShippingSimulation'

interface ShippingSimulationProps extends HTMLAttributes<HTMLDivElement> {
/**
* ID to find this component in testing tools (e.g.: cypress,
* testing-library, and jest).
*/
testId?: string
}

function ShippingSimulation({
testId = 'store-shipping-simulation',
...otherProps
}: ShippingSimulationProps) {
const { dispatch, input, shippingSimulation, handleSubmit, handleOnInput } =
useShippingSimulation()

const {
postalCode: shippingPostalCode,
displayClearButton,
errorMessage,
} = input

const { location: shippingLocation, options: shippingOptions } =
shippingSimulation

const formatter = usePriceFormatter()

const hasShippingOptions = !!shippingOptions && shippingOptions.length > 0

return (
<section
className={styles.fsShippingSimulation}
data-fs-shipping-simulation
data-fs-shipping-simulation-empty={!hasShippingOptions ? 'true' : 'false'}
data-testid={testId}
{...otherProps}
>
<h2 className="text__title-subsection" data-fs-shipping-simulation-title>
Shipping
</h2>

<InputText
actionable
error={errorMessage}
id="shipping-postal-code"
label="Postal Code"
value={shippingPostalCode}
onInput={handleOnInput}
onSubmit={handleSubmit}
onClear={() => dispatch({ type: 'clear' })}
displayClearButton={displayClearButton}
/>

<Link href="/" data-fs-shipping-simulation-link>
{"I don't know my Postal Code"}
<Icon name="ArrowSquareOut" width={18} height={18} />
</Link>

{hasShippingOptions && (
<>
<h3 data-fs-shipping-simulation-subtitle>Shipping options</h3>
<p className="text__body" data-fs-shipping-simulation-location>
{shippingLocation}
</p>

<Table data-fs-shipping-simulation-table>
<TableBody>
{shippingOptions.map((option) => (
<TableRow
key={option.carrier}
data-fs-shipping-simulation-table-row
>
<TableCell data-fs-shipping-simulation-table-cell>
{option.carrier}
</TableCell>
<TableCell data-fs-shipping-simulation-table-cell>
{option.estimate}
</TableCell>
<TableCell data-fs-shipping-simulation-table-cell>
<Price
formatter={formatter}
value={option.price}
SRText="price"
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</>
)}
</section>
)
}

export default ShippingSimulation
1 change: 1 addition & 0 deletions src/components/ui/ShippingSimulation/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ShippingSimulation'
Loading