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: adding new free shipping bar functionality #177

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
7 changes: 5 additions & 2 deletions components/minicart/Cart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AnalyticsEvent } from "deco-sites/std/commerce/types.ts";
import { useUI } from "deco-sites/fashion/sdk/useUI.ts";
import CartItem from "./CartItem.tsx";
import Coupon from "./Coupon.tsx";
import FreeShippingBar from "./FreeShippingBar.tsx";

declare global {
interface Window {
Expand All @@ -23,8 +24,8 @@ function Cart() {
const { cart, loading, mapItemsToAnalyticsItems } = useCart();
const isCartEmpty = cart.value?.items.length === 0;
const total = cart.value?.totalizers.find((item) => item.id === "Items");
const discounts = cart.value?.totalizers.find((item) =>
item.id === "Discounts"
const discounts = cart.value?.totalizers.find(
(item) => item.id === "Discounts",
);
const locale = cart.value?.clientPreferencesData.locale;
const currencyCode = cart.value?.storePreferencesData.currencyCode;
Expand Down Expand Up @@ -53,6 +54,7 @@ function Cart() {
return (
<>
{/* Cart Items */}
<FreeShippingBar />
<ul
role="list"
class="mt-6 px-2 flex-grow overflow-y-auto flex flex-col gap-6"
Expand Down Expand Up @@ -129,3 +131,4 @@ function Cart() {
}

export default Cart;

54 changes: 54 additions & 0 deletions components/minicart/FreeShippingBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Icon from "deco-sites/fashion/components/ui/Icon.tsx";
import { useCart } from "deco-sites/std/commerce/vtex/hooks/useCart.ts";

import { formatPrice } from "deco-sites/fashion/sdk/format.ts";

export interface Props {
value?: number;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

since this component will likely be used by a huge amount of people, I think it may worth to add at least short descriptions here

e.g.: https://github.com/deco-sites/fashion/blob/main/components/header/Header.tsx#L34

Choose a reason for hiding this comment

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

@mcandeia ahh, yes... great suggestion


function FreeShippingBar({ value }: Props) {
const { cart } = useCart();

const locale = cart.value?.clientPreferencesData.locale;
const currencyCode = cart.value?.storePreferencesData.currencyCode;

const total = cart.value?.totalizers.find((item) => item.id === "Items");

if (!total || !value) return null;

const progress = ((total?.value / 100) / value) * 100;

return (
<>
<div className="pt-4 mx-4">
<div className="mb-2 text-[#1A7346]">
<Icon
className="mr-2 inline-block"
id="TruckShippingBar"
size={21}
stroke="currentColor"
strokeWidth={0}
/>
{progress < 100
? `Faltam R$ ${
formatPrice(value - total?.value / 100, currencyCode!, locale)
} para o frete grátis`
: "Parabéns! Você tem frete grátis"}
Copy link
Contributor

Choose a reason for hiding this comment

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

How about use a config key instead?

you can let the user input a sort of templatestring e.g

export interface Messages {
    leftTofreeShippingTemplate: string // "Faltam {currency} {value} para o frete grátis"
    freeShipping: string // "Parabéns! Você tem frete grátis"
}

export interface Props {
  value?: number;
  messages: Messages;
}

Then you can replace when using it

const leftToShipping = props.message.leftToShippingTemplate.replace("{currency}", currencyCode).replace("{value}", formatPrice(value - total?.value / 100, currencyCode!, locale))

Choose a reason for hiding this comment

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

@mcandeia makes a lot of sense... improvements completed

</div>
<div
className="bg-[#D4DBD7] h-2.5 rounded-full"
style={{ width: `100%` }}
>
<div
className="max-w-full bg-[#1A7346] h-2.5 rounded-full after:content-[''] after:h-[10px] after:w-[10px] after:ml-0.5 after:bg-[#FFFFFF] after:block after:rounded-full after:float-right block"
style={{ width: `${progress}%` }}
>
</div>
</div>
</div>
</>
);
}

export default FreeShippingBar;
3 changes: 2 additions & 1 deletion components/ui/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export type AvailableIcons =
| "Trash"
| "FilterList"
| "WhatsApp"
| "ArrowsPointingOut";
| "ArrowsPointingOut"
| "TruckShippingBar";

interface Props extends JSX.SVGAttributes<SVGSVGElement> {
/**
Expand Down
8 changes: 8 additions & 0 deletions sections/FreeShippingBarValue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import FreeShippingBar from "deco-sites/fashion/components/minicart/FreeShippingBar.tsx";
import type { Props } from "deco-sites/fashion/components/minicart/FreeShippingBar.tsx";

function FreeShippingBarSection(props: Props) {
return <FreeShippingBar {...props} />;
}

export default FreeShippingBarSection;
1 change: 1 addition & 0 deletions static/sprites.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.