Skip to content

Commit

Permalink
Add cyber monday discount
Browse files Browse the repository at this point in the history
  • Loading branch information
255kb committed Nov 27, 2023
1 parent 2747876 commit 5f4ee5d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ NEXT_PUBLIC_PADDLE_PLAN_TEAM_MONTHLY_PRICE_ID=pri_01h8ez018gcqaee9qb1e5dam81
NEXT_PUBLIC_PADDLE_PLAN_TEAM_YEARLY_PRICE_ID=pri_01h8ez0zh6f5c98f9q3pvgmtv9
NEXT_PUBLIC_PADDLE_PLAN_ENTERPRISE_MONTHLY_PRICE_ID=pri_01h8gra77xee2tsaaz9vatkj9k
NEXT_PUBLIC_PADDLE_PLAN_ENTERPRISE_YEARLY_PRICE_ID=pri_01h8gr7y27rp1mnxqzpt5cpvwx
NEXT_PUBLIC_PADDLE_PLAN_SOLO_MONTHLY_DISCOUNT=dsc_01hg7yfh21311s0rysd7rw8zw6
NEXT_PUBLIC_PADDLE_PLAN_SOLO_YEARLY_DISCOUNT=dsc_01hg7yjt95ny81yy681qz55w2z
NEXT_PUBLIC_DISCOUNT_TIME_LIMIT=1701201600000
# only on dev
NEXT_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=http://127.0.0.1:9099
NODE_ENV=development
3 changes: 3 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ NEXT_PUBLIC_PADDLE_PLAN_TEAM_MONTHLY_PRICE_ID=pri_01h8gwsp95amj9z03hpeqxwyqm
NEXT_PUBLIC_PADDLE_PLAN_TEAM_YEARLY_PRICE_ID=pri_01h8gwt70w0hy5wmzrwaragy7t
NEXT_PUBLIC_PADDLE_PLAN_ENTERPRISE_MONTHLY_PRICE_ID=pri_01h8gwvc1s97zmkmpmrqet6y3a
NEXT_PUBLIC_PADDLE_PLAN_ENTERPRISE_YEARLY_PRICE_ID=pri_01h8gwvwwcy4hf6705jz6a863v
NEXT_PUBLIC_PADDLE_PLAN_SOLO_MONTHLY_DISCOUNT=dsc_01hg7xhs3b857pfgajwh67gr17
NEXT_PUBLIC_PADDLE_PLAN_SOLO_YEARLY_DISCOUNT=dsc_01hg7yrpewvmf7t8y94y66gx9f
NEXT_PUBLIC_DISCOUNT_TIME_LIMIT=1701201600000
49 changes: 49 additions & 0 deletions components/plans.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useRouter } from 'next/router';
import { FunctionComponent, useState } from 'react';
import { frequencyNames, planNames } from '../constants/plans';
import { useAuth } from '../utils/auth';
import { useCountdown } from '../utils/countdown';
import { useCurrentUser } from '../utils/queries';
import PaddleScript from './paddle';

Expand Down Expand Up @@ -50,6 +51,13 @@ const pricing = {
}
};

const discounts = {
SOLO: {
MONTHLY: process.env.NEXT_PUBLIC_PADDLE_PLAN_SOLO_MONTHLY_DISCOUNT,
YEARLY: process.env.NEXT_PUBLIC_PADDLE_PLAN_SOLO_YEARLY_DISCOUNT
}
};

const suffixes = {
MONTHLY: 'mo',
YEARLY: 'yr'
Expand All @@ -63,6 +71,11 @@ const Plans: FunctionComponent<{ showFree: boolean; showTagline: boolean }> =
const [planFrequency, setPlanFrequency] = useState('MONTHLY');
const [seats, setSeats] = useState(1);
const [configurePlan, setConfigurePlan] = useState(null);
const discountLimit =
parseInt(process.env.NEXT_PUBLIC_DISCOUNT_TIME_LIMIT, 10) - 3600000;
const discountEnabled = new Date().getTime() < discountLimit;
const [countdownDays, countdownHours, countdownMinutes, countdownSeconds] =
useCountdown(discountLimit);

const openCheckout = (planId: string) => {
// @ts-ignore
Expand All @@ -71,6 +84,9 @@ const Plans: FunctionComponent<{ showFree: boolean; showTagline: boolean }> =
theme: 'light',
locale: 'en'
},
discountId: discountEnabled
? discounts[planId][planFrequency] || null
: null,
items: [
{
priceId: pricing[planId][planFrequency].priceId,
Expand Down Expand Up @@ -118,6 +134,39 @@ const Plans: FunctionComponent<{ showFree: boolean; showTagline: boolean }> =
<QueryClientProvider client={queryClient}>
<section className='mb-8'>
<div className='container'>
{discountEnabled && (
<div className='text-center my-6 col-md-8 mx-auto'>
<div className='alert alert-light border-success border-2 shadow'>
🤖 <strong>Cyber Monday!</strong> Get 50% off a new Solo
plan subscription! <br /> (50% off the first year or first 6
months, discount applied at checkout)
<br />
Remaining time:{' '}
{countdownDays > 0 && (
<strong>
<span>
{countdownDays} day{countdownDays > 1 ? 's' : ''}
</span>
</strong>
)}{' '}
{countdownHours > 0 && (
<strong>
<span>
{countdownHours} hour{countdownHours > 1 ? 's' : ''}
</span>
</strong>
)}{' '}
{countdownMinutes > 0 && (
<strong>
<span>
{countdownMinutes} minute
{countdownMinutes > 1 ? 's' : ''}
</span>
</strong>
)}
</div>
</div>
)}
<div className='text-center my-6'>
<div
className='btn-group'
Expand Down
35 changes: 35 additions & 0 deletions utils/countdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useEffect, useState } from 'react';

const useCountdown = (targetDate: number) => {
const countDownDate = new Date(targetDate).getTime();

const [countDown, setCountDown] = useState(
countDownDate - new Date().getTime()
);

useEffect(() => {
const interval = setInterval(() => {
setCountDown(countDownDate - new Date().getTime());
}, 1000);

return () => clearInterval(interval);
}, [countDownDate]);

return getReturnValues(countDown);
};

const getReturnValues = (countDown: number) => {
// calculate time left
const countdownDays = Math.floor(countDown / (1000 * 60 * 60 * 24));
const countdownHours = Math.floor(
(countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
);
const countdownMinutes = Math.floor(
(countDown % (1000 * 60 * 60)) / (1000 * 60)
);
const countdownSeconds = Math.floor((countDown % (1000 * 60)) / 1000);

return [countdownDays, countdownHours, countdownMinutes, countdownSeconds];
};

export { useCountdown };

0 comments on commit 5f4ee5d

Please sign in to comment.