Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / containers / topBanners / StorageLimitTopBanner.tsx
blobe45cfd43b7e094be2e6f926452255080bb00a532
1 import type { ReactNode } from 'react';
3 import { c } from 'ttag';
5 import { useSubscription } from '@proton/account/subscription/hooks';
6 import { useUser } from '@proton/account/user/hooks';
7 import SettingsLink from '@proton/components/components/link/SettingsLink';
8 import useConfig from '@proton/components/hooks/useConfig';
9 import type { PLANS } from '@proton/payments';
10 import type { APP_NAMES } from '@proton/shared/lib/constants';
11 import {
12     APPS,
13     DRIVE_SHORT_APP_NAME,
14     MAIL_SHORT_APP_NAME,
15     SHARED_UPSELL_PATHS,
16     UPSELL_COMPONENT,
17 } from '@proton/shared/lib/constants';
18 import { addUpsellPath, getUpgradePath, getUpsellRefFromApp } from '@proton/shared/lib/helpers/upsell';
19 import type { Subscription, UserModel } from '@proton/shared/lib/interfaces';
20 import {
21     SpaceState,
22     getAppStorage,
23     getCompleteSpaceDetails,
24     getPlanToUpsell,
25     getSpace,
26 } from '@proton/shared/lib/user/storage';
28 import useLocalState from '../../hooks/useLocalState';
29 import LockedStateTopBanner from './LockedStateTopBanner';
30 import TopBanner from './TopBanner';
32 const IGNORE_STORAGE_LIMIT_KEY = 'ignore-storage-limit';
34 const getStr = (percentage: number, storage: ReactNode, cta: ReactNode) => {
35     if (percentage >= 100) {
36         // Translator: Your Drive storage is full. To upload or sync files, free up space or upgrade for more storage.
37         return c('storage_split: info').jt`Your ${storage} is full. ${cta}.`;
38     }
39     // Translator: Your Drive storage is 99% full. To upload or sync files, free up space or upgrade for more storage.
40     return c('storage_split: info').jt`Your ${storage} is ${percentage}% full. ${cta}.`;
43 const getStrFull = (percentage: number, storage: ReactNode, cta: ReactNode) => {
44     if (percentage >= 100) {
45         // Translator: Your storage is full. To upload or sync files, free up space or upgrade for more storage.
46         return c('storage_split: info').jt`Your storage is full. ${cta}.`;
47     }
48     // Translator: Your storage is 99% full. To upload or sync files, free up space or upgrade for more storage.
49     return c('storage_split: info').jt`Your storage is ${percentage}% full. ${cta}.`;
52 interface Props {
53     app: APP_NAMES;
56 const getStorageFull = ({
57     user,
58     subscription,
59     percentage,
60     mode,
61     upsellRef,
62     plan,
63     app,
64 }: {
65     user: UserModel;
66     subscription: Subscription | undefined;
67     percentage: number;
68     mode: 'mail' | 'drive' | 'both';
69     app?: APP_NAMES;
70     upsellRef: string | undefined;
71     plan: PLANS;
72 }): ReactNode => {
73     const upgrade = user.canPay ? (
74         <SettingsLink
75             key="storage-link"
76             className="color-inherit"
77             path={addUpsellPath(getUpgradePath({ user, plan, subscription }), upsellRef)}
78         >
79             {
80                 // Translator: To upload or sync files, free up space or upgrade for more storage
81                 c('storage_split: info').t`upgrade for more storage`
82             }
83         </SettingsLink>
84     ) : (
85         // Translator: To upload or sync files, contact your administrator
86         c('storage_split: info').t`contact your administrator`
87     );
89     const driveCta = c('storage_split: info').jt`To upload or sync files, free up space or ${upgrade}`;
90     const mailCta = c('storage_split: info').jt`To send or receive emails, free up space or ${upgrade}`;
92     if (mode === 'drive') {
93         return getStr(percentage, getAppStorage(DRIVE_SHORT_APP_NAME), driveCta);
94     }
95     if (mode === 'mail') {
96         return getStr(percentage, getAppStorage(MAIL_SHORT_APP_NAME), mailCta);
97     }
98     if (mode === 'both') {
99         if (app === APPS.PROTONDRIVE) {
100             return getStrFull(percentage, getAppStorage(DRIVE_SHORT_APP_NAME), driveCta);
101         }
102         return getStrFull(percentage, getAppStorage(DRIVE_SHORT_APP_NAME), mailCta);
103     }
106 const SplitStorageLimitTopBanner = ({
107     app,
108     user,
109     subscription,
110     upsellRef,
111     ignoreStorageLimit,
112     setIgnoreStorageLimit,
113     space,
114 }: {
115     app: APP_NAMES;
116     user: UserModel;
117     subscription: Subscription | undefined;
118     upsellRef: string | undefined;
119     ignoreStorageLimit: boolean;
120     setIgnoreStorageLimit: (value: boolean) => void;
121     space: ReturnType<typeof getSpace>;
122 }) => {
123     const details = getCompleteSpaceDetails(space);
124     const plan = getPlanToUpsell({ storageDetails: details, app });
126     if (details.base.type === SpaceState.Danger && details.drive.type === SpaceState.Danger) {
127         return (
128             <TopBanner className="bg-danger">
129                 {getStorageFull({
130                     plan,
131                     user,
132                     subscription,
133                     percentage: app === APPS.PROTONDRIVE ? details.drive.displayed : details.base.displayed,
134                     mode: 'both',
135                     app,
136                     upsellRef,
137                 })}
138             </TopBanner>
139         );
140     }
142     if (details.base.type === SpaceState.Danger) {
143         return (
144             <TopBanner className="bg-danger">
145                 {getStorageFull({
146                     plan,
147                     user,
148                     subscription,
149                     percentage: details.base.displayed,
150                     mode: 'mail',
151                     upsellRef,
152                 })}
153             </TopBanner>
154         );
155     }
157     if (details.drive.type === SpaceState.Danger && app === APPS.PROTONDRIVE) {
158         return (
159             <TopBanner className="bg-danger">
160                 {getStorageFull({
161                     plan,
162                     user,
163                     subscription,
164                     percentage: details.drive.displayed,
165                     mode: 'drive',
166                     upsellRef,
167                 })}
168             </TopBanner>
169         );
170     }
172     if (ignoreStorageLimit) {
173         return null;
174     }
176     if (details.drive.type === SpaceState.Warning && details.base.type === SpaceState.Warning) {
177         return (
178             <TopBanner className="bg-warning" onClose={() => setIgnoreStorageLimit(true)}>
179                 {getStorageFull({
180                     plan,
181                     user,
182                     subscription,
183                     percentage: app === APPS.PROTONDRIVE ? details.drive.displayed : details.base.displayed,
184                     mode: app === APPS.PROTONDRIVE ? 'drive' : 'mail',
185                     upsellRef,
186                 })}
187             </TopBanner>
188         );
189     }
191     if (details.drive.type === SpaceState.Warning && app === APPS.PROTONDRIVE) {
192         return (
193             <TopBanner className="bg-warning" onClose={() => setIgnoreStorageLimit(true)}>
194                 {getStorageFull({
195                     plan,
196                     user,
197                     subscription,
198                     percentage: details.drive.displayed,
199                     mode: 'drive',
200                     upsellRef,
201                 })}
202             </TopBanner>
203         );
204     }
206     if (details.base.type === SpaceState.Warning) {
207         return (
208             <TopBanner className="bg-warning" onClose={() => setIgnoreStorageLimit(true)}>
209                 {getStorageFull({
210                     plan,
211                     user,
212                     subscription,
213                     percentage: details.base.displayed,
214                     mode: 'mail',
215                     upsellRef,
216                 })}
217             </TopBanner>
218         );
219     }
221     return null;
224 const PooledStorageLimitTopBanner = ({
225     app,
226     user,
227     subscription,
228     upsellRef,
229     ignoreStorageLimit,
230     setIgnoreStorageLimit,
231     space,
232 }: {
233     app: APP_NAMES;
234     user: UserModel;
235     subscription: Subscription | undefined;
236     upsellRef: string | undefined;
237     ignoreStorageLimit: boolean;
238     setIgnoreStorageLimit: (value: boolean) => void;
239     space: ReturnType<typeof getSpace>;
240 }) => {
241     const details = getCompleteSpaceDetails(space);
242     const plan = getPlanToUpsell({ storageDetails: details, app });
244     if (details.pooled.type === SpaceState.Danger) {
245         return (
246             <TopBanner className="bg-danger">
247                 {getStorageFull({
248                     plan,
249                     user,
250                     subscription,
251                     percentage: details.pooled.displayed,
252                     mode: app === APPS.PROTONDRIVE ? 'drive' : 'mail',
253                     upsellRef,
254                 })}
255             </TopBanner>
256         );
257     }
259     if (ignoreStorageLimit) {
260         return null;
261     }
263     if (details.pooled.type === SpaceState.Warning) {
264         return (
265             <TopBanner className="bg-warning" onClose={() => setIgnoreStorageLimit(true)}>
266                 {getStorageFull({
267                     plan,
268                     user,
269                     subscription,
270                     percentage: details.pooled.displayed,
271                     mode: app === APPS.PROTONDRIVE ? 'drive' : 'mail',
272                     upsellRef,
273                 })}
274             </TopBanner>
275         );
276     }
278     return null;
281 const StorageLimitTopBanner = ({ app }: Props) => {
282     const [user] = useUser();
283     const [subscription] = useSubscription();
284     const { APP_NAME } = useConfig();
285     const [ignoreStorageLimit, setIgnoreStorageLimit] = useLocalState(false, `${IGNORE_STORAGE_LIMIT_KEY}${user.ID}`);
286     const space = getSpace(user);
288     const upsellRef = getUpsellRefFromApp({
289         app: APP_NAME,
290         feature: SHARED_UPSELL_PATHS.STORAGE_PERCENTAGE,
291         component: UPSELL_COMPONENT.MODAL,
292         fromApp: app,
293     });
295     if (user.LockedFlags) {
296         return (
297             <LockedStateTopBanner
298                 app={app}
299                 user={user}
300                 subscription={subscription}
301                 upsellRef={upsellRef}
302                 lockedFlags={user.LockedFlags}
303             />
304         );
305     }
307     return space.splitStorage ? (
308         <SplitStorageLimitTopBanner
309             app={app}
310             space={space}
311             user={user}
312             subscription={subscription}
313             upsellRef={upsellRef}
314             ignoreStorageLimit={ignoreStorageLimit}
315             setIgnoreStorageLimit={setIgnoreStorageLimit}
316         />
317     ) : (
318         <PooledStorageLimitTopBanner
319             app={app}
320             user={user}
321             subscription={subscription}
322             space={space}
323             upsellRef={upsellRef}
324             ignoreStorageLimit={ignoreStorageLimit}
325             setIgnoreStorageLimit={setIgnoreStorageLimit}
326         />
327     );
330 export default StorageLimitTopBanner;