Random styling fixes, param for user id on track calls, params on calendly embed, add favicon
BIN
public/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
public/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 182 KiB |
BIN
public/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
public/favicon-16x16.png
Normal file
After Width: | Height: | Size: 783 B |
BIN
public/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 15 KiB |
19
public/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "PlebDevs",
|
||||||
|
"short_name": "PlebDevs",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#201c24",
|
||||||
|
"background_color": "#201c24",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
@ -80,7 +80,7 @@ const CoursePaymentButton = ({ lnAddress, amount, onSuccess, onError, courseId }
|
|||||||
const result = await axios.post('/api/purchase/course', purchaseData);
|
const result = await axios.post('/api/purchase/course', purchaseData);
|
||||||
|
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
track('Course Payment', { courseId: courseId });
|
track('Course Payment', { courseId: courseId, userId: session?.user?.id });
|
||||||
if (onSuccess) onSuccess(response);
|
if (onSuccess) onSuccess(response);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to update user purchases');
|
throw new Error('Failed to update user purchases');
|
||||||
|
@ -77,7 +77,7 @@ const ResourcePaymentButton = ({ lnAddress, amount, onSuccess, onError, resource
|
|||||||
const result = await axios.post('/api/purchase/resource', purchaseData);
|
const result = await axios.post('/api/purchase/resource', purchaseData);
|
||||||
|
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
track('Resource Payment', { resourceId: resourceId });
|
track('Resource Payment', { resourceId: resourceId, userId: session?.user?.id });
|
||||||
if (onSuccess) onSuccess(response);
|
if (onSuccess) onSuccess(response);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to update user purchases');
|
throw new Error('Failed to update user purchases');
|
||||||
|
@ -73,7 +73,7 @@ const SubscriptionPaymentButtons = ({ onSuccess, onError, onRecurringSubscriptio
|
|||||||
|
|
||||||
const handlePaymentSuccess = async (response) => {
|
const handlePaymentSuccess = async (response) => {
|
||||||
console.log('Payment successful', response);
|
console.log('Payment successful', response);
|
||||||
track('Subscription Payment', { method: "pay_as_you_go" });
|
track('Subscription Payment', { method: "pay_as_you_go", userId: session?.user?.id });
|
||||||
showToast('success', 'Payment Successful', 'Your payment has been processed successfully.');
|
showToast('success', 'Payment Successful', 'Your payment has been processed successfully.');
|
||||||
if (onSuccess) onSuccess(response);
|
if (onSuccess) onSuccess(response);
|
||||||
};
|
};
|
||||||
@ -131,7 +131,7 @@ const SubscriptionPaymentButtons = ({ onSuccess, onError, onRecurringSubscriptio
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (subscriptionResponse.status === 200) {
|
if (subscriptionResponse.status === 200) {
|
||||||
track('Subscription Payment', { method: "recurring" });
|
track('Subscription Payment', { method: "recurring", userId: session?.user?.id });
|
||||||
showToast('success', 'Subscription Setup', 'Recurring subscription setup successful!');
|
showToast('success', 'Subscription Setup', 'Recurring subscription setup successful!');
|
||||||
if (onRecurringSubscriptionSuccess) onRecurringSubscriptionSuccess();
|
if (onRecurringSubscriptionSuccess) onRecurringSubscriptionSuccess();
|
||||||
} else {
|
} else {
|
||||||
@ -185,7 +185,7 @@ const SubscriptionPaymentButtons = ({ onSuccess, onError, onRecurringSubscriptio
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (subscriptionResponse.status === 200) {
|
if (subscriptionResponse.status === 200) {
|
||||||
track('Subscription Payment', { method: "recurring-manual" });
|
track('Subscription Payment', { method: "recurring-manual", userId: session?.user?.id });
|
||||||
showToast('success', 'NWC', 'Subscription setup successful!');
|
showToast('success', 'NWC', 'Subscription setup successful!');
|
||||||
if (onRecurringSubscriptionSuccess) onRecurringSubscriptionSuccess();
|
if (onRecurringSubscriptionSuccess) onRecurringSubscriptionSuccess();
|
||||||
} else {
|
} else {
|
||||||
|
@ -253,7 +253,7 @@ const DocumentForm = ({ draft = null, isPublished = false }) => {
|
|||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
External Links
|
External Links
|
||||||
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
||||||
data-pr-tooltip="Add any relevant external links that pair with this content"
|
data-pr-tooltip="Add any relevant external links that pair with this content (these links are currently not encrypted for 'paid' content)"
|
||||||
data-pr-position="right"
|
data-pr-position="right"
|
||||||
data-pr-at="right+5 top"
|
data-pr-at="right+5 top"
|
||||||
data-pr-my="left center-2"
|
data-pr-my="left center-2"
|
||||||
|
@ -171,7 +171,7 @@ const VideoForm = ({ draft = null }) => {
|
|||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
External Links
|
External Links
|
||||||
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
||||||
data-pr-tooltip="Add any relevant external links that pair with this content"
|
data-pr-tooltip="Add any relevant external links that pair with this content (these links are currently not encrypted for 'paid' content)"
|
||||||
data-pr-position="right"
|
data-pr-position="right"
|
||||||
data-pr-at="right+5 top"
|
data-pr-at="right+5 top"
|
||||||
data-pr-my="left center-2"
|
data-pr-my="left center-2"
|
||||||
|
@ -184,7 +184,7 @@ const EmbeddedDocumentForm = ({ draft = null, isPublished = false, onSave, isPai
|
|||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
External Links
|
External Links
|
||||||
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
||||||
data-pr-tooltip="Add any relevant external links that pair with this content"
|
data-pr-tooltip="Add any relevant external links that pair with this content (these links are currently not encrypted for 'paid' content)"
|
||||||
data-pr-position="right"
|
data-pr-position="right"
|
||||||
data-pr-at="right+5 top"
|
data-pr-at="right+5 top"
|
||||||
data-pr-my="left center-2"
|
data-pr-my="left center-2"
|
||||||
|
@ -144,7 +144,7 @@ const EmbeddedVideoForm = ({ draft = null, onSave, isPaid }) => {
|
|||||||
<span className="pl-1 flex items-center">
|
<span className="pl-1 flex items-center">
|
||||||
External Links
|
External Links
|
||||||
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
<i className="pi pi-info-circle ml-2 cursor-pointer"
|
||||||
data-pr-tooltip="Add any relevant external links that pair with this content"
|
data-pr-tooltip="Add any relevant external links that pair with this content (these links are currently not encrypted for 'paid' content)"
|
||||||
data-pr-position="right"
|
data-pr-position="right"
|
||||||
data-pr-at="right+5 top"
|
data-pr-at="right+5 top"
|
||||||
data-pr-my="left center-2"
|
data-pr-my="left center-2"
|
||||||
|
@ -197,7 +197,7 @@ const UserSettings = () => {
|
|||||||
</h3>
|
</h3>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col w-1/2 mx-auto justify-between items-center max-mob:w-full max-tab:w-full">
|
<div className="flex flex-col w-1/2 mx-auto justify-between items-center max-mob:w-full max-tab:w-full">
|
||||||
<h2 className="text-xl my-2 max-mob:text-base max-tab:text-base">Connect Your Lightning Wallet</h2>
|
<h3 className="text-xl my-2 max-mob:text-base max-tab:text-base">Connect Your Lightning Wallet for easier zaps and payments</h3>
|
||||||
<BitcoinConnectButton />
|
<BitcoinConnectButton />
|
||||||
</div>
|
</div>
|
||||||
{user && (
|
{user && (
|
||||||
|
@ -3,7 +3,7 @@ import { Dialog } from 'primereact/dialog';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
|
|
||||||
const CalendlyEmbed = ({ visible, onHide }) => {
|
const CalendlyEmbed = ({ visible, onHide, userId, userEmail, userName }) => {
|
||||||
const windowWidth = useWindowWidth();
|
const windowWidth = useWindowWidth();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@ -34,7 +34,7 @@ const CalendlyEmbed = ({ visible, onHide }) => {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="calendly-inline-widget"
|
className="calendly-inline-widget"
|
||||||
data-url="https://calendly.com/plebdevs/30min?hide_event_type_details=1&hide_gdpr_banner=1"
|
data-url={`https://calendly.com/plebdevs/30min?hide_event_type_details=1&hide_gdpr_banner=1&email=${encodeURIComponent(userEmail)}&name=${encodeURIComponent(userName)}&custom_data=${encodeURIComponent(JSON.stringify({ user_id: userId }))}`}
|
||||||
style={{ minWidth: '320px', height: '700px' }}
|
style={{ minWidth: '320px', height: '700px' }}
|
||||||
/>
|
/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -235,6 +235,9 @@ const SubscribeModal = ({ user }) => {
|
|||||||
<CalendlyEmbed
|
<CalendlyEmbed
|
||||||
visible={calendlyVisible}
|
visible={calendlyVisible}
|
||||||
onHide={() => setCalendlyVisible(false)}
|
onHide={() => setCalendlyVisible(false)}
|
||||||
|
userId={session?.user?.id}
|
||||||
|
userName={session?.user?.name || user?.kind0?.username}
|
||||||
|
userEmail={session?.user?.email}
|
||||||
/>
|
/>
|
||||||
<CancelSubscription
|
<CancelSubscription
|
||||||
visible={cancelSubscriptionVisible}
|
visible={cancelSubscriptionVisible}
|
||||||
|
@ -228,6 +228,9 @@ const UserSubscription = () => {
|
|||||||
<CalendlyEmbed
|
<CalendlyEmbed
|
||||||
visible={calendlyVisible}
|
visible={calendlyVisible}
|
||||||
onHide={() => setCalendlyVisible(false)}
|
onHide={() => setCalendlyVisible(false)}
|
||||||
|
userId={session?.user?.id}
|
||||||
|
userName={session?.user?.name || user?.kind0?.username}
|
||||||
|
userEmail={session?.user?.email}
|
||||||
/>
|
/>
|
||||||
<CancelSubscription
|
<CancelSubscription
|
||||||
visible={cancelSubscriptionVisible}
|
visible={cancelSubscriptionVisible}
|
||||||
|
@ -7,6 +7,12 @@ class MyDocument extends Document {
|
|||||||
<Head>
|
<Head>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Blinker:wght@100;200;300;400;600;700;800;900&family=Poppins&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Blinker:wght@100;200;300;400;600;700;800;900&family=Poppins&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
|
{/* Favicon configuration */}
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<body>
|
||||||
<Main />
|
<Main />
|
||||||
|
@ -33,6 +33,8 @@ export default async function handler(req, res) {
|
|||||||
if (response && response?.preimage) {
|
if (response && response?.preimage) {
|
||||||
await updateUserSubscription(userId, true, nwc);
|
await updateUserSubscription(userId, true, nwc);
|
||||||
continue; // Skip adding to stillExpired list
|
continue; // Skip adding to stillExpired list
|
||||||
|
} else {
|
||||||
|
console.log(`Payment failed for user ${userId}: (stillExpired)`, response);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Payment failed for user ${userId}:`, error);
|
console.error(`Payment failed for user ${userId}:`, error);
|
||||||
|
@ -287,6 +287,9 @@ const Subscribe = () => {
|
|||||||
<CalendlyEmbed
|
<CalendlyEmbed
|
||||||
visible={calendlyVisible}
|
visible={calendlyVisible}
|
||||||
onHide={() => setCalendlyVisible(false)}
|
onHide={() => setCalendlyVisible(false)}
|
||||||
|
userId={session?.user?.id}
|
||||||
|
userName={session?.user?.name || user?.kind0?.username}
|
||||||
|
userEmail={session?.user?.email}
|
||||||
/>
|
/>
|
||||||
<CancelSubscription
|
<CancelSubscription
|
||||||
visible={cancelSubscriptionVisible}
|
visible={cancelSubscriptionVisible}
|
||||||
|