diff --git a/src/components/bitcoinConnect/CoursePaymentButton.js b/src/components/bitcoinConnect/CoursePaymentButton.js index a8040d3..f20754c 100644 --- a/src/components/bitcoinConnect/CoursePaymentButton.js +++ b/src/components/bitcoinConnect/CoursePaymentButton.js @@ -10,12 +10,15 @@ import axios from 'axios'; import GenericButton from '@/components/buttons/GenericButton'; import { useRouter } from 'next/router'; import useWindowWidth from '@/hooks/useWindowWidth'; +import { InputText } from 'primereact/inputtext'; const Payment = dynamic( () => import('@getalby/bitcoin-connect-react').then((mod) => mod.Payment), { ssr: false } ); +const DISCOUNT_CODE = process.env.NEXT_PUBLIC_DISCOUNT_CODE; + const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId }) => { const [invoice, setInvoice] = useState(null); const [isLoading, setIsLoading] = useState(false); @@ -25,6 +28,9 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId } const router = useRouter(); const windowWidth = useWindowWidth(); const isMobile = windowWidth < 768; + const [discountCode, setDiscountCode] = useState(''); + const [discountApplied, setDiscountApplied] = useState(false); + const [showDiscountInput, setShowDiscountInput] = useState(false); useEffect(() => { let intervalId; @@ -49,12 +55,21 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId } }; }, [invoice]); + const calculateDiscount = (originalAmount) => { + if (discountCode === DISCOUNT_CODE) { + const discountedAmount = 21000; + const savedPercentage = Math.round(((originalAmount - discountedAmount) / originalAmount) * 100); + return { discountedAmount, savedPercentage }; + } + return { discountedAmount: originalAmount, savedPercentage: 0 }; + }; + const fetchInvoice = async () => { setIsLoading(true); try { const ln = new LightningAddress(lnAddress); await ln.fetch(); - const invoice = await ln.requestInvoice({ satoshi: amount }); + const invoice = await ln.requestInvoice({ satoshi: discountApplied ? calculateDiscount(amount).discountedAmount : amount }); setInvoice(invoice); setDialogVisible(true); } catch (error) { @@ -70,7 +85,7 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId } const purchaseData = { userId: session.user.id, courseId: courseId, - amountPaid: parseInt(amount, 10) + amountPaid: discountApplied ? calculateDiscount(amount).discountedAmount : parseInt(amount, 10) }; const result = await axios.post('/api/purchase/course', purchaseData); @@ -90,9 +105,56 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId } }; return ( - <> +
+ {!showDiscountInput ? ( + + ) : ( +
+
+
+ { + setDiscountCode(e.target.value); + setDiscountApplied(e.target.value === DISCOUNT_CODE); + }} + placeholder="Enter discount code" + className="text-sm w-full p-2" + /> + +
+ {discountApplied && ( + + + {calculateDiscount(amount).savedPercentage}% off! + + )} +
+ {discountApplied && ( +
+ {amount} sats + → {calculateDiscount(amount).discountedAmount} sats +
+ )} +
+ )} { if (status === 'unauthenticated') { @@ -133,7 +195,7 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId }

Loading payment details...

)} - +
); }; diff --git a/src/components/content/courses/CourseDetails.js b/src/components/content/courses/CourseDetails.js index 31df945..fee1b5c 100644 --- a/src/components/content/courses/CourseDetails.js +++ b/src/components/content/courses/CourseDetails.js @@ -91,7 +91,7 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec } if (paidCourse && decryptionPerformed && author && processedEvent?.pubkey !== session?.user?.pubkey && !session?.user?.role?.subscribed) { - return + return } if (paidCourse && author && processedEvent?.pubkey === session?.user?.pubkey) { diff --git a/src/components/content/documents/DocumentDetails.js b/src/components/content/documents/DocumentDetails.js index 661ef26..0f6e9af 100644 --- a/src/components/content/documents/DocumentDetails.js +++ b/src/components/content/documents/DocumentDetails.js @@ -77,11 +77,11 @@ const DocumentDetails = ({ processedEvent, topics, title, summary, image, price, // if the user paid for the course that this lesson is in, show a message that says you have this lesson through the course and show how much you paid for the course if (isLesson && course && session?.user?.purchased?.some(purchase => purchase.courseId === course)) { - return purchase.courseId === course)?.course?.price} sats for the course.`} icon="pi pi-check" label={`Paid ${session?.user?.purchased?.find(purchase => purchase.courseId === course)?.course?.price} sats`} severity="success" outlined size="small" className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" /> + return purchase.courseId === course)?.course?.price} sats for the course.`} icon="pi pi-check" label={`Paid`} severity="success" outlined size="small" className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" /> } if (paidResource && decryptedContent && author && processedEvent?.pubkey !== session?.user?.pubkey && !session?.user?.role?.subscribed) { - return + return } if (paidResource && author && processedEvent?.pubkey === session?.user?.pubkey) { diff --git a/src/config/appConfig.js b/src/config/appConfig.js index 30556e0..44155e5 100644 --- a/src/config/appConfig.js +++ b/src/config/appConfig.js @@ -11,7 +11,7 @@ const appConfig = { "wss://purplerelay.com/", "wss://relay.devs.tools/" ], - authorPubkeys: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345"], + authorPubkeys: ["f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345", "468f729dd409053dac5e7470622c3996aad88db6ed1de9165cb1921b5ab4fd5e"], customLightningAddresses: [ { // todo remove need for lowercase