import React, { useState, useRef, useEffect } from 'react'; import { useSession } from 'next-auth/react'; import { useRouter } from 'next/router'; import { useToast } from '@/hooks/useToast'; import axios from 'axios'; import { Card } from 'primereact/card'; import { Message } from 'primereact/message'; import useWindowWidth from '@/hooks/useWindowWidth'; import { Menu } from "primereact/menu"; import GenericButton from '@/components/buttons/GenericButton'; import { ProgressSpinner } from 'primereact/progressspinner'; import SubscriptionPaymentButtons from '@/components/bitcoinConnect/SubscriptionPaymentButton'; import Image from 'next/image'; import NostrIcon from '../../public/images/nostr.png'; import CalendlyEmbed from '@/components/profile/subscription/CalendlyEmbed'; import CancelSubscription from '@/components/profile/subscription/CancelSubscription'; import RenewSubscription from '@/components/profile/subscription/RenewSubscription'; import Nip05Form from '@/components/profile/subscription/Nip05Form'; import LightningAddressForm from '@/components/profile/subscription/LightningAddressForm'; const Subscribe = () => { const { data: session, update } = useSession(); const { showToast } = useToast(); const router = useRouter(); const menu = useRef(null); const windowWidth = useWindowWidth(); const [user, setUser] = useState(null); const [isProcessing, setIsProcessing] = useState(false); const [subscribed, setSubscribed] = useState(false); const [subscribedUntil, setSubscribedUntil] = useState(null); const [subscriptionExpiredAt, setSubscriptionExpiredAt] = useState(null); const [calendlyVisible, setCalendlyVisible] = useState(false); const [lightningAddressVisible, setLightningAddressVisible] = useState(false); const [nip05Visible, setNip05Visible] = useState(false); const [cancelSubscriptionVisible, setCancelSubscriptionVisible] = useState(false); const [renewSubscriptionVisible, setRenewSubscriptionVisible] = useState(false); useEffect(() => { if (session && session?.user) { setUser(session.user); } }, [session]) useEffect(() => { if (user && user.role) { setSubscribed(user.role.subscribed); const subscribedAt = new Date(user.role.lastPaymentAt); const subscribedUntil = new Date(subscribedAt.getTime() + 31 * 24 * 60 * 60 * 1000); setSubscribedUntil(subscribedUntil); if (user.role.subscriptionExpiredAt) { const expiredAt = new Date(user.role.subscriptionExpiredAt) setSubscriptionExpiredAt(expiredAt); } } }, [user]); const handleSubscriptionSuccess = async (response) => { setIsProcessing(true); try { const apiResponse = await axios.put('/api/users/subscription', { userId: session.user.id, isSubscribed: true, }); if (apiResponse.data) { await update(); showToast('success', 'Subscription Successful', 'Your subscription has been activated.'); } else { throw new Error('Failed to update subscription status'); } } catch (error) { console.error('Subscription update error:', error); showToast('error', 'Subscription Update Failed', `Error: ${error.message}`); } finally { setIsProcessing(false); } }; const handleSubscriptionError = (error) => { console.error('Subscription error:', error); showToast('error', 'Subscription Failed', `An error occurred: ${error.message}`); setIsProcessing(false); }; const handleRecurringSubscriptionSuccess = async () => { setIsProcessing(true); try { await update(); showToast('success', 'Recurring Subscription Activated', 'Your recurring subscription has been set up successfully.'); } catch (error) { console.error('Session update error:', error); showToast('error', 'Session Update Failed', `Error: ${error.message}`); } finally { setIsProcessing(false); } }; const menuItems = [ { label: "Schedule 1:1", icon: "pi pi-calendar", command: () => setCalendlyVisible(true), }, { label: session?.user?.lightningAddress ? "Update PlebDevs Lightning Address" : "Claim PlebDevs Lightning Address", icon: "pi pi-bolt", command: () => setLightningAddressVisible(true), }, { label: session?.user?.nip05 ? "Update PlebDevs Nostr NIP-05" : "Claim PlebDevs Nostr NIP-05", icon: "pi pi-at", command: () => setNip05Visible(true), }, { label: "Renew Subscription", icon: "pi pi-sync", command: () => setRenewSubscriptionVisible(true), }, { label: "Cancel Subscription", icon: "pi pi-trash", command: () => setCancelSubscriptionVisible(true), }, ]; const subscriptionCardTitleAndButton = (
Plebdevs Subscription menu.current.toggle(e)} >
); const subscriptionCardTitle = (
Plebdevs Subscription
); return (
{windowWidth < 768 && (

Subscription Management

)}
{session && session?.user ? ( <> {subscribed && (

Thank you for your support 🎉

Pay-as-you-go subscription will renew on {subscribedUntil.toLocaleDateString()}

)} {(!subscribed && !subscriptionExpiredAt) && (
)} {subscriptionExpiredAt && (
)} ) : (
)}
{!session?.user && ( <>

The PlebDevs subscription unlocks all paid content, grants access to our 1:1 calendar for tutoring, support, and mentorship, and grants you your own personal plebdevs.com Lightning Address and Nostr NIP-05 identity.

Subscribe monthly with a pay-as-you-go option or set up an auto-recurring subscription using Nostr Wallet Connect.

Login to start your subscription!

router.push('/auth/signin')} className='text-[#f8f8ff] w-fit' rounded icon="pi pi-user" />
)} {isProcessing ? (
Processing subscription...
) : (

Unlock Premium Benefits

Subscribe now and elevate your development journey!

Access ALL current and future PlebDevs content
Personal mentorship & guidance and access to exclusive 1:1 booking calendar
Claim your own personal plebdevs.com Lightning Address
Nostr Claim your own personal plebdevs.com Nostr NIP-05 identity
I WILL MAKE SURE YOU WIN HARD AND LEVEL UP AS A DEV!
)}
{session?.user && subscribed && ( <>
setCalendlyVisible(true)} /> setNip05Visible(true)} /> } onClick={() => setLightningAddressVisible(true)} />
setRenewSubscriptionVisible(true)} /> setCancelSubscriptionVisible(true)} />
)}

How does the subscription work?

Think of the subscriptions as a Patreon-type model. You pay a monthly fee and in return you get access to premium features and all of the paid content. You can cancel at any time.

How do I Subscribe? (Pay as you go)

The pay as you go subscription is a one-time payment that gives you access to all of the premium features for one month. You will need to manually renew your subscription every month.

How do I Subscribe? (Recurring)

The recurring subscription option allows you to submit a Nostr Wallet Connect URI that will be used to automatically send the subscription fee every month. You can cancel at any time.

Can I cancel my subscription?

Yes, you can cancel your subscription at any time. Your access will remain active until the end of the current billing period.

What happens if I don't renew my subscription?

If you don't renew your subscription, your access to 1:1 calendar and paid content will be removed. However, you will still have access to your PlebDevs Lightning Address, NIP-05, and any content that you paid for.

setCalendlyVisible(false)} /> setCancelSubscriptionVisible(false)} /> setRenewSubscriptionVisible(false)} subscribedUntil={subscribedUntil} /> setNip05Visible(false)} /> setLightningAddressVisible(false)} />
); }; export default Subscribe;