Skip to content

Commit

Permalink
feat: add trial status badge in appbar
Browse files Browse the repository at this point in the history
  • Loading branch information
barinali committed Apr 8, 2023
1 parent 94a3b66 commit afdbed6
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 7 deletions.
4 changes: 3 additions & 1 deletion packages/backend/src/graphql/queries/get-trial-status.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const getTrialStatus = async (
if (!appConfig.isCloud) return;

const inTrial = await context.currentUser.inTrial();
if (!inTrial) return;
const hasActiveSubscription = await context.currentUser.hasActiveSubscription();

if (!inTrial && hasActiveSubscription) return;

return {
expireAt: context.currentUser.trialExpiryDate,
Expand Down
14 changes: 11 additions & 3 deletions packages/backend/src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ class User extends Base {
this.trialExpiryDate = DateTime.now().plus({ days: 30 }).toISODate();
}

async hasActiveSubscription() {
if (!appConfig.isCloud) {
return false;
}

const subscription = await this.$relatedQuery('currentSubscription');

return subscription?.isActive;
}

async inTrial() {
if (!appConfig.isCloud) {
return false;
Expand All @@ -174,9 +184,7 @@ class User extends Base {
return false;
}

const subscription = await this.$relatedQuery('currentSubscription');

if (subscription?.isActive) {
if (await this.hasActiveSubscription()) {
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion packages/web/src/components/AppBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import AccountCircleIcon from '@mui/icons-material/AccountCircle';

import * as URLS from 'config/urls';
import AccountDropdownMenu from 'components/AccountDropdownMenu';
import TrialStatusBadge from 'components/TrialStatusBadge/index.ee';
import Container from 'components/Container';
import { FormattedMessage } from 'react-intl';
import { Link } from './style';
Expand Down Expand Up @@ -67,9 +68,10 @@ export default function AppBar(props: AppBarProps): React.ReactElement {
</Link>
</div>

<TrialStatusBadge />

<IconButton
size="large"
edge="start"
color="inherit"
onClick={handleAccountMenuOpen}
aria-controls={accountMenuId}
Expand Down
24 changes: 24 additions & 0 deletions packages/web/src/components/TrialStatusBadge/index.ee.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Chip } from './style.ee';

import * as URLS from 'config/urls';
import useTrialStatus from 'hooks/useTrialStatus.ee';

export default function TrialStatusBadge(): React.ReactElement {
const data = useTrialStatus();

if (!data) return <React.Fragment />;

const { message, status } = data;

return (
<Chip
component={Link}
to={URLS.SETTINGS_BILLING_AND_USAGE}
clickable
label={message}
color={status}
/>
);
}
13 changes: 13 additions & 0 deletions packages/web/src/components/TrialStatusBadge/style.ee.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { styled } from '@mui/material/styles';
import MuiChip, { chipClasses } from '@mui/material/Chip';

export const Chip = styled(MuiChip)`
&.${chipClasses.root} {
font-weight: 500;
}
&.${chipClasses.colorWarning} {
background: #fef3c7;
color: #78350f;
}
` as typeof MuiChip;
9 changes: 9 additions & 0 deletions packages/web/src/graphql/queries/get-trial-status.ee.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { gql } from '@apollo/client';

export const GET_TRIAL_STATUS = gql`
query GetTrialStatus {
getTrialStatus {
expireAt
}
}
`;
2 changes: 1 addition & 1 deletion packages/web/src/hooks/useBillingAndUsageData.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function transform(billingAndUsageData: NonNullable<UseBillingAndUsageDataReturn
}

type UseBillingAndUsageDataReturn = {
subscription: TSubscription,
subscription: TSubscription;
usage: {
task: number;
}
Expand Down
63 changes: 63 additions & 0 deletions packages/web/src/hooks/useTrialStatus.ee.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useQuery } from '@apollo/client';
import { DateTime } from 'luxon';

import { GET_TRIAL_STATUS } from 'graphql/queries/get-trial-status.ee';
import useFormatMessage from './useFormatMessage';

type UseTrialStatusReturn = {
expireAt: DateTime;
message: string;
status: 'error' | 'warning';
} | null;

function getDiffInDays(date: DateTime) {
const diffInDays = date.diffNow('days').days;
const roundedDiffInDays = Math.round(diffInDays);

return roundedDiffInDays;
}

function getFeedbackPayload(date: DateTime) {
const diffInDays = getDiffInDays(date);

if (diffInDays <= -1) {
return {
translationEntryId: 'trialBadge.over',
status: 'error' as const,
};
} else if (diffInDays <= 1) {
return {
translationEntryId: 'trialBadge.endsToday',
status: 'warning' as const,
}
} else {
return {
translationEntryId: 'trialBadge.xDaysLeft',
translationEntryValues: {
remainingDays: diffInDays
},
status: 'warning' as const,
}
}
}

export default function useTrialStatus(): UseTrialStatusReturn {
const formatMessage = useFormatMessage();
const { data, loading } = useQuery(GET_TRIAL_STATUS);

if (loading || !data.getTrialStatus) return null;

const expireAt = DateTime.fromMillis(Number(data.getTrialStatus.expireAt));

const {
translationEntryId,
translationEntryValues,
status,
} = getFeedbackPayload(expireAt);

return {
message: formatMessage(translationEntryId, translationEntryValues),
expireAt,
status
};
}
5 changes: 4 additions & 1 deletion packages/web/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,8 @@
"invoices.date": "Date",
"invoices.amount": "Amount",
"invoices.invoice": "Invoice",
"invoices.link": "Link"
"invoices.link": "Link",
"trialBadge.xDaysLeft": "{remainingDays} trial days left",
"trialBadge.endsToday": "Trial ends today",
"trialBadge.over": "Trial is over"
}

0 comments on commit afdbed6

Please sign in to comment.