mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 00:32:03 +00:00
Merge pull request #3 from AustinKelsay/feature/discount-code-hardcoded
Discount code single
This commit is contained in:
commit
8e68214972
@ -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);
|
||||
@ -89,10 +104,64 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId }
|
||||
setDialogVisible(false);
|
||||
};
|
||||
|
||||
const handleDiscountCode = (value) => {
|
||||
setDiscountCode(value);
|
||||
if (value.toLowerCase() === DISCOUNT_CODE.toLowerCase()) {
|
||||
setDiscountApplied(true);
|
||||
showToast('success', 'Discount Applied', `${calculateDiscount(amount).savedPercentage}% discount applied!`);
|
||||
} else if (value && value.toLowerCase() !== DISCOUNT_CODE.toLowerCase()) {
|
||||
setDiscountApplied(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-2">
|
||||
{!showDiscountInput ? (
|
||||
<button
|
||||
onClick={() => setShowDiscountInput(true)}
|
||||
className="text-sm text-blue-500 hover:text-blue-700 underline self-start flex items-center gap-1"
|
||||
>
|
||||
<i className="pi pi-tag text-xs"></i>
|
||||
Have a discount code?
|
||||
</button>
|
||||
) : (
|
||||
<div className="flex flex-col gap-2 w-full">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="relative flex-1">
|
||||
<InputText
|
||||
value={discountCode}
|
||||
onChange={(e) => handleDiscountCode(e.target.value)}
|
||||
placeholder="Enter discount code"
|
||||
className="text-sm w-full p-2"
|
||||
/>
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowDiscountInput(false);
|
||||
setDiscountCode('');
|
||||
setDiscountApplied(false);
|
||||
}}
|
||||
className="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600"
|
||||
>
|
||||
<i className="pi pi-times text-xs"></i>
|
||||
</button>
|
||||
</div>
|
||||
{discountApplied && (
|
||||
<span className="text-green-500 text-sm whitespace-nowrap flex items-center gap-1">
|
||||
<i className="pi pi-check-circle"></i>
|
||||
{calculateDiscount(amount).savedPercentage}% off!
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{discountApplied && (
|
||||
<div className="text-xs text-gray-500 flex items-center gap-1">
|
||||
<span className="line-through">{amount} sats</span>
|
||||
<span className="text-green-500 font-semibold">→ {calculateDiscount(amount).discountedAmount} sats</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<GenericButton
|
||||
label={`${amount} sats`}
|
||||
label={`${discountApplied ? calculateDiscount(amount).discountedAmount : amount} sats`}
|
||||
icon="pi pi-wallet"
|
||||
onClick={() => {
|
||||
if (status === 'unauthenticated') {
|
||||
@ -133,7 +202,7 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId }
|
||||
<p>Loading payment details...</p>
|
||||
)}
|
||||
</Dialog>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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 <GenericButton icon="pi pi-check" label={`Paid ${processedEvent.price} sats`} severity="success" outlined size="small" className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" />
|
||||
return <GenericButton icon="pi pi-check" label={`Paid`} severity="success" outlined size="small" tooltip={`You paid ${processedEvent.price} sats to access this course (or potentially less if a discount was applied)`} tooltipOptions={{ position: 'top' }} className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" />
|
||||
}
|
||||
|
||||
if (paidCourse && author && processedEvent?.pubkey === session?.user?.pubkey) {
|
||||
|
@ -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 <GenericButton tooltipOptions={{ position: 'top' }} tooltip={`You have this lesson through purchasing the course it belongs to. You paid ${session?.user?.purchased?.find(purchase => 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 <GenericButton tooltipOptions={{ position: 'top' }} tooltip={`You have this lesson through purchasing the course it belongs to. You paid ${session?.user?.purchased?.find(purchase => 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 <GenericButton icon="pi pi-check" label={`Paid ${processedEvent.price} sats`} severity="success" outlined size="small" className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" />
|
||||
return <GenericButton icon="pi pi-check" label={`Paid`} severity="success" outlined size="small" tooltip={`You paid ${processedEvent.price} sats to access this content (or potentially less if a discount was applied)`} tooltipOptions={{ position: 'top' }} className="cursor-default hover:opacity-100 hover:bg-transparent focus:ring-0" />
|
||||
}
|
||||
|
||||
if (paidResource && author && processedEvent?.pubkey === session?.user?.pubkey) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user