mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
@@ -390,6 +390,7 @@ export async function isLoggedIn(request: NextRequest, origin: string) {
|
||||
}
|
||||
|
||||
newHeaders.set('x-shop-customer-token', `${customerTokenValue}`);
|
||||
console.log('Customer Token', customerTokenValue);
|
||||
return NextResponse.next({
|
||||
request: {
|
||||
// New request headers
|
||||
|
17
lib/shopify/fragments/address.ts
Normal file
17
lib/shopify/fragments/address.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
const addressFragment = /* GraphQL */ `
|
||||
fragment Address on CustomerAddress {
|
||||
id
|
||||
address1
|
||||
address2
|
||||
firstName
|
||||
lastName
|
||||
provinceCode: zoneCode
|
||||
city
|
||||
zip
|
||||
countryCodeV2: territoryCode
|
||||
company
|
||||
phone: phoneNumber
|
||||
}
|
||||
`;
|
||||
|
||||
export default addressFragment;
|
0
lib/shopify/fragments/order-card.ts
Normal file
0
lib/shopify/fragments/order-card.ts
Normal file
56
lib/shopify/fragments/order-metafields.ts
Normal file
56
lib/shopify/fragments/order-metafields.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
const orderMetafieldsFragment = /* GraphQL */ `
|
||||
fragment OrderMetafields on Order {
|
||||
warrantyStatus: metafield(namespace: "custom", key: "warranty_status") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationDeadline: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_deadline"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationOdometer: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_odometer"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationInstallation: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_installation"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationSelfInstall: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_self_install"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationVIN: metafield(namespace: "custom", key: "warranty_activation_vin") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationMileage: metafield(namespace: "custom", key: "warranty_activation_mileage") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
orderConfirmation: metafield(namespace: "custom", key: "customer_confirmation") {
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default orderMetafieldsFragment;
|
38
lib/shopify/fragments/order-transaction.ts
Normal file
38
lib/shopify/fragments/order-transaction.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
const orderTransactionFragment = /* GraphQL */ `
|
||||
fragment OrderTransaction on OrderTransaction {
|
||||
id
|
||||
processedAt
|
||||
paymentIcon {
|
||||
id
|
||||
url
|
||||
altText
|
||||
}
|
||||
paymentDetails {
|
||||
... on CardPaymentDetails {
|
||||
last4
|
||||
cardBrand
|
||||
}
|
||||
}
|
||||
transactionAmount {
|
||||
presentmentMoney {
|
||||
...Price
|
||||
}
|
||||
}
|
||||
giftCardDetails {
|
||||
last4
|
||||
balance {
|
||||
...Price
|
||||
}
|
||||
}
|
||||
status
|
||||
kind
|
||||
transactionParentId
|
||||
type
|
||||
typeDetails {
|
||||
name
|
||||
message
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default orderTransactionFragment;
|
@@ -1,4 +1,8 @@
|
||||
import addressFragment from './address';
|
||||
import lineItemFragment from './line-item';
|
||||
import orderMetafieldsFragment from './order-metafields';
|
||||
import orderTrasactionFragment from './order-transaction';
|
||||
import priceFragment from './price';
|
||||
|
||||
const orderCard = /* GraphQL */ `
|
||||
fragment OrderCard on Order {
|
||||
@@ -16,69 +20,44 @@ const orderCard = /* GraphQL */ `
|
||||
}
|
||||
}
|
||||
totalPrice {
|
||||
amount
|
||||
currencyCode
|
||||
...Price
|
||||
}
|
||||
subtotal {
|
||||
...Price
|
||||
}
|
||||
totalShipping {
|
||||
...Price
|
||||
}
|
||||
totalTax {
|
||||
...Price
|
||||
}
|
||||
shippingLine {
|
||||
title
|
||||
originalPrice {
|
||||
...Price
|
||||
}
|
||||
}
|
||||
lineItems(first: 20) {
|
||||
nodes {
|
||||
...LineItem
|
||||
}
|
||||
}
|
||||
shippingAddress {
|
||||
...Address
|
||||
}
|
||||
billingAddress {
|
||||
...Address
|
||||
}
|
||||
transactions {
|
||||
...OrderTransaction
|
||||
}
|
||||
...OrderMetafields
|
||||
}
|
||||
${lineItemFragment}
|
||||
`;
|
||||
|
||||
export const orderMetafields = /* GraphQL */ `
|
||||
fragment OrderMetafield on Order {
|
||||
id
|
||||
warrantyStatus: metafield(namespace: "custom", key: "warranty_status") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationDeadline: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_deadline"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationOdometer: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_odometer"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationInstallation: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_installation"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationSelfInstall: metafield(
|
||||
namespace: "custom"
|
||||
key: "warranty_activation_self_install"
|
||||
) {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationVIN: metafield(namespace: "custom", key: "warranty_activation_vin") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
warrantyActivationMileage: metafield(namespace: "custom", key: "warranty_activation_mileage") {
|
||||
value
|
||||
id
|
||||
key
|
||||
}
|
||||
}
|
||||
${addressFragment}
|
||||
${priceFragment}
|
||||
${orderTrasactionFragment}
|
||||
${orderMetafieldsFragment}
|
||||
`;
|
||||
|
||||
export default orderCard;
|
||||
|
8
lib/shopify/fragments/price.ts
Normal file
8
lib/shopify/fragments/price.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
const priceFragment = /* GraphQL */ `
|
||||
fragment Price on MoneyV2 {
|
||||
amount
|
||||
currencyCode
|
||||
}
|
||||
`;
|
||||
|
||||
export default priceFragment;
|
@@ -38,8 +38,7 @@ import { getCustomerQuery } from './queries/customer';
|
||||
import { getMenuQuery } from './queries/menu';
|
||||
import { getMetaobjectQuery, getMetaobjectsQuery } from './queries/metaobject';
|
||||
import { getFileQuery, getImageQuery, getMetaobjectsByIdsQuery } from './queries/node';
|
||||
import { getCustomerOrderQuery, getOrderMetafieldsQuery } from './queries/order';
|
||||
import { getCustomerOrderMetafieldsQuery, getCustomerOrdersQuery } from './queries/orders';
|
||||
import { getCustomerOrdersQuery } from './queries/orders';
|
||||
import { getPageQuery, getPagesQuery } from './queries/page';
|
||||
import {
|
||||
getProductQuery,
|
||||
@@ -64,6 +63,7 @@ import {
|
||||
Metaobject,
|
||||
Money,
|
||||
Order,
|
||||
OrderConfirmationContent,
|
||||
Page,
|
||||
PageInfo,
|
||||
Product,
|
||||
@@ -86,10 +86,10 @@ import {
|
||||
ShopifyImageOperation,
|
||||
ShopifyMenuOperation,
|
||||
ShopifyMetaobject,
|
||||
ShopifyMetaobjectOperation,
|
||||
ShopifyMetaobjectsOperation,
|
||||
ShopifyMoneyV2,
|
||||
ShopifyOrder,
|
||||
ShopifyOrderMetafield,
|
||||
ShopifyPage,
|
||||
ShopifyPageOperation,
|
||||
ShopifyPagesOperation,
|
||||
@@ -109,6 +109,7 @@ import {
|
||||
UploadInput,
|
||||
WarrantyStatus
|
||||
} from './types';
|
||||
import getCustomerOrderQuery from './queries/order';
|
||||
|
||||
const domain = process.env.SHOPIFY_STORE_DOMAIN
|
||||
? ensureStartsWith(process.env.SHOPIFY_STORE_DOMAIN, 'https://')
|
||||
@@ -185,7 +186,7 @@ export async function shopifyFetch<T>({
|
||||
}
|
||||
}
|
||||
|
||||
async function adminFetch<T>({
|
||||
async function shopifyAdminFetch<T>({
|
||||
headers,
|
||||
query,
|
||||
variables,
|
||||
@@ -313,7 +314,7 @@ export async function shopifyCustomerFetch<T>({
|
||||
}
|
||||
}
|
||||
|
||||
const removeEdgesAndNodes = (array: Connection<any>) => {
|
||||
const removeEdgesAndNodes = <T = any>(array: Connection<T>) => {
|
||||
return array.edges.map((edge) => edge?.node);
|
||||
};
|
||||
|
||||
@@ -439,7 +440,7 @@ const reshapeImages = (images: Connection<Image>, productTitle: string) => {
|
||||
const flattened = removeEdgesAndNodes(images);
|
||||
|
||||
return flattened.map((image) => {
|
||||
const filename = image.url.match(/.*\/(.*)\..*/)[1];
|
||||
const filename = (image.url.match(/.*\/(.*)\..*/) || [])[1];
|
||||
return {
|
||||
...image,
|
||||
altText: image.altText || `${productTitle} - ${filename}`
|
||||
@@ -531,8 +532,7 @@ function reshapeOrders(orders: ShopifyOrder[]): any[] | Promise<Order[]> {
|
||||
}
|
||||
|
||||
function reshapeOrder(shopifyOrder: ShopifyOrder): Order {
|
||||
const reshapeAddress = (address?: ShopifyAddress): Address | undefined => {
|
||||
if (!address) return undefined;
|
||||
const reshapeAddress = (address: ShopifyAddress): Address => {
|
||||
return {
|
||||
address1: address.address1,
|
||||
address2: address.address2,
|
||||
@@ -547,8 +547,7 @@ function reshapeOrder(shopifyOrder: ShopifyOrder): Order {
|
||||
};
|
||||
};
|
||||
|
||||
const reshapeMoney = (money?: ShopifyMoneyV2): Money | undefined => {
|
||||
if (!money) return undefined;
|
||||
const reshapeMoney = (money: ShopifyMoneyV2): Money => {
|
||||
return {
|
||||
amount: money.amount || '0.00',
|
||||
currencyCode: money.currencyCode || 'USD'
|
||||
@@ -619,23 +618,38 @@ function reshapeOrder(shopifyOrder: ShopifyOrder): Order {
|
||||
totalShipping: reshapeMoney(shopifyOrder.totalShipping),
|
||||
totalTax: reshapeMoney(shopifyOrder.totalTax),
|
||||
totalPrice: reshapeMoney(shopifyOrder.totalPrice),
|
||||
createdAt: shopifyOrder.createdAt
|
||||
createdAt: shopifyOrder.createdAt,
|
||||
shippingMethod: {
|
||||
name: shopifyOrder.shippingLine?.title,
|
||||
price: reshapeMoney(shopifyOrder.shippingLine.originalPrice)!
|
||||
},
|
||||
warrantyActivationDeadline: shopifyOrder.warrantyActivationDeadline,
|
||||
warrantyStatus: shopifyOrder.warrantyStatus,
|
||||
warrantyActivationInstallation: shopifyOrder.warrantyActivationInstallation,
|
||||
warrantyActivationMileage: shopifyOrder.warrantyActivationMileage,
|
||||
warrantyActivationOdometer: shopifyOrder.warrantyActivationOdometer,
|
||||
warrantyActivationSelfInstall: shopifyOrder.warrantyActivationSelfInstall,
|
||||
warrantyActivationVIN: shopifyOrder.warrantyActivationVIN,
|
||||
orderConfirmation: shopifyOrder.orderConfirmation
|
||||
};
|
||||
|
||||
if (shopifyOrder.customer) {
|
||||
order.customer = reshapeCustomer(shopifyOrder.customer);
|
||||
}
|
||||
|
||||
if (shopifyOrder.shippingLine) {
|
||||
order.shippingMethod = {
|
||||
name: shopifyOrder.shippingLine?.title,
|
||||
price: reshapeMoney(shopifyOrder.shippingLine.originalPrice)!
|
||||
};
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
export function reshapeOrderConfirmationPdf(
|
||||
metaobject: ShopifyMetaobject
|
||||
): OrderConfirmationContent {
|
||||
return {
|
||||
body: metaobject.fields.find((field) => field.key === 'body')?.value || '',
|
||||
logo: metaobject.fields.find((field) => field.key === 'logo')?.reference.image!,
|
||||
color: metaobject.fields.find((field) => field.key === 'color')?.value || '#000000'
|
||||
};
|
||||
}
|
||||
|
||||
export async function createCart(): Promise<Cart> {
|
||||
const res = await shopifyFetch<ShopifyCreateCartOperation>({
|
||||
query: createCartMutation,
|
||||
@@ -874,6 +888,31 @@ export async function getMetaobjects(type: string) {
|
||||
return reshapeMetaobjects(removeEdgesAndNodes(res.body.data.metaobjects));
|
||||
}
|
||||
|
||||
export async function getAllMetaobjects(type: string) {
|
||||
const allMetaobjects: Metaobject[] = [];
|
||||
let hasNextPage = true;
|
||||
let after: string | undefined;
|
||||
|
||||
while (hasNextPage) {
|
||||
const res = await shopifyFetch<ShopifyMetaobjectsOperation>({
|
||||
query: getMetaobjectsQuery,
|
||||
tags: [TAGS.collections, TAGS.products],
|
||||
variables: { type, after }
|
||||
});
|
||||
|
||||
const metaobjects = reshapeMetaobjects(removeEdgesAndNodes(res.body.data.metaobjects));
|
||||
|
||||
for (const metaobject of metaobjects) {
|
||||
allMetaobjects.push(metaobject);
|
||||
}
|
||||
|
||||
hasNextPage = res.body.data.metaobjects.pageInfo?.hasNextPage || false;
|
||||
after = res.body.data.metaobjects.pageInfo?.endCursor;
|
||||
}
|
||||
|
||||
return allMetaobjects;
|
||||
}
|
||||
|
||||
export async function getMetaobjectsByIds(ids: string[]) {
|
||||
if (!ids.length) return [];
|
||||
|
||||
@@ -895,10 +934,7 @@ export async function getMetaobject({
|
||||
id?: string;
|
||||
handle?: { handle: string; type: string };
|
||||
}) {
|
||||
const res = await shopifyFetch<{
|
||||
data: { metaobject: ShopifyMetaobject };
|
||||
variables: { id?: string; handle?: { handle: string; type: string } };
|
||||
}>({
|
||||
const res = await shopifyFetch<ShopifyMetaobjectOperation>({
|
||||
query: getMetaobjectQuery,
|
||||
variables: { id, handle }
|
||||
});
|
||||
@@ -906,6 +942,15 @@ export async function getMetaobject({
|
||||
return res.body.data.metaobject ? reshapeMetaobjects([res.body.data.metaobject])[0] : null;
|
||||
}
|
||||
|
||||
export async function getOrderConfirmationContent(): Promise<OrderConfirmationContent> {
|
||||
const res = await shopifyFetch<ShopifyMetaobjectOperation>({
|
||||
query: getMetaobjectQuery,
|
||||
variables: { handle: { handle: 'order-confirmation-pdf', type: 'order_confirmation_pdf' } }
|
||||
});
|
||||
|
||||
return reshapeOrderConfirmationPdf(res.body.data.metaobject);
|
||||
}
|
||||
|
||||
export async function getPage(handle: string): Promise<Page> {
|
||||
const res = await shopifyFetch<ShopifyPageOperation>({
|
||||
query: getPageQuery,
|
||||
@@ -1064,7 +1109,7 @@ export const getImage = async (id: string): Promise<Image> => {
|
||||
};
|
||||
|
||||
export const stageUploadFile = async (params: UploadInput) => {
|
||||
const res = await adminFetch<ShopifyStagedUploadOperation>({
|
||||
const res = await shopifyAdminFetch<ShopifyStagedUploadOperation>({
|
||||
query: createStageUploads,
|
||||
variables: { input: [params] }
|
||||
});
|
||||
@@ -1080,7 +1125,7 @@ export const uploadFile = async ({ url, formData }: { url: string; formData: For
|
||||
};
|
||||
|
||||
export const createFile = async (params: FileCreateInput) => {
|
||||
const res = await adminFetch<ShopifyCreateFileOperation>({
|
||||
const res = await shopifyAdminFetch<ShopifyCreateFileOperation>({
|
||||
query: createFileMutation,
|
||||
variables: { files: [params] }
|
||||
});
|
||||
@@ -1103,7 +1148,7 @@ export const updateOrderMetafields = async ({
|
||||
validMetafields.find(({ key }) => (Array.isArray(field) ? field.includes(key) : key === field))
|
||||
);
|
||||
|
||||
const response = await adminFetch<ShopifyUpdateOrderMetafieldsOperation>({
|
||||
const response = await shopifyAdminFetch<ShopifyUpdateOrderMetafieldsOperation>({
|
||||
query: updateOrderMetafieldsMutation,
|
||||
variables: {
|
||||
input: {
|
||||
@@ -1125,59 +1170,6 @@ export const updateOrderMetafields = async ({
|
||||
return response.body.data.orderUpdate.order.id;
|
||||
};
|
||||
|
||||
export const getOrdersMetafields = async (): Promise<{ [key: string]: ShopifyOrderMetafield }> => {
|
||||
const customer = await getCustomer();
|
||||
const res = await adminFetch<{
|
||||
data: {
|
||||
customer: {
|
||||
orders: {
|
||||
nodes: Array<
|
||||
{
|
||||
id: string;
|
||||
} & ShopifyOrderMetafield
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
variables: {
|
||||
id: string;
|
||||
};
|
||||
}>({
|
||||
query: getCustomerOrderMetafieldsQuery,
|
||||
variables: { id: customer.id },
|
||||
tags: [TAGS.orderMetafields]
|
||||
});
|
||||
|
||||
return res.body.data.customer.orders.nodes.reduce(
|
||||
(acc, order) => ({
|
||||
...acc,
|
||||
[order.id]: order
|
||||
}),
|
||||
{} as { [key: string]: ShopifyOrderMetafield }
|
||||
);
|
||||
};
|
||||
|
||||
export const getOrderMetafields = async (orderId: string): Promise<ShopifyOrderMetafield> => {
|
||||
const res = await adminFetch<{
|
||||
data: {
|
||||
order: {
|
||||
id: string;
|
||||
} & ShopifyOrderMetafield;
|
||||
};
|
||||
variables: {
|
||||
id: string;
|
||||
};
|
||||
}>({
|
||||
query: getOrderMetafieldsQuery,
|
||||
variables: { id: `gid://shopify/Order/${orderId}` },
|
||||
tags: [TAGS.orderMetafields]
|
||||
});
|
||||
|
||||
const order = res.body.data.order;
|
||||
|
||||
return order;
|
||||
};
|
||||
|
||||
export const getFile = async (id: string) => {
|
||||
const res = await shopifyFetch<{
|
||||
data: {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
export const getMetaobjectsQuery = /* GraphQL */ `
|
||||
query getMetaobjects($type: String!) {
|
||||
metaobjects(type: $type, first: 200) {
|
||||
query getMetaobjects($type: String!, $after: String) {
|
||||
metaobjects(type: $type, first: 200, after: $after) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
@@ -16,6 +16,10 @@ export const getMetaobjectsQuery = /* GraphQL */ `
|
||||
}
|
||||
}
|
||||
}
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
endCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -30,6 +34,14 @@ export const getMetaobjectQuery = /* GraphQL */ `
|
||||
... on Metaobject {
|
||||
id
|
||||
}
|
||||
... on MediaImage {
|
||||
image {
|
||||
url
|
||||
altText
|
||||
height
|
||||
width
|
||||
}
|
||||
}
|
||||
}
|
||||
key
|
||||
value
|
||||
|
@@ -1,8 +1,11 @@
|
||||
import addressFragment from '../fragments/address';
|
||||
import lineItemFragment from '../fragments/line-item';
|
||||
import { orderMetafields } from '../fragments/order';
|
||||
import orderMetafieldsFragment from '../fragments/order-metafields';
|
||||
import orderTrasactionFragment from '../fragments/order-transaction';
|
||||
import priceFragment from '../fragments/price';
|
||||
|
||||
// NOTE: https://shopify.dev/docs/api/customer/latest/queries/customer
|
||||
export const getCustomerOrderQuery = /* GraphQL */ `
|
||||
const getCustomerOrderQuery = /* GraphQL */ `
|
||||
query getCustomerOrderQuery($orderId: ID!) {
|
||||
customer {
|
||||
emailAddress {
|
||||
@@ -95,60 +98,7 @@ export const getCustomerOrderQuery = /* GraphQL */ `
|
||||
...Price
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment OrderTransaction on OrderTransaction {
|
||||
id
|
||||
processedAt
|
||||
paymentIcon {
|
||||
id
|
||||
url
|
||||
altText
|
||||
}
|
||||
paymentDetails {
|
||||
... on CardPaymentDetails {
|
||||
last4
|
||||
cardBrand
|
||||
}
|
||||
}
|
||||
transactionAmount {
|
||||
presentmentMoney {
|
||||
...Price
|
||||
}
|
||||
}
|
||||
giftCardDetails {
|
||||
last4
|
||||
balance {
|
||||
...Price
|
||||
}
|
||||
}
|
||||
status
|
||||
kind
|
||||
transactionParentId
|
||||
type
|
||||
typeDetails {
|
||||
name
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
fragment Price on MoneyV2 {
|
||||
amount
|
||||
currencyCode
|
||||
}
|
||||
|
||||
fragment Address on CustomerAddress {
|
||||
id
|
||||
address1
|
||||
address2
|
||||
firstName
|
||||
lastName
|
||||
provinceCode: zoneCode
|
||||
city
|
||||
zip
|
||||
countryCodeV2: territoryCode
|
||||
company
|
||||
phone: phoneNumber
|
||||
...OrderMetafields
|
||||
}
|
||||
|
||||
fragment Fulfillment on Fulfillment {
|
||||
@@ -220,13 +170,10 @@ export const getCustomerOrderQuery = /* GraphQL */ `
|
||||
}
|
||||
}
|
||||
${lineItemFragment}
|
||||
${addressFragment}
|
||||
${priceFragment}
|
||||
${orderTrasactionFragment}
|
||||
${orderMetafieldsFragment}
|
||||
`;
|
||||
|
||||
export const getOrderMetafieldsQuery = /* GraphQL */ `
|
||||
query getOrderMetafields($id: ID!) {
|
||||
order(id: $id) {
|
||||
...OrderMetafield
|
||||
}
|
||||
}
|
||||
${orderMetafields}
|
||||
`;
|
||||
export default getCustomerOrderQuery;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import customerDetailsFragment from '../fragments/customer-details';
|
||||
import { orderMetafields } from '../fragments/order';
|
||||
|
||||
const customerFragment = `#graphql
|
||||
`;
|
||||
@@ -14,16 +13,3 @@ export const getCustomerOrdersQuery = `#graphql
|
||||
${customerFragment}
|
||||
${customerDetailsFragment}
|
||||
`;
|
||||
|
||||
export const getCustomerOrderMetafieldsQuery = /* GraphQL */ `
|
||||
query getCustomerOrderMetafields($id: ID!) {
|
||||
customer(id: $id) {
|
||||
orders(first: 20, sortKey: PROCESSED_AT, reverse: true) {
|
||||
nodes {
|
||||
...OrderMetafield
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${orderMetafields}
|
||||
`;
|
||||
|
@@ -3,6 +3,7 @@ export type Maybe<T> = T | null;
|
||||
|
||||
export type Connection<T> = {
|
||||
edges: Array<Edge<T>>;
|
||||
pageInfo?: PageInfo;
|
||||
};
|
||||
|
||||
export type Edge<T> = {
|
||||
@@ -141,18 +142,18 @@ export type Order = {
|
||||
fulfillments: Fulfillment[];
|
||||
transactions: Transaction[];
|
||||
lineItems: LineItem[];
|
||||
shippingAddress?: Address;
|
||||
billingAddress?: Address;
|
||||
shippingAddress: Address;
|
||||
billingAddress: Address;
|
||||
/** the price of all line items, excluding taxes and surcharges */
|
||||
subtotal?: Money;
|
||||
totalShipping?: Money;
|
||||
totalTax?: Money;
|
||||
totalPrice?: Money;
|
||||
shippingMethod?: {
|
||||
subtotal: Money;
|
||||
totalShipping: Money;
|
||||
totalTax: Money;
|
||||
totalPrice: Money;
|
||||
shippingMethod: {
|
||||
name: string;
|
||||
price: Money;
|
||||
};
|
||||
};
|
||||
} & ShopifyOrderMetafield;
|
||||
|
||||
export type ShopifyOrder = {
|
||||
id: string;
|
||||
@@ -181,7 +182,7 @@ export type ShopifyOrder = {
|
||||
requiresShipping: boolean;
|
||||
shippingLine: ShopifyShippingLine;
|
||||
note: string | null;
|
||||
};
|
||||
} & ShopifyOrderMetafield;
|
||||
|
||||
type ShopifyShippingLine = {
|
||||
title: string;
|
||||
@@ -372,16 +373,30 @@ export type ShopifyMetaobject = {
|
||||
value: string;
|
||||
reference: {
|
||||
id: string;
|
||||
image?: Image;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
|
||||
export type ShopifyMetafield = {
|
||||
id: string;
|
||||
namespace: string;
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type Metaobject = {
|
||||
id: string;
|
||||
type: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
export type OrderConfirmationContent = {
|
||||
logo: Image;
|
||||
body: string;
|
||||
color: string;
|
||||
};
|
||||
|
||||
export type TransmissionType = 'Automatic' | 'Manual';
|
||||
|
||||
export type Product = Omit<
|
||||
@@ -665,7 +680,7 @@ export type ShopifyImageOperation = {
|
||||
|
||||
export type ShopifyMetaobjectsOperation = {
|
||||
data: { metaobjects: Connection<ShopifyMetaobject> };
|
||||
variables: { type: string };
|
||||
variables: { type: string; after?: string };
|
||||
};
|
||||
|
||||
export type ShopifyPagesOperation = {
|
||||
@@ -675,8 +690,8 @@ export type ShopifyPagesOperation = {
|
||||
};
|
||||
|
||||
export type ShopifyMetaobjectOperation = {
|
||||
data: { nodes: ShopifyMetaobject[] };
|
||||
variables: { ids: string[] };
|
||||
data: { metaobject: ShopifyMetaobject };
|
||||
variables: { id?: string; handle?: { handle: string; type: string } };
|
||||
};
|
||||
|
||||
export type ShopifyProductOperation = {
|
||||
@@ -858,20 +873,15 @@ export enum WarrantyStatus {
|
||||
LimitedActivated = 'Limited Activation'
|
||||
}
|
||||
|
||||
export type OrderMetafieldValue<T = string> = {
|
||||
value: T;
|
||||
id: string;
|
||||
key: string;
|
||||
};
|
||||
|
||||
export type ShopifyOrderMetafield = {
|
||||
warrantyStatus: OrderMetafieldValue | null;
|
||||
warrantyActivationDeadline: OrderMetafieldValue | null;
|
||||
warrantyActivationOdometer: OrderMetafieldValue | null;
|
||||
warrantyActivationInstallation: OrderMetafieldValue | null;
|
||||
warrantyActivationSelfInstall: OrderMetafieldValue | null;
|
||||
warrantyActivationVIN: OrderMetafieldValue | null;
|
||||
warrantyActivationMileage: OrderMetafieldValue | null;
|
||||
orderConfirmation: ShopifyMetafield | null;
|
||||
warrantyStatus: ShopifyMetafield | null;
|
||||
warrantyActivationDeadline: ShopifyMetafield | null;
|
||||
warrantyActivationOdometer: ShopifyMetafield | null;
|
||||
warrantyActivationInstallation: ShopifyMetafield | null;
|
||||
warrantyActivationSelfInstall: ShopifyMetafield | null;
|
||||
warrantyActivationVIN: ShopifyMetafield | null;
|
||||
warrantyActivationMileage: ShopifyMetafield | null;
|
||||
};
|
||||
|
||||
export type File = {
|
||||
|
@@ -5,7 +5,7 @@ export const carPartPlanetColor = {
|
||||
muted: '#E6CCB7'
|
||||
},
|
||||
content: {
|
||||
subtle: '#9ca3af', // gray-400
|
||||
subtle: '#d1d5db', // gray-300
|
||||
DEFAULT: '#6b7280', // gray-500
|
||||
emphasis: '#374151', // gray-700
|
||||
strong: '#111827', // gray-900
|
||||
|
28
lib/utils.ts
28
lib/utils.ts
@@ -3,6 +3,34 @@ import { ReadonlyURLSearchParams } from 'next/navigation';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { Menu } from './shopify/types';
|
||||
|
||||
export function cx(...args: ClassValue[]) {
|
||||
return twMerge(clsx(...args));
|
||||
}
|
||||
export const focusInput = [
|
||||
// base
|
||||
'focus:ring-2',
|
||||
// ring color
|
||||
'focus:ring-blue-200 focus:dark:ring-blue-700/30',
|
||||
// border color
|
||||
'focus:border-blue-500 focus:dark:border-blue-700'
|
||||
];
|
||||
|
||||
export const hasErrorInput = [
|
||||
// base
|
||||
'ring-2',
|
||||
// border color
|
||||
'border-red-500 dark:border-red-700',
|
||||
// ring color
|
||||
'ring-red-200 dark:ring-red-700/30'
|
||||
];
|
||||
|
||||
export const focusRing = [
|
||||
// base
|
||||
'outline outline-offset-2 outline-0 focus-visible:outline-2',
|
||||
// outline color
|
||||
'outline-blue-500 dark:outline-blue-500'
|
||||
];
|
||||
|
||||
export const createUrl = (pathname: string, params: URLSearchParams | ReadonlyURLSearchParams) => {
|
||||
const paramsString = params.toString();
|
||||
const queryString = `${paramsString.length ? '?' : ''}${paramsString}`;
|
||||
|
Reference in New Issue
Block a user