unify subscription period constants & handle missing payment dates

This commit is contained in:
austinkelsay 2025-05-14 16:29:54 -05:00
parent 2c6c230521
commit dc359dd1d1
No known key found for this signature in database
GPG Key ID: 5A763922E5BA08EE
3 changed files with 59 additions and 10 deletions

View File

@ -18,6 +18,7 @@ import NostrIcon from '../../../../public/images/nostr.png';
import Image from 'next/image';
import RenewSubscription from '@/components/profile/subscription/RenewSubscription';
import { SelectButton } from 'primereact/selectbutton';
import { calculateExpirationDate } from '@/constants/subscriptionPeriods';
const SubscribeModal = ({ user }) => {
const { data: session, update } = useSession();
@ -45,13 +46,20 @@ const SubscribeModal = ({ user }) => {
if (user && user.role) {
setSubscribed(user.role.subscribed);
setSubscriptionType(user.role.subscriptionType || 'monthly');
const subscribedAt = new Date(user.role.lastPaymentAt);
// Calculate subscription end date based on type
const daysToAdd = subscriptionType === 'yearly' ? 365 : 31;
const subscribedUntil = new Date(subscribedAt.getTime() + daysToAdd * 24 * 60 * 60 * 1000);
// Only calculate dates if lastPaymentAt exists
if (user.role.lastPaymentAt) {
const subscribedAt = new Date(user.role.lastPaymentAt);
// Use the shared helper to calculate expiration date
const subscribedUntil = calculateExpirationDate(subscribedAt, subscriptionType);
setSubscribedUntil(subscribedUntil);
} else {
// Reset the subscribedUntil value if no lastPaymentAt
setSubscribedUntil(null);
}
setSubscribedUntil(subscribedUntil);
if (user.role.subscriptionExpiredAt) {
const expiredAt = new Date(user.role.subscriptionExpiredAt);
setSubscriptionExpiredAt(expiredAt);
@ -174,7 +182,7 @@ const SubscribeModal = ({ user }) => {
<Message className="w-fit" severity="success" text="Subscribed!" />
<p className="mt-3">Thank you for your support 🎉</p>
<p className="text-sm text-gray-400">
Pay-as-you-go {user?.role?.subscriptionType || 'monthly'} subscription will renew on {subscribedUntil?.toLocaleDateString()}
Pay-as-you-go {user?.role?.subscriptionType || 'monthly'} subscription will renew on {subscribedUntil ? subscribedUntil.toLocaleDateString() : 'N/A'}
</p>
</div>
)}
@ -183,7 +191,7 @@ const SubscribeModal = ({ user }) => {
<Message className="w-fit" severity="success" text="Subscribed!" />
<p className="mt-3">Thank you for your support 🎉</p>
<p className="text-sm text-gray-400">
Recurring {user?.role?.subscriptionType || 'monthly'} subscription will AUTO renew on {subscribedUntil?.toLocaleDateString()}
Recurring {user?.role?.subscriptionType || 'monthly'} subscription will AUTO renew on {subscribedUntil ? subscribedUntil.toLocaleDateString() : 'N/A'}
</p>
</div>
)}

View File

@ -0,0 +1,36 @@
// Constants for subscription periods to maintain consistency across the application
export const SUBSCRIPTION_PERIODS = {
MONTHLY: {
DAYS: 30,
BUFFER_HOURS: 1, // Buffer time for expiration checks
},
YEARLY: {
DAYS: 365,
BUFFER_HOURS: 1, // Buffer time for expiration checks
}
};
// Helper to calculate expiration date (for UI display)
export const calculateExpirationDate = (startDate, subscriptionType) => {
const periodDays = subscriptionType === 'yearly'
? SUBSCRIPTION_PERIODS.YEARLY.DAYS
: SUBSCRIPTION_PERIODS.MONTHLY.DAYS;
return new Date(startDate.getTime() + periodDays * 24 * 60 * 60 * 1000);
};
// Helper to check if subscription has expired (for backend logic)
export const hasSubscriptionExpired = (lastPaymentDate, subscriptionType) => {
if (!lastPaymentDate) return true;
const now = new Date();
const period = subscriptionType === 'yearly'
? SUBSCRIPTION_PERIODS.YEARLY
: SUBSCRIPTION_PERIODS.MONTHLY;
const expirationTime = lastPaymentDate.getTime() +
(period.DAYS * 24 * 60 * 60 * 1000) +
(period.BUFFER_HOURS * 60 * 60 * 1000);
return now.getTime() > expirationTime;
};

View File

@ -1,4 +1,5 @@
import prisma from '../prisma';
import { SUBSCRIPTION_PERIODS } from '@/constants/subscriptionPeriods';
export const getAllUsers = async () => {
return await prisma.user.findMany({
@ -205,12 +206,16 @@ export const findExpiredSubscriptions = async () => {
try {
const now = new Date();
// Define expiration periods
// Use the constants for expiration periods
const monthlyExpiration = new Date(
now.getTime() - 30 * 24 * 60 * 60 * 1000 - 1 * 60 * 60 * 1000
now.getTime() -
(SUBSCRIPTION_PERIODS.MONTHLY.DAYS * 24 * 60 * 60 * 1000) -
(SUBSCRIPTION_PERIODS.MONTHLY.BUFFER_HOURS * 60 * 60 * 1000)
);
const yearlyExpiration = new Date(
now.getTime() - 365 * 24 * 60 * 60 * 1000 - 1 * 60 * 60 * 1000
now.getTime() -
(SUBSCRIPTION_PERIODS.YEARLY.DAYS * 24 * 60 * 60 * 1000) -
(SUBSCRIPTION_PERIODS.YEARLY.BUFFER_HOURS * 60 * 60 * 1000)
);
// Find expired subscriptions of both types