0.1.0 • Published 3 months ago

@bogos/freegifts-hydrogen v0.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
3 months ago

BOGOS: Freegifts Hydrogen App

Requirements

Installation

Step 1: Getting started

  1. Navigate to your working directory.

    cd <directory>
  2. Install BOGOS: Free gift package

    npm i @bogos/freegifts-hydrogen

Step 2: Integration

  1. Open file containing event to render cart component (This event should be rendered on every single page), and add this basic integration:

    import {BOGOS} from '@bogos/freegifts-hydrogen';
    ...
    <Await resolve={data.cart}>
        {(cart) => (
            <>
                <BOGOS
                    cart={cart}
                    customerAccessToken={CUSTOMER_ACCESS_TOKEN}
    
                    publicStoreDomain={PUBLIC_STORE_DOMAIN}
                    publicStorefrontApiToken={PUBLIC_STORE_FRONT_API_TOKEN}
                    publicStorefrontApiVersion={PUBLIC_STOREFRONT_API_VERSION}
                    bogosAccessToken={BOGOS_ACCESS_TOKEN}
                />
            ...
            </>
        )}
    </Await>
    ...
    • Details of BOGOS component properties
    import { Cart, Customer } from "@shopify/hydrogen/storefront-api-types";
    
    interface BOGOSProps {
        cart: Cart;
        customerAccessToken?: string;
        publicStoreDomain: string;
        publicStorefrontApiToken: string;
        publicStorefrontApiVersion: string;
        bogosAccessToken: string;
    
        customer?: Customer;
        others?: OthersSetting;
        renderCart?: Function;
    }
  2. Find Checkout button, and add bogosCheckCartValid function to prevent gift invalid after checkout.

    import {bogosCheckCartValid} from '@bogos/freegifts-hydrogen';
    
    async function {your_function_checkout} (args) {
        ...
        await bogosCheckCartValid({});
        ...
    }
    • Details of bogosCheckCartValid function
    export type BogosCheckCartValidParams = {
        cart?: Cart | FGObject; /* If you don't want to fetch catch again */
        reloadIfInvalid?: boolean; /* Default: true. You don't want to reload page if invalid */
        callback?: (isValidCart: boolean) => void; /* If you want to do something after BOGOS check */
    };
    
    export declare const bogosCheckCartValid: (params: BogosCheckCartValidParams) => Promise<boolean>;

Step 3: Details of Other settings for BOGOS

export type OthersSetting = {
    isPopUp?: boolean;
    customGiftImgSize?: string;
    enableToastAdded?: boolean;
    scaTextNotifySuccess?: string;
    localesFormat?: string;
    currencyCode?: string;
    currencyRate?: number;
    useRateForOffer?: boolean;
    disableBogosAttrCart?: boolean;
    disableReloadCartUpdated?: boolean;
    renderCart?: Function;
    useCart?: boolean;
    useCustomer?: boolean;
    prefixProduct?: string;
    numberOrders?: number;
    toFixed?: number;
    debug?: boolean;
};

Step 4: Integration customize

  1. Gift Icon

    • Details of BOGOSGiftIcon
    type GiftItem = {
        id: number;
        discount_type: 'percentage' | 'fixed_amount';
        discount_value: number;
        original_price: number;  // Original price - price before discount
        price: number;           // Discount price - price after discount
        title: string;
        thumbnail?: string;
    };
    
    type GiftProduct = {
        id: number;
        title: string;
        handle: string;
        thumbnail?: string;
        belongs_to_offer: string;
        variants: GiftItem[];
    };
    
    type FilterVariant = {
        id: string | number;
        title: string;
        price?: string | number;
    };
    
    type ProductInfo = {
        id: string | number;
        handle: string;
        title: string;
        price_max?: string | number;
        collections?: {
            id: string | number;
            title?: string;
        }[];
        product_type?: string;
        vendor?: string;
        variants?: FilterVariant[];
    };
    
    interface BOGOSGiftIconProps {
        product: ProductInfo;
        selectedVariant?: FilterVariant;
        enableForAllCondition?: boolean; /* Default false - only use with specific product condition */
        page: "collection" | "product";
    };
    
    /* Example Collection page or page has list products */
    <div ...>
        ...
        {products.map(product => (
            <div>
                ...
                <div style={{position: 'relative'}}>
                    ...
                    <BOGOSGiftIcon
                        product={{
                            id: product.id,
                            handle: product.handle,
                            title: product.title,
                        }}
                        page="collection"
                    />
                    ...
                </div>
                ...
            </div>
        ))}
        ...
    </div>
    
    /* Example Product page */
    <div ...> 
        ...
        <h1 style={{width: 'fit-content', position: 'relative'}}>
            {title}
            <BOGOSGiftIcon
                product={{
                    id: product.id,
                    handle: product.handle,
                    title: product.title,
                }}
                page="product"
            />
        </h1>
        ...
    </div>
    • Gift-icon customization (Use it in case you want to handle the customization of gift icon instead of using BOGOS default component)
    /* Other type check above */
    export interface BogosCheckProductHasGiftsParams {
        product: ProductInfo;
        selectedVariant?: FilterVariant;
        enableForAllCondition?: boolean;
    }
    
    /* Return the gift product associated with purchasing the product from product page */
    export declare const bogosCheckProductHasGifts: async ({ 
        product, 
        selectedVariant, 
        enableForAllCondition, 
    }: BogosCheckProductHasGiftsParams) => GiftProduct[];
    
    export const GiftIcon = (props: Props) => {
        /* States */
        const [gifts, setGifts] = useState<GiftProduct[]>([]);
    
        /* Vars */
        const event = "fg-data:loaded";
    
        const handleGiftIcon = async (e?: Event) => {
            try {
                setGifts(await bogosCheckProductHasGifts(props));
            } catch (e) {}
        };
    
        useEffect(() => {
            handleGiftIcon();
        }, [props.selectedVariant?.id]);
    
        useEffect(() => {
            /* This event will run on the next render */
            handleGiftIcon();
            /* This event is used after fetching BOGOS' data to get information of gift icon (only run once) */
            document.addEventListener(event, handleGiftIcon);
    
            return () => {
                document.removeEventListener(event, handleGiftIcon);
            };
        }, []);
    
        const renderGiftIcon = useCallback(() => {
            const gift_icon = typeof window !== "undefined" &&
                window?.FGSECOMAPP?.appearance?.gift_icon?.product_page?.gift_icon;
    
            /* Check if gift icon can be shown or not */
            if (gifts?.length > 0 && gift_icon && gift_icon?.status) {
                const giftIcon = window.FGSECOMAPP?.giftIcon; // or other icon you want to show
            }
            
            // render gift icons
        }, [gifts]);
    
        return <Fragment>{renderGiftIcon()}</Fragment>;
    };
  2. Gift thumbnail

    • Details of BOGOSGiftThumbnail
    /* Other type check above */
    
    interface Props {
        product: ProductInfo;
        selectedVariant?: FilterVariant;
        enableForAllCondition?: boolean;
        numberGiftsThumbnail?: number; /* Default: 3. Number of gift images can be shown per thumbnail */
        arrows?: boolean;
        dots?: boolean;
        prefixProduct?: string; /* Default: "/products/". Path name product */
    }
    
    /* Example Product page */
    <div ...> 
        ...
        <BOGOSGiftThumbnail
            product={{
                id: product.id,
                handle: product.handle,
                title: product.title,
            }}
            arrows={false}
        />
        {{ add_to_cart_btn }}
        ...
    </div>
    • Gift-thumbnail customization (Use it in case you want to handle the customization of gift thumbnail instead of using BOGOS default component)
    /* Other type check above */
    export interface BogosCheckProductHasGiftsParams {
        product: ProductInfo;
        selectedVariant?: FilterVariant;
        enableForAllCondition?: boolean;
    }
    
    /* Return the gift product associated with purchasing the product from product page */
    export declare const bogosCheckProductHasGifts: async ({ 
        product, 
        selectedVariant, 
        enableForAllCondition, 
    }: BogosCheckProductHasGiftsParams) => GiftProduct[];
    
    export const GiftThumbnail = (props: Props) => {
        /* States */
        const [gifts, setGifts] = useState<GiftProduct[]>([]);
    
        /* Vars */
        const event = "fg-data:loaded";
    
        const handleGiftThumbnail = (e?: Event) => {
            try {
                const gifts = await bogosCheckProductHasGifts(props);
                renderGiftThumbnail(gifts);
            } catch (e) {}
        };
    
        useEffect(() => {
            handleGiftThumbnail();
        }, [props.selectedVariant?.id]);
    
        useEffect(() => {
            /* This event will run on the next render */
            handleGiftThumbnail();
            /* This event is used after fetching BOGOS' data to get information of gift thumbnail (only run once) */
            document.addEventListener(event, handleGiftThumbnail);
    
            return () => {
                document.removeEventListener(event, handleGiftThumbnail);
            };
        }, []);
    
        const renderGiftThumbnail = useCallback(() => {
            const gift_thumbnail = typeof window !== "undefined" &&
                window?.FGSECOMAPP?.appearance?.gift_icon?.product_page?.gift_thumbnail;
                
            /* Check if gift thumbnail can be shown or not */
            if (gifts?.length > 0 && gift_thumbnail && gift_thumbnail?.status) {
                
            }
            
            // render gift thumbnail
        }, [gifts]);
    
        return <Fragment>{renderGiftThumbnail()}</Fragment>;
    };
  3. Cart message

    • Details of BOGOSCartMessage
    /* Other type check above */
    
    interface Props {
        delay?: number; /* Default: 3000 (ms). Time delay between auto scroll cart message */
        toFixed?: number; /* Default: 2. Number after '.' E.g: 100.00*/
    }
    
    /* Example */
    <div className={className}>
        <BOGOSCartMessage
            delay={5000}
        />
    
        <CartEmpty ... />
        <CartDetails ... />
    </div>
    • Cart message customization (Use it in case you want to handle the customization of cart message instead of using BOGOS default component)
    /* Other type check above */
    export interface BOGOSCartMessageParams {
        toFixed?: number;
    }
    
    /* return cart message can be shown */
    export declare const bogosCheckCartMessage: ({ toFixed, }: BOGOSCartMessageParams) => string[]; 
    
    export const CartMessage = (props: Props) => {
        /* States */
        const [msgs, setMsgs] = useState<{value: string}[]>([]);
    
        /* Vars */
        const event = "fg-cart:end-process";
    
        const handleCartMsg = (e?: Event) => {
            try {
            const msgs = e
                ? (e as CustomEvent)?.detail?.data
                : (typeof window !== "undefined" && window?.FGSECOMAPP?.cart_message) ?? [];
                setMsgs(msgs);
            } catch (e) {}
        };
    
        useEffect(() => {
            /* This event will run on the next render */
            handleGiftCartMsg();
            /* This event is used after fetching BOGOS' data to get information of cart message (only run once) */
            document.addEventListener(event, handleGiftCartMsg);
    
            return () => {
                document.removeEventListener(event, handleGiftCartMsg);
            };
        }, []);
    
        const renderCartMsg = useCallback(() => {
            const promotion_message = typeof window !== "undefined" &&
                window?.FGSECOMAPP?.appearance?.promotion_message;
      
            /* Check if cart message can be shown or not */
            if (
                messages?.length > 0 &&
                promotion_message &&
                promotion_message?.show_on_cart_page
            ) {
            
            }
            
            // render gift thumbnail
        }, [msgs]);
    
        return <Fragment>{renderCartMsg()}</Fragment>;
    };

Step 5: Other integration for BOGOS: Free Gift

  1. Hide gift product (cloned product) from your headless store

    • If you use products query, you should add : query: "tag_not:bogos-gift"
    products (
        ...,
        query: "tag_not:bogos-gift"
    ) {
    ...
    }
    • For collection and product page, you can import bogosCheckGift and use returned value to skip gift products or replace to other pages
    import {bogosCheckGift} from '@bogos/freegifts-hydrogen';
    • Details of bogosCheckGift
    export type ProductObject = {
        handle?: string;
        tags?: string[];
    };
    
    /* item can be product handle */
    export declare const bogosCheckGift: (item: string | ProductObject) => boolean;
  2. Customize gift popup/slider

    Change isPopup to true and listen event:

    type GiftItem = {
        id: number;
        discount_type: 'percentage' | 'fixed_amount';
        discount_value: number;
        original_price: number;  // Original price - price before discount
        price: number;           // Discount price - price after discount
        title: string;
        thumbnail?: string;
    };
    
    type GiftProduct = {
        id: number;
        title: string;
        handle: string;
        thumbnail?: string;
        belongs_to_offer: string;
        variants: GiftItem[];
    };
    
    export declare const bogosProcessAddGift: (variantID: number | string, quantity: number, offerId: string) => void;
    
    document.addEventListener("fg-gifts:show-slider", (e) => {
        console.log((e as CustomEvent).detail.arrGiftShow);
        /* render gift slider with arrGiftShow: GiftProduct[] */
        /* use bogosProcessAddGift when click add to cart from popup to process BOGOS */
    });
  3. Details of other event listeners

    • fg-gifts:updated
    document.addEventListener("fg-gifts:updated", (e) => {
        /* use this function to re-render cart with disableReloadCartUpdated: true */
        console.log((e as CustomEvent).detail);
        /* render gift slider with detail: { 
            is_auto?: boolean,
            popup?: gift can be shown 
            add?: gift can be added to cart
            update?: gift already in cart need to update
        } */
    });
    • fg-cart:auto-updated
    document.addEventListener("fg-gifts:updated", (e) => {
        /* use this function to re-render cart with disableReloadCartUpdated: true when gifts are auto updated (add/remove) */
        console.log((e as CustomEvent).detail);
        /* detail: { 
            popup?: gift can be shown 
            add?: gift can be added to cart
            update?: gift already in cart need to update
        } */
    });
    document.addEventListener("fg-gifts:added", (e) => {
        /* use this function to re-render cart with disableReloadCartUpdated: true */
        console.log((e as CustomEvent).detail);
        /* render gift slider with detail: { 
            is_auto?: boolean,
            gift?: {
                variant_id,
                quantity
            } gift added from popup
        } */
    });
  4. Some features is not available on this version yet

    • Stop the offer when the gift is out of stock
    • Draft-Order API

Notice

Publish gift/cloned product to Headless channel (or other channels you want BOGOS package to work with)

  • After creating/editing offer, please make sure that the gift/cloned product is available on Headless channel in order for the offer to work.

Support

BOGOS: Free Gift - support@secomapp.com

OR

You can contact our live-chat supporters in app on Shopify Admin.

0.1.0

3 months ago

0.0.10

5 months ago

0.0.9

5 months ago

0.0.8

6 months ago

0.0.7

6 months ago

0.0.6

6 months ago

0.0.5

6 months ago

0.0.4

7 months ago

0.0.3

7 months ago

0.0.2

7 months ago

0.0.1

7 months ago