UNPKG

@coursebuilder/commerce-next

Version:

Commerce Functionality for Course Builder with Next.js

47 lines (46 loc) 4.04 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import React from 'react'; import { ClockIcon } from 'lucide-react'; import pluralize from 'pluralize'; import Countdown from 'react-countdown'; const SaleCountdown = ({ coupon, size = 'lg', ...rest }) => { // storing coupon in state so that it doesn't rerender // and cause layout shift when quantity changes const [storedCoupon, setStoredCoupon] = React.useState(coupon); const [mounted, setMounted] = React.useState(false); React.useEffect(() => { setMounted(true); }, []); React.useEffect(() => { coupon && setStoredCoupon(coupon); }, [coupon]); if (!storedCoupon?.expires) return null; return mounted ? (_jsx(Countdown, { date: storedCoupon.expires, renderer: (props) => size === 'sm' ? (_jsx(CountdownRendererSm, { ...props, ...rest })) : (_jsx(CountdownRendererLg, { ...props, ...rest })) })) : null; }; export default SaleCountdown; const CountdownRendererLg = ({ days, hours, minutes, seconds, completed, ...rest }) => { const [srValues] = React.useState({ days, hours, minutes, seconds, }); const screenReaderValues = `${srValues.days} days, ${srValues.hours} hours, ${srValues.minutes} minutes, and ${srValues.seconds} seconds`; return completed ? null : (_jsx(_Fragment, { children: _jsx("div", { className: "w-full px-10 pb-7", ...rest, children: _jsxs("div", { className: "w-full rounded-lg text-center", children: [_jsx("p", { className: "pb-5 font-medium", children: "Hurry! Price goes up in:" }), _jsxs("div", { "aria-hidden": "true", "data-grid": "", className: "mx-auto grid max-w-[300px] grid-cols-4 items-center justify-center gap-2 tabular-nums tracking-tight", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("span", { "data-number": "days", className: "text-3xl font-medium leading-none", children: days }), _jsx("span", { "data-label": "days", className: "pt-1 text-xs font-medium uppercase tracking-wide text-gray-500", children: "days" })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { "data-number": "hours", className: "text-3xl font-medium leading-none", children: hours }), _jsx("span", { "data-label": "hours", className: "pt-1 text-xs font-medium uppercase tracking-wide text-gray-500", children: "hours" })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { "data-number": "minutes", className: "text-3xl font-medium leading-none", children: minutes }), _jsx("span", { "data-label": "minutes", className: "pt-1 text-xs font-medium uppercase tracking-wide text-gray-500", children: "minutes" })] }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { "data-number": "seconds", className: "text-3xl font-medium leading-none", children: seconds }), _jsx("span", { "data-label": "seconds", className: "pt-1 text-xs font-medium uppercase tracking-wide text-gray-500", children: "seconds" })] })] }), _jsx("div", { className: "sr-only", children: screenReaderValues })] }) }) })); }; const CountdownRendererSm = ({ days, hours, minutes, seconds, completed, ...rest }) => { const [srValues] = React.useState({ days, hours, minutes, seconds, }); return completed ? null : (_jsx(_Fragment, { children: _jsx("div", { className: "w-full px-10 pb-7", ...rest, children: _jsx("div", { className: "w-full rounded-lg text-center", children: _jsxs("p", { className: "flex items-center gap-1", children: [_jsx(ClockIcon, { className: "w-5" }), ' ', days > 0 ? `${days} ${pluralize('day', days)}` : hours > 0 ? `${hours} ${pluralize('hour', hours)}` : minutes > 0 ? `${minutes} ${pluralize('minute', minutes)}` : `${seconds} ${pluralize('second', seconds)}`, ' ', "left at this price!"] }) }) }) })); };