mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 23:46:58 +00:00
Add : discount api fetching
This commit is contained in:
parent
11b8711fca
commit
de958dcdf3
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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}
|
||||
`;
|
||||
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
23
lib/utils.ts
23
lib/utils.ts
@ -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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user