'use server'; import { loadCurrentUserAccount } from '@/app/home/(user)/_lib/server/load-user-account'; import { MontonioOrderHandlerService } from '@/packages/billing/montonio/src'; import { addToCart, deleteLineItem, retrieveCart } from '@lib/data/cart'; import { getCartId } from '@lib/data/cookies'; import { StoreCartLineItem, StoreProductVariant } from '@medusajs/types'; import { z } from 'zod'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { requireUserInServerComponent } from '../server/require-user-in-server-component'; const env = () => z .object({ medusaBackendPublicUrl: z .string({ error: 'MEDUSA_BACKEND_PUBLIC_URL is required', }) .min(1), siteUrl: z .string({ error: 'NEXT_PUBLIC_SITE_URL is required', }) .min(1), }) .parse({ medusaBackendPublicUrl: process.env.MEDUSA_BACKEND_PUBLIC_URL!, siteUrl: process.env.NEXT_PUBLIC_SITE_URL!, }); export async function handleAddToCart({ selectedVariant, countryCode, }: { selectedVariant: Pick; countryCode: string; }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount(); if (!account) { throw new Error('Account not found'); } const quantity = 1; const cart = await addToCart({ variantId: selectedVariant.id, quantity, countryCode, }); const { error } = await supabase.schema('audit').from('cart_entries').insert({ variant_id: selectedVariant.id, operation: 'ADD_TO_CART', account_id: account.id, cart_id: cart.id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } return cart; } export async function handleDeleteCartItem({ lineId }: { lineId: string }) { await deleteLineItem(lineId); const supabase = getSupabaseServerClient(); const cartId = await getCartId(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount(); if (!account) { throw new Error('Account not found'); } const { error } = await supabase.schema('audit').from('cart_entries').insert({ variant_id: lineId, operation: 'REMOVE_FROM_CART', account_id: account.id, cart_id: cartId!, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } } export async function handleNavigateToPayment({ language, paymentSessionId, }: { language: string; paymentSessionId: string; }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount(); if (!account) { throw new Error('Account not found'); } const cart = await retrieveCart(); if (!cart) { throw new Error('No cart found'); } const paymentLink = await new MontonioOrderHandlerService().getMontonioPaymentLink({ notificationUrl: `${env().medusaBackendPublicUrl}/hooks/payment/montonio_montonio`, returnUrl: `${env().siteUrl}/home/cart/montonio-callback`, amount: cart.total, currency: cart.currency_code.toUpperCase(), description: `Order from Medreport`, locale: language, merchantReference: `${account.id}:${paymentSessionId}:${cart.id}`, }); const { error } = await supabase.schema('audit').from('cart_entries').insert({ operation: 'NAVIGATE_TO_PAYMENT', account_id: account.id, cart_id: cart.id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } return paymentLink; } export async function handleLineItemTimeout({ lineItem, }: { lineItem: StoreCartLineItem; }) { const supabase = getSupabaseServerClient(); const user = await requireUserInServerComponent(); const account = await loadCurrentUserAccount(); if (!account) { throw new Error('Account not found'); } await deleteLineItem(lineItem.id); const { error } = await supabase.schema('audit').from('cart_entries').insert({ operation: 'LINE_ITEM_TIMEOUT', account_id: account.id, cart_id: lineItem.cart_id, changed_by: user.id, }); if (error) { throw new Error('Error logging cart entry: ' + error.message); } }