diff --git a/src/components/profile/subscription/UserSubscription.js b/src/components/profile/subscription/UserSubscription.js
index 496f349..1d43ddd 100644
--- a/src/components/profile/subscription/UserSubscription.js
+++ b/src/components/profile/subscription/UserSubscription.js
@@ -95,48 +95,6 @@ const UserSubscription = () => {
}
};
- 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);
- },
- },
- ];
-
- useEffect(() => {
- console.log(subscribed)
- }, [subscribed])
-
return (
{windowWidth < 768 && (
diff --git a/src/components/sidebar/Sidebar.js b/src/components/sidebar/Sidebar.js
index 5c23025..0687d25 100644
--- a/src/components/sidebar/Sidebar.js
+++ b/src/components/sidebar/Sidebar.js
@@ -150,7 +150,7 @@ const Sidebar = ({ course = false }) => {
Create
)}
- session ? router.push('/profile?tab=subscribe') : router.push('/auth/signin')} className={`w-full flex flex-row items-center cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/profile?tab=subscribe') ? 'bg-gray-700' : ''}`}>
+
session ? router.push('/profile?tab=subscribe') : router.push('/auth/signin')} className={`w-full flex flex-row items-center cursor-pointer py-2 my-2 hover:bg-gray-700 rounded-lg ${isActive('/profile?tab=subscribe') || isActive('/subscribe') ? 'bg-gray-700' : ''}`}>
Subscribe
diff --git a/src/pages/about.js b/src/pages/about.js
index 9e9de5d..95c5094 100644
--- a/src/pages/about.js
+++ b/src/pages/about.js
@@ -34,7 +34,7 @@ const AboutPage = () => {
)}
-
+
{
- Documents: Markdown documents posted as NIP-23 long-form events on Nostr.
- Videos: Enhanced markdown files with rich media support, including embedded videos, also saved as NIP-23 events.
- - Courses: Nostr lists that combine multiple documents and videos into a structured learning path.
+ - Courses: Nostr lists (NIP-51) that combines multiple documents and videos into a structured learning path.
diff --git a/src/pages/subscribe.js b/src/pages/subscribe.js
index 9f32915..b611171 100644
--- a/src/pages/subscribe.js
+++ b/src/pages/subscribe.js
@@ -10,47 +10,66 @@ 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 menu = useRef(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) {
- setSubscribed(session?.user.role.subscribed);
- const subscribedAt = new Date(session?.user.role.lastPaymentAt);
+ 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 (session?.user.role.subscriptionExpiredAt) {
- const expiredAt = new Date(session?.user.role.subscriptionExpiredAt)
+ if (user.role.subscriptionExpiredAt) {
+ const expiredAt = new Date(user.role.subscriptionExpiredAt)
setSubscriptionExpiredAt(expiredAt);
}
}
- }, [session, session?.user]);
+ }, [user]);
- const handleSubscriptionSuccess = async (paymentResponse) => {
+ const handleSubscriptionSuccess = async (response) => {
setIsProcessing(true);
try {
- const response = await axios.post('/api/subscription/create', {
- paymentResponse,
+ const apiResponse = await axios.put('/api/users/subscription', {
+ userId: session.user.id,
+ isSubscribed: true,
});
- if (response.data.success) {
- showToast('success', 'Subscription successful!');
+ if (apiResponse.data) {
await update();
- router.push('/dashboard');
+ showToast('success', 'Subscription Successful', 'Your subscription has been activated.');
} else {
- showToast('error', 'Subscription failed. Please try again.');
+ throw new Error('Failed to update subscription status');
}
} catch (error) {
- console.error('Subscription error:', error);
- showToast('error', 'An error occurred. Please try again.');
+ console.error('Subscription update error:', error);
+ showToast('error', 'Subscription Update Failed', `Error: ${error.message}`);
} finally {
setIsProcessing(false);
}
@@ -58,51 +77,48 @@ const Subscribe = () => {
const handleSubscriptionError = (error) => {
console.error('Subscription error:', error);
- showToast('error', 'An error occurred during subscription. Please try again.');
+ showToast('error', 'Subscription Failed', `An error occurred: ${error.message}`);
+ setIsProcessing(false);
};
- const handleRecurringSubscriptionSuccess = async (paymentResponse) => {
+ const handleRecurringSubscriptionSuccess = async () => {
setIsProcessing(true);
try {
- const response = await axios.post('/api/subscription/recurring', {
- paymentResponse,
- });
- if (response.data.success) {
- showToast('success', 'Recurring subscription set up successfully!');
- await update();
- router.push('/dashboard');
- } else {
- showToast('error', 'Failed to set up recurring subscription. Please try again.');
- }
+ await update();
+ showToast('success', 'Recurring Subscription Activated', 'Your recurring subscription has been set up successfully.');
} catch (error) {
- console.error('Recurring subscription error:', error);
- showToast('error', 'An error occurred. Please try again.');
+ console.error('Session update error:', error);
+ showToast('error', 'Session Update Failed', `Error: ${error.message}`);
} finally {
setIsProcessing(false);
}
};
const menuItems = [
- {
- label: "Renew Subscription",
- icon: "pi pi-bolt",
- command: () => {
- // Add your renew functionality here
- },
- },
{
label: "Schedule 1:1",
icon: "pi pi-calendar",
- command: () => {
- // Add your schedule functionality here
- },
+ 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: () => {
- // Add your cancel functionality here
- },
+ command: () => setCancelSubscriptionVisible(true),
},
];
@@ -125,49 +141,55 @@ const Subscribe = () => {
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 && (
-
-
-
- )}
-
- ) : (
-
-
- The plebdevs subscription is a monthly subscription that unlocks all of the paid content, grants you access to the plebdevs 1:1 calendar for tutoring, support, and mentorship, and gives you an exclusive invite to the pleblab bitcoin hackerspace community.
-
-
-
- The plebdevs subscription is Lightning only and you can subscribe a month at a time with the pay as you go option or easily setup an auto recurring monthly subscription using Nostr Wallet Connect.
-
-
-
-
Login to start your subscription
-
router.push('/auth/signin')} className='text-[#f8f8ff] w-fit' size="small" rounded icon="pi pi-user" />
+ {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 ? (
@@ -175,59 +197,107 @@ const Subscribe = () => {
) : (
-
Choose your subscription plan:
-
-
- Monthly Subscription
- Get access to all PlebDevs features / content one month at a time.
-
-
-
- Recurring Monthly Subscription
- Setup auto recurring monthly payments for uninterrupted access.
-
-
+
+
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
+
+
+
+ Claim your own personal plebdevs.com Nostr NIP-05 identity
+
+
+
+ I WILL MAKE SURE YOU WIN HARD AND LEVEL UP AS A DEV!
+
+
+
)}
-
-
- - Access to exclusive content
- - Priority support
- - Early access to new features
- - Community forums
-
-
+ {session?.user && subscribed && (
+ <>
+
+
+ setCalendlyVisible(true)} />
+ setNip05Visible(true)} />
+ } onClick={() => setLightningAddressVisible(true)} />
+
+
+
+
+ setRenewSubscriptionVisible(true)} />
+ setCancelSubscriptionVisible(true)} />
+
+
+ >
+ )}
How does the subscription work?
-
Our subscription provides monthly access to all PlebDevs features. You can choose between a one-time payment or a recurring subscription.
+
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.
- {/* Add more FAQ items as needed */}
+
+
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)}
+ />
);
};