UNPKG

@coursebuilder/commerce-next

Version:

Commerce Functionality for Course Builder with Next.js

58 lines (57 loc) 3.29 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { usePathname } from 'next/navigation.js'; import { useQuery } from '@tanstack/react-query'; import { z } from 'zod'; import { buildStripeCheckoutPath } from '@coursebuilder/core/pricing/build-stripe-checkout-path'; import { PriceDisplay } from '../pricing/price-display'; import { useDebounce } from '../utils/use-debounce'; const buyMoreSeatsSchema = z.object({ productId: z.string(), userId: z.string(), buttonLabel: z.string().default('Buy').nullish(), className: z.string().optional(), }); export const BuyMoreSeats = ({ productId, userId, buttonLabel = 'Buy', className = '', }) => { const [quantity, setQuantity] = React.useState(5); const debouncedQuantity = useDebounce(quantity, 250); const pathname = usePathname(); const cancelUrl = process.env.NEXT_PUBLIC_URL + pathname; const { data: formattedPrice, status } = useQuery({ queryKey: ['prices-formatted', productId, debouncedQuantity], queryFn: async () => { return await fetch(`${process.env.NEXT_PUBLIC_URL}/api/coursebuilder/prices-formatted`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ productId, quantity: debouncedQuantity, }), }).then(async (res) => { return (await res.json()); }); }, }); return (_jsx("form", { "data-buy-more-seats-form": "", action: buildStripeCheckoutPath({ userId, quantity: debouncedQuantity, productId, bulk: Boolean(formattedPrice?.bulk), couponId: formattedPrice?.appliedMerchantCoupon?.id, cancelUrl, }), method: "POST", className: className, children: _jsxs("fieldset", { id: "team-upgrade-pricing-inline", children: [_jsxs("div", { "data-seats-form": "", children: [_jsx("label", { children: "Seats" }), _jsx("button", { type: "button", "aria-label": "decrease seat quantity by one", onClick: () => { if (quantity === 1) return; setQuantity(quantity - 1); }, children: "-" }), _jsx("input", { value: quantity, required: true, type: "number", min: 1, max: 100, step: 1, onChange: (e) => { const newQuantity = Number(e.target.value); setQuantity(newQuantity); } }), _jsx("button", { type: "button", "aria-label": "increase seat quantity by one", onClick: () => { if (quantity === 100) return; setQuantity(quantity + 1); }, children: "+" })] }), _jsx("div", { "data-pricing-product": "", children: _jsxs("div", { "data-pricing-product-header": "", children: [_jsx(PriceDisplay, { status: status, formattedPrice: formattedPrice }), _jsx("button", { type: "submit", disabled: status !== 'success', children: buttonLabel })] }) })] }) })); };