Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / components / hooks / assistant / useAssistantSubscriptionStatus.ts
blob1989254a58be11268706f2edb4880bfe45328ed0
1 import { addDays, fromUnixTime, getUnixTime, isAfter, isBefore } from 'date-fns';
2 import { c } from 'ttag';
4 import { useUser } from '@proton/account/user/hooks';
5 import useAssistantTelemetry from '@proton/components/hooks/assistant/useAssistantTelemetry';
6 import { FeatureCode, useFeature } from '@proton/features';
8 import useNotifications from '../useNotifications';
10 export const ASSISTANT_TRIAL_TIME_DAYS = 14;
12 export type TrialStatus = 'trial-ongoing' | 'trial-ended' | 'trial-not-started' | 'is-paid' | 'no-trial';
14 // Prevent multiple starts in case of multiple start calls
15 let started = false;
17 export interface AssistantSubscriptionStatus {
18     canUseAssistant: boolean;
19     trialEndDate: Date | null;
20     trialStatus: TrialStatus;
21     start: () => void;
24 const useAssistantSubscriptionStatus = (): AssistantSubscriptionStatus => {
25     const [user] = useUser();
26     const { createNotification } = useNotifications();
27     const { sendFreeTrialStart } = useAssistantTelemetry();
28     const nowDate = new Date();
30     const hasAiAssistantAddon = !!user.NumAI;
31     const trialStartDateFeat = useFeature(FeatureCode.ComposerAssistantTrialStartDate);
32     const trialStartDate =
33         trialStartDateFeat.feature?.Value && typeof trialStartDateFeat.feature?.Value === 'number'
34             ? fromUnixTime(trialStartDateFeat.feature?.Value)
35             : null;
37     const endDate = trialStartDate ? addDays(trialStartDate, ASSISTANT_TRIAL_TIME_DAYS) : null;
39     const trialStatus: TrialStatus = (() => {
40         // Free users have no trial period
41         if (user.isFree) {
42             return 'no-trial';
43         }
45         if (hasAiAssistantAddon) {
46             return 'is-paid';
47         }
49         if (endDate && isBefore(nowDate, endDate)) {
50             return 'trial-ongoing';
51         }
53         if (endDate && isAfter(nowDate, endDate)) {
54             return 'trial-ended';
55         }
57         return 'trial-not-started';
58     })();
60     const start = async () => {
61         if (!started && !trialStartDate && !hasAiAssistantAddon) {
62             started = true;
63             await trialStartDateFeat.update(getUnixTime(new Date()));
64             createNotification({
65                 text: c('Notification').t`Trial started`,
66             });
67             sendFreeTrialStart();
68         }
69     };
71     return {
72         canUseAssistant: hasAiAssistantAddon && trialStatus !== 'trial-ended' && trialStatus !== 'no-trial',
73         trialEndDate: endDate,
74         trialStatus,
75         start,
76     };
79 export default useAssistantSubscriptionStatus;