import { toast } from "sonner"; // Shopify API Configuration const SHOPIFY_API_VERSION = '2025-07'; const SHOPIFY_STORE_PERMANENT_DOMAIN = 'sweet-office-treats-2ar62.myshopify.com'; const SHOPIFY_STOREFRONT_URL = `https://${SHOPIFY_STORE_PERMANENT_DOMAIN}/api/${SHOPIFY_API_VERSION}/graphql.json`; const SHOPIFY_STOREFRONT_TOKEN = 'd9c2c43fc30d96d1742cc76da58c4ddb'; export interface ShopifyProduct { node: { id: string; title: string; description: string; handle: string; priceRange: { minVariantPrice: { amount: string; currencyCode: string; }; }; images: { edges: Array<{ node: { url: string; altText: string | null; }; }>; }; variants: { edges: Array<{ node: { id: string; title: string; price: { amount: string; currencyCode: string; }; availableForSale: boolean; selectedOptions: Array<{ name: string; value: string; }>; }; }>; }; sellingPlanGroups?: { edges: Array<{ node: { name: string; sellingPlans: { edges: Array<{ node: { id: string; name: string; }; }>; }; }; }>; }; options: Array<{ name: string; values: string[]; }>; }; } // Storefront API helper function export async function storefrontApiRequest(query: string, variables: Record = {}) { const response = await fetch(SHOPIFY_STOREFRONT_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': SHOPIFY_STOREFRONT_TOKEN }, body: JSON.stringify({ query, variables, }), }); if (response.status === 402) { toast.error("Shopify: Betalning krävs", { description: "Shopify API kräver en aktiv betalplan. Besök admin.shopify.com för att uppgradera.", }); return null; } if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); if (data.errors) { throw new Error(`Error calling Shopify: ${data.errors.map((e: { message: string }) => e.message).join(', ')}`); } return data; } // Fetch products query export const STOREFRONT_PRODUCTS_QUERY = ` query GetProducts($first: Int!, $query: String) { products(first: $first, query: $query) { edges { node { id title description handle priceRange { minVariantPrice { amount currencyCode } } images(first: 5) { edges { node { url altText } } } variants(first: 10) { edges { node { id title price { amount currencyCode } availableForSale selectedOptions { name value } } } } sellingPlanGroups(first: 5) { edges { node { name sellingPlans(first: 10) { edges { node { id name } } } } } } options { name values } } } } } `; // Cart mutations export const CART_QUERY = ` query cart($id: ID!) { cart(id: $id) { id totalQuantity checkoutUrl lines(first: 100) { edges { node { id quantity merchandise { ... on ProductVariant { id title price { amount currencyCode } } } } } } } } `; export const CART_CREATE_MUTATION = ` mutation cartCreate($input: CartInput!) { cartCreate(input: $input) { cart { id checkoutUrl lines(first: 100) { edges { node { id merchandise { ... on ProductVariant { id } } } } } } userErrors { field message } } } `; export const CART_LINES_ADD_MUTATION = ` mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) { cartLinesAdd(cartId: $cartId, lines: $lines) { cart { id lines(first: 100) { edges { node { id merchandise { ... on ProductVariant { id } } } } } } userErrors { field message } } } `; export const CART_LINES_UPDATE_MUTATION = ` mutation cartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) { cartLinesUpdate(cartId: $cartId, lines: $lines) { cart { id } userErrors { field message } } } `; export const CART_LINES_REMOVE_MUTATION = ` mutation cartLinesRemove($cartId: ID!, $lineIds: [ID!]!) { cartLinesRemove(cartId: $cartId, lineIds: $lineIds) { cart { id } userErrors { field message } } } `; export function formatCheckoutUrl(checkoutUrl: string): string { try { const url = new URL(checkoutUrl); url.searchParams.set('channel', 'online_store'); return url.toString(); } catch { return checkoutUrl; } } export function isCartNotFoundError(userErrors: Array<{ field: string[] | null; message: string }>): boolean { return userErrors.some(e => e.message.toLowerCase().includes('cart not found') || e.message.toLowerCase().includes('does not exist') ); }