Add : discount api fetching

This commit is contained in:
Wijayaac 2024-03-28 10:53:35 +07:00
parent 11b8711fca
commit de958dcdf3
10 changed files with 60 additions and 33 deletions

View File

@ -4,7 +4,7 @@ import { GridTileImage } from './grid/tile';
export async function Carousel() {
// Collections that start with `hidden-*` are hidden from the search page.
const products = await getCollectionProducts({ collection: 'boxes' });
const products = await getCollectionProducts({ collection: 'all' });
if (!products?.length) return null;

View File

@ -1,7 +1,15 @@
'use server';
import { TAGS } from 'lib/constants';
import { addToCart, createCart, getCart, removeFromCart, updateCart } from 'lib/shopify';
import {
addToCart,
createCart,
getCart,
getDiscountMetaobjects,
removeFromCart,
updateCart
} from 'lib/shopify';
import { formatDiscounts } from 'lib/utils';
import { revalidateTag } from 'next/cache';
import { cookies } from 'next/headers';
@ -83,22 +91,13 @@ export async function updateItemQuantity(
}
export async function calculateDiscounts(cart: any) {
const discountGroups = [
{
name: 'Tier 2',
discount: {
amount: 0.1,
minimumSpent: 150
const metaobjects = await getDiscountMetaobjects('dynamic_discount');
const discountGroups = formatDiscounts(metaobjects);
if (discountGroups === undefined) {
return;
}
},
{
name: 'Tier 1',
discount: {
amount: 0.05,
minimumSpent: 120
}
}
];
const subTotal = cart?.cost.subtotalAmount.amount;
const currencyCode = cart?.cost.subtotalAmount.currencyCode;
@ -122,12 +121,15 @@ export async function calculateDiscounts(cart: any) {
: 0;
const nextDiscount = closestNextTier?.discount.amount;
const discountAmount = finalDiscount ? finalDiscount * 100 : 0;
// get discount code from the final discount group
const discountCode = eligibleDiscount.length ? eligibleDiscount[0]?.code : '';
return {
discountAmount,
spentToNextDiscount,
nextDiscount,
discountGroups: discountGroupsSorted,
discountCode,
minSpent,
subTotal,
currencyCode

View File

@ -182,7 +182,7 @@ export default function CartModal({
</div>
</div>
<a
href={cart.checkoutUrl}
href={`${cart.checkoutUrl}&discount=${tieredDiscount?.discountCode || ''}`}
className="block w-full rounded-full bg-blue-600 p-3 text-center text-sm font-medium text-white opacity-90 hover:opacity-100"
>
Proceed to Checkout

View File

@ -40,7 +40,7 @@ function ThreeItemGridItem({
export async function ThreeItemGrid() {
// Collections that start with `hidden-*` are hidden from the search page.
const homepageItems = await getCollectionProducts({
collection: 'sale'
collection: 'all'
});
if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null;

View File

@ -1,9 +1,9 @@
import Link from 'next/link';
import FooterMenu from 'components/layout/footer-menu';
import LogoSquare from 'components/logo-square';
import { getMenu } from 'lib/shopify';
import { Suspense } from 'react';
import FooterMenu from './footer-menu';
const { COMPANY_NAME, SITE_NAME } = process.env;
@ -16,9 +16,9 @@ export default async function Footer() {
return (
<footer className="text-sm text-neutral-500 dark:text-neutral-400">
<div className="mx-auto flex w-full max-w-7xl flex-col gap-6 border-t border-neutral-200 px-6 py-12 text-sm dark:border-neutral-700 md:flex-row md:gap-12 md:px-4 min-[1320px]:px-0">
<div className="mx-auto flex w-full max-w-7xl flex-col gap-6 border-t border-neutral-200 px-6 py-12 text-sm md:flex-row md:gap-12 md:px-4 min-[1320px]:px-0 dark:border-neutral-700">
<div>
<Link className="flex items-center gap-2 text-black dark:text-white md:pt-1" href="/">
<Link className="flex items-center gap-2 text-black md:pt-1 dark:text-white" href="/">
<LogoSquare size="sm" />
<span className="uppercase">{SITE_NAME}</span>
</Link>

View File

@ -10,7 +10,7 @@ import Search from './search';
const { SITE_NAME } = process.env;
export default async function Navbar() {
const menu = await getMenu('next-js-frontend-header-menu');
const menu = await getMenu('main-menu');
return (
<nav className="relative flex items-center justify-between p-4 lg:px-6">

View File

@ -451,11 +451,13 @@ export async function revalidate(req: NextRequest): Promise<NextResponse> {
return NextResponse.json({ status: 200, revalidated: true, now: Date.now() });
}
export async function getDiscountMetaobjects() {
export async function getDiscountMetaobjects(type: string) {
const res = await shopifyFetch<ShopifyDiscountMetaobjectsOperation>({
query: getDiscountMetaobjectsQuery,
cache: 'no-store'
cache: 'no-store',
tags: ['metaobjects'],
variables: { type }
});
return res.body.data.metaobjects;
return removeEdgesAndNodes(res.body.data.metaobjects);
}

View File

@ -3,10 +3,12 @@ import discountMetaobject from '../fragments/discount-metaobject';
export const getDiscountMetaobjectsQuery = /* GraphQL */ `
query getDiscountMetaobjects {
metaobjects(type: "dynamic_discount", first: 10) {
nodes {
edges {
node {
...metaobject
}
}
}
}
${discountMetaobject}
`;

View File

@ -61,7 +61,7 @@ export type Page = {
updatedAt: string;
};
type Field = {
export type Field = {
key: string;
value: string;
};
@ -282,8 +282,6 @@ export type ShopifyDiscountMetaobjectsOperation = {
metaobjects: Connection<DiscountMetaobject>;
};
variables: {
query?: string;
reverse?: boolean;
sortKey?: string;
type: string;
};
};

View File

@ -1,4 +1,5 @@
import { ReadonlyURLSearchParams } from 'next/navigation';
import { DiscountMetaobject, Field } from './shopify/types';
export const createUrl = (pathname: string, params: URLSearchParams | ReadonlyURLSearchParams) => {
const paramsString = params.toString();
@ -37,3 +38,25 @@ export const validateEnvironmentVariables = () => {
);
}
};
export const formatDiscounts = (data: DiscountMetaobject[]) => {
const formattedData = data.map((item) => {
const fields = item.fields.reduce(
(acc, field: Field) => {
acc[field.key as string] = field.value;
return acc;
},
{} as Record<string, any>
);
return {
name: fields.name,
code: fields.discount_code,
discount: {
amount: parseFloat(fields.amount) / 100,
minimumSpent: parseFloat(fields.minimum_spent)
}
};
});
return formattedData;
};