4
0
forked from crowetic/commerce

Latest Release (#187)

* Remove duplicated css rules. (#185)

* Fix typo in the Marquee component (#176)

Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* Remove duplicated css rules.
Fix invalid JSX props.

Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* Fix the body scroll when the sidebar is open (#184)

* Fix typo in the Marquee component (#176)

Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* Fix the body scroll when the sidebar is open

Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* Remove duplicate class in the I18nWidget comp (#183)

* Fix typo in the Marquee component (#176)

Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* Remove duplicate class name in the I18nWidget comp

This PR removes a duplicate class name in the I18nWidget component.

Co-authored-by: Hugo Lopes <hugo.rodrigues.lopes@gmail.com>
Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>

* add horizontal margin to pages when mobile screen (#180)

* Add cart item options like color and size (#177)

Co-authored-by: hlopes <hugo.lopes@present-technologies.com>

* Changes

Co-authored-by: Hugo Lopes <hugo.rodrigues.lopes@gmail.com>
Co-authored-by: Hugo Lopes <hugo.lopes@present-technologies.com>
Co-authored-by: Jamie Isaksen <jamie@jamie.no>
Co-authored-by: Vinicius Zucatti <51221635+vczb@users.noreply.github.com>
This commit is contained in:
B 2021-01-29 12:00:16 -03:00 committed by GitHub
parent 08a6b2efcf
commit 3a7d5e2489
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 51 additions and 32 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# local env files # local env files
.env
.env.local .env.local
.env.development.local .env.development.local
.env.test.local .env.test.local

View File

@ -102,8 +102,6 @@ a {
} }
.animated { .animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-duration: 1s; -webkit-animation-duration: 1s;
animation-duration: 1s; animation-duration: 1s;
-webkit-animation-fill-mode: both; -webkit-animation-fill-mode: both;

View File

@ -8,6 +8,13 @@ import useUpdateItem from '@framework/cart/use-update-item'
import useRemoveItem from '@framework/cart/use-remove-item' import useRemoveItem from '@framework/cart/use-remove-item'
import s from './CartItem.module.css' import s from './CartItem.module.css'
type ItemOption = {
name: string,
nameId: number,
value: string,
valueId: number
}
const CartItem = ({ const CartItem = ({
item, item,
currencyCode, currencyCode,
@ -88,12 +95,20 @@ const CartItem = ({
<div className="flex-1 flex flex-col text-base"> <div className="flex-1 flex flex-col text-base">
{/** TODO: Replace this. No `path` found at Cart */} {/** TODO: Replace this. No `path` found at Cart */}
<Link href={`/product/${item.url.split('/')[3]}`}> <Link href={`/product/${item.url.split('/')[3]}`}>
<span className="font-bold mb-5 text-lg cursor-pointer"> <span className="font-bold text-lg cursor-pointer leading-6">
{item.name} {item.name}
</span> </span>
</Link> </Link>
{item.options && item.options.length > 0 ? (
<div className="flex items-center"> <div className="">
{item.options.map((option:ItemOption, i: number) =>
<span key={`${item.id}-${option.name}`} className="text-sm font-semibold text-accents-7">
{option.value}{ i === item.options.length -1 ? "" : ", " }
</span>
)}
</div>
) : null}
<div className="flex items-center mt-3">
<button type="button" onClick={() => increaseQuantity(-1)}> <button type="button" onClick={() => increaseQuantity(-1)}>
<Minus width={18} height={18} /> <Minus width={18} height={18} />
</button> </button>

View File

@ -29,7 +29,7 @@
} }
.item { .item {
@apply flex cursor-pointer px-6 py-3 flex transition ease-in-out duration-150 text-primary leading-6 font-medium items-center; @apply flex cursor-pointer px-6 py-3 transition ease-in-out duration-150 text-primary leading-6 font-medium items-center;
text-transform: capitalize; text-transform: capitalize;
} }

View File

@ -61,16 +61,16 @@ const Layout: FC<Props> = ({ children, pageProps }) => {
<main className="fit">{children}</main> <main className="fit">{children}</main>
<Footer pages={pageProps.pages} /> <Footer pages={pageProps.pages} />
<Sidebar open={displaySidebar} onClose={closeSidebar}>
<CartSidebarView />
</Sidebar>
<Modal open={displayModal} onClose={closeModal}> <Modal open={displayModal} onClose={closeModal}>
{modalView === 'LOGIN_VIEW' && <LoginView />} {modalView === 'LOGIN_VIEW' && <LoginView />}
{modalView === 'SIGNUP_VIEW' && <SignUpView />} {modalView === 'SIGNUP_VIEW' && <SignUpView />}
{modalView === 'FORGOT_VIEW' && <ForgotPassword />} {modalView === 'FORGOT_VIEW' && <ForgotPassword />}
</Modal> </Modal>
<Sidebar open={displaySidebar} onClose={closeSidebar}>
<CartSidebarView />
</Sidebar>
<FeatureBar <FeatureBar
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy." title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
hide={acceptedCookies} hide={acceptedCookies}

View File

@ -38,15 +38,14 @@ const ProductView: FC<Props> = ({ product }) => {
size: null, size: null,
color: null, color: null,
}) })
const variant = const variant = getCurrentVariant(product, choices)
getCurrentVariant(product, choices) || product.variants.edges?.[0]
const addToCart = async () => { const addToCart = async () => {
setLoading(true) setLoading(true)
try { try {
await addItem({ await addItem({
productId: product.entityId, productId: product.entityId,
variantId: product.variants.edges?.[0]?.node.entityId!, variantId: variant?.node.entityId!,
}) })
openSidebar() openSidebar()
setLoading(false) setLoading(false)
@ -156,7 +155,7 @@ const ProductView: FC<Props> = ({ product }) => {
<WishlistButton <WishlistButton
className={s.wishlistButton} className={s.wishlistButton}
productId={product.entityId} productId={product.entityId}
variant={product.variants.edges?.[0]!} variant={variant!}
/> />
</div> </div>
</Container> </Container>

View File

@ -32,8 +32,10 @@ export function getProductOptions(product: ProductNode) {
export function getCurrentVariant(product: ProductNode, opts: SelectedOptions) { export function getCurrentVariant(product: ProductNode, opts: SelectedOptions) {
const variant = product.variants.edges?.find((edge) => { const variant = product.variants.edges?.find((edge) => {
const { node } = edge ?? {} const { node } = edge ?? {}
const numberOfDefinedOpts = Object.values(opts).filter(value => value !== null).length;
const numberOfEdges = node?.productOptions?.edges?.length;
return Object.entries(opts).every(([key, value]) => const isEdgeEqualToOption = ([key, value]:[string, string | null]) =>
node?.productOptions.edges?.find((edge) => { node?.productOptions.edges?.find((edge) => {
if ( if (
edge?.node.__typename === 'MultipleChoiceOption' && edge?.node.__typename === 'MultipleChoiceOption' &&
@ -43,9 +45,12 @@ export function getCurrentVariant(product: ProductNode, opts: SelectedOptions) {
(valueEdge) => valueEdge?.node.label === value (valueEdge) => valueEdge?.node.label === value
) )
} }
}) });
)
return numberOfDefinedOpts === numberOfEdges ?
Object.entries(opts).every(isEdgeEqualToOption)
: Object.entries(opts).some(isEdgeEqualToOption)
}) })
return variant return variant ?? product.variants.edges?.[0]
} }

View File

@ -9,7 +9,7 @@ interface Props {
variant?: 'primary' | 'secondary' variant?: 'primary' | 'secondary'
} }
const Maquee: FC<Props> = ({ const Marquee: FC<Props> = ({
className = '', className = '',
children, children,
variant = 'primary', variant = 'primary',
@ -32,4 +32,4 @@ const Maquee: FC<Props> = ({
) )
} }
export default Maquee export default Marquee

View File

@ -90,6 +90,7 @@ function uiReducer(state: State, action: Action) {
return { return {
...state, ...state,
displayModal: true, displayModal: true,
displaySidebar: false,
} }
} }
case 'CLOSE_MODAL': { case 'CLOSE_MODAL': {

View File

@ -26,8 +26,8 @@ const addItem: CartHandlers['addItem'] = async ({
}), }),
} }
const { data } = cartId const { data } = cartId
? await config.storeApiFetch(`/v3/carts/${cartId}/items`, options) ? await config.storeApiFetch(`/v3/carts/${cartId}/items?include=line_items.physical_items.options`, options)
: await config.storeApiFetch('/v3/carts', options) : await config.storeApiFetch('/v3/carts?include=line_items.physical_items.options', options)
// Create or update the cart cookie // Create or update the cart cookie
res.setHeader( res.setHeader(

View File

@ -12,7 +12,7 @@ const getCart: CartHandlers['getCart'] = async ({
if (cartId) { if (cartId) {
try { try {
result = await config.storeApiFetch(`/v3/carts/${cartId}`) result = await config.storeApiFetch(`/v3/carts/${cartId}?include=line_items.physical_items.options`)
} catch (error) { } catch (error) {
if (error instanceof BigcommerceApiError && error.status === 404) { if (error instanceof BigcommerceApiError && error.status === 404) {
// Remove the cookie if it exists but the cart wasn't found // Remove the cookie if it exists but the cart wasn't found

View File

@ -15,7 +15,7 @@ const removeItem: CartHandlers['removeItem'] = async ({
} }
const result = await config.storeApiFetch<{ data: any } | null>( const result = await config.storeApiFetch<{ data: any } | null>(
`/v3/carts/${cartId}/items/${itemId}`, `/v3/carts/${cartId}/items/${itemId}?include=line_items.physical_items.options`,
{ method: 'DELETE' } { method: 'DELETE' }
) )
const data = result?.data ?? null const data = result?.data ?? null

View File

@ -16,7 +16,7 @@ const updateItem: CartHandlers['updateItem'] = async ({
} }
const { data } = await config.storeApiFetch( const { data } = await config.storeApiFetch(
`/v3/carts/${cartId}/items/${itemId}`, `/v3/carts/${cartId}/items/${itemId}?include=line_items.physical_items.options`,
{ {
method: 'PUT', method: 'PUT',
body: JSON.stringify({ body: JSON.stringify({

View File

@ -65,7 +65,7 @@ export default function Pages({
page, page,
}: InferGetStaticPropsType<typeof getStaticProps>) { }: InferGetStaticPropsType<typeof getStaticProps>) {
return ( return (
<div className="max-w-2xl mx-auto py-20"> <div className="max-w-2xl mx-8 sm:mx-auto py-20">
{page?.body && <Text html={page.body} />} {page?.body && <Text html={page.body} />}
</div> </div>
) )

View File

@ -106,9 +106,9 @@ export default function Search({
fill="currentColor" fill="currentColor"
> >
<path <path
fill-rule="evenodd" fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
</button> </button>
@ -205,9 +205,9 @@ export default function Search({
fill="currentColor" fill="currentColor"
> >
<path <path
fill-rule="evenodd" fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
</button> </button>
@ -378,9 +378,9 @@ export default function Search({
fill="currentColor" fill="currentColor"
> >
<path <path
fill-rule="evenodd" fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
</button> </button>