Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEOS-1579: add free trial timer to header #2871

Merged
merged 7 commits into from
Oct 30, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 54 additions & 59 deletions frontend/apps/web/components/site-header/AccountStatusHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import { SystemAppConfig } from '@/app/config/app-config';
import { cn } from '@/libs/utils';
import { useQuery } from '@connectrpc/connect-query';
import { AccountStatus, IsAccountStatusValidResponse } from '@neosync/sdk';
import { AccountStatus } from '@neosync/sdk';
import { isAccountStatusValid } from '@neosync/sdk/connectquery';
import { differenceInDays } from 'date-fns';
import { useAccount } from '../providers/account-provider';
import { Skeleton } from '../ui/skeleton';
import Upgrade from './Upgrade';
Expand Down Expand Up @@ -31,14 +32,19 @@ export function AccountStatusHandler(props: Props) {
(data?.accountStatus == AccountStatus.ACCOUNT_TRIAL_ACTIVE ||
data?.accountStatus == AccountStatus.ACCOUNT_TRIAL_EXPIRED);

const trialEndDate = new Date(
data?.trialExpiresAt?.toDate() ?? Date.now()
).getTime();

const daysRemaining = differenceInDays(Math.max(trialEndDate), Date.now());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const daysRemaining = differenceInDays(Math.max(trialEndDate), Date.now());
const daysRemaining = Math.max(0, differenceInDays(trialEndDate, Date.now()));


return (
<div className="flex flex-row items-center gap-2">
{showTrialCountdown && (
<TrialCountdown
nickzelei marked this conversation as resolved.
Show resolved Hide resolved
trialEndDate={new Date(
data?.trialExpiresAt?.toDate() ?? Date.now()
).getTime()}
isAccountStatusValidResp={data}
isExpired={data?.accountStatus == AccountStatus.ACCOUNT_TRIAL_EXPIRED}
isAlmostExpired={daysRemaining <= 3}
daysRemaining={daysRemaining}
/>
)}
<Upgrade
Expand All @@ -52,63 +58,52 @@ export function AccountStatusHandler(props: Props) {
}

interface TrialCountdownProps {
trialEndDate: number;
isAccountStatusValidResp: IsAccountStatusValidResponse | undefined;
isExpired: boolean;
isAlmostExpired: boolean;
daysRemaining: number;
}

function TrialCountdown(props: TrialCountdownProps) {
const { trialEndDate, isAccountStatusValidResp } = props;

const now = Date.now();
const daysRemaining = Math.max(
0,
Math.ceil((trialEndDate - now) / (1000 * 60 * 60 * 24))
);

const isExpired =
isAccountStatusValidResp?.accountStatus ==
AccountStatus.ACCOUNT_TRIAL_EXPIRED;
const isAlmostExpired = daysRemaining <= 3;
const { isExpired, isAlmostExpired, daysRemaining } = props;

if (isExpired)
return (
<div
className={cn(
isExpired
? 'border-red-700'
: isAlmostExpired
? 'border-yellow-500'
: ' border-blue-400 dark:border-blue-700',
'border flex items-center gap-2 h-8 rounded-md px-2 py-1'
)}
>
<div className="relative flex items-center">
<div
className={cn(
isExpired
? 'bg-red-600'
: isAlmostExpired
? 'bg-yellow-600'
: ' border-blue-400 dark:border-blue-700',
'absolute animate-ping h-2.5 w-2.5 rounded-full bg-blue-400 opacity-75'
)}
/>
<div
className={cn(
isExpired
? 'bg-red-600'
: isAlmostExpired
? 'bg-yellow-600'
: 'bg-blue-700',
'relative h-2.5 w-2.5 rounded-full'
)}
/>
</div>
<div className="text-xs ">
{isExpired
? 'Trial Expired'
: `${daysRemaining} day${daysRemaining !== 1 ? 's' : ''} left in your trial`}
</div>
return (
<div
className={cn(
isExpired
? 'border-red-700'
: isAlmostExpired
? 'border-yellow-500'
: ' border-blue-400 dark:border-blue-700',
'border flex items-center gap-2 h-8 rounded-md px-2 py-1'
)}
>
<div className="relative flex items-center">
<div
className={cn(
isExpired
? 'bg-red-600'
: isAlmostExpired
? 'bg-yellow-600'
: ' border-blue-400 dark:border-blue-700',
'absolute animate-ping h-2.5 w-2.5 rounded-full bg-blue-400 opacity-75'
)}
/>
<div
className={cn(
isExpired
? 'bg-red-600'
: isAlmostExpired
? 'bg-yellow-600'
: 'bg-blue-700',
'relative h-2.5 w-2.5 rounded-full'
)}
/>
</div>
);
<div className="text-xs ">
{isExpired
? 'Trial Expired'
: `${daysRemaining} day${daysRemaining !== 1 ? 's' : ''} left in your trial`}
</div>
</div>
);
}