Phone
diff --git a/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/ConfirmUpdatedMembersModal.tsx b/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/ConfirmUpdatedMembersModal.tsx
new file mode 100644
index 000000000..6e4b16eaa
--- /dev/null
+++ b/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/ConfirmUpdatedMembersModal.tsx
@@ -0,0 +1,108 @@
+import { Button } from '@internxt/internxtui';
+import { StoragePlan } from '@internxt/sdk/dist/drive/payments/types';
+import { ArrowRight } from '@phosphor-icons/react';
+import { bytesToString } from 'app/drive/services/size.service';
+import { Translate } from 'app/i18n/types';
+import Modal from 'app/shared/components/Modal';
+
+interface ConfirmUpdateMembersModalProps {
+ isOpen: boolean;
+ plan: StoragePlan;
+ updatedAmountOfSeats: number;
+ isConfirmingMembersWorkspace: boolean;
+ translate: Translate;
+ onConfirmUpdate: () => void;
+ onClose: () => void;
+}
+
+export const ConfirmUpdatedMembersModal = ({
+ isOpen,
+ plan,
+ updatedAmountOfSeats,
+ isConfirmingMembersWorkspace,
+ translate,
+ onConfirmUpdate,
+ onClose,
+}: ConfirmUpdateMembersModalProps): JSX.Element => {
+ const currentAmountOfSeats = plan.amountOfSeats;
+ const storagePerUser = plan.storageLimit;
+ const monthlyPrice = plan.monthlyPrice;
+ const warnMessageKey =
+ currentAmountOfSeats && currentAmountOfSeats < updatedAmountOfSeats ? 'increaseStorage' : 'decreaseStorage';
+ const currentTotalStorage = currentAmountOfSeats && bytesToString(storagePerUser * currentAmountOfSeats);
+ const updatedTotalStorage = bytesToString(storagePerUser * updatedAmountOfSeats);
+
+ return (
+
+
+
+ {translate('preferences.workspace.billing.members.confirmUpdateModal.title')}
+
+
+ {translate('preferences.workspace.billing.members.confirmUpdateModal.confirmToProceed.text1')}
+ {currentAmountOfSeats}{' '}
+ {translate('preferences.workspace.billing.members.confirmUpdateModal.confirmToProceed.to')}
+ {updatedAmountOfSeats}{' '}
+ {translate('preferences.workspace.billing.members.confirmUpdateModal.confirmToProceed.text2')}
+
+
+
+ {
+
+ {translate(`preferences.workspace.billing.members.confirmUpdateModal.${warnMessageKey}.text`)}
+ {currentTotalStorage}
+ {translate(`preferences.workspace.billing.members.confirmUpdateModal.${warnMessageKey}.to`)}
+ {updatedTotalStorage}
+
+ }
+
+
+
+
+
+
+
+ );
+};
+
+const MembersCard = ({
+ members,
+ price,
+ label,
+ translate,
+}: {
+ members: number;
+ price: string;
+ label: string;
+ translate: Translate;
+}): JSX.Element => {
+ return (
+
+
+
+ {members} {translate('preferences.workspace.billing.membersLabel')}
+
+
€{price}/year
+
+ );
+};
diff --git a/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/SelectNewMembersModal.tsx b/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/SelectNewMembersModal.tsx
new file mode 100644
index 000000000..7ce5a9e30
--- /dev/null
+++ b/src/app/newSettings/Sections/Workspace/Billing/components/UpdateMembers/SelectNewMembersModal.tsx
@@ -0,0 +1,107 @@
+import { Button, RangeSlider } from '@internxt/internxtui';
+import { X } from '@phosphor-icons/react';
+import { Translate } from '../../../../../../i18n/types';
+import Modal from '../../../../../../shared/components/Modal';
+import { StoragePlan } from '@internxt/sdk/dist/drive/payments/types';
+
+interface SeatsProps {
+ minimumAllowedSeats: number;
+ maximumAllowedSeats?: number;
+ currentAmountOfSeats?: number;
+ updatedAmountOfSeats: number;
+ actualMembersInWorkspace: number;
+}
+
+interface UpdateMembersModalProps {
+ isOpen: boolean;
+ plan: StoragePlan;
+ joinedUsers?: number;
+ updatedAmountOfSeats?: number;
+ onSaveChanges: () => void;
+ handleUpdateMembers: (value: number) => void;
+ onClose: () => void;
+ translate: Translate;
+}
+
+export const SelectNewMembersModal = ({
+ isOpen,
+ plan,
+ joinedUsers,
+ updatedAmountOfSeats,
+ onSaveChanges,
+ handleUpdateMembers,
+ translate,
+ onClose,
+}: UpdateMembersModalProps): JSX.Element => {
+ const seats: SeatsProps = {
+ currentAmountOfSeats: plan.amountOfSeats,
+ actualMembersInWorkspace: joinedUsers as number,
+ minimumAllowedSeats: Math.max(joinedUsers as number, plan.seats?.minimumSeats as number) ?? 3,
+ maximumAllowedSeats: plan.seats?.maximumSeats,
+ updatedAmountOfSeats: updatedAmountOfSeats as number,
+ };
+
+ return (
+
+
+
+ {translate('preferences.workspace.members.actions.modifyStorage')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const UpdateMembersCard = ({
+ translate,
+ seats,
+ handleUpdateMembers,
+}: Pick
& {
+ seats: SeatsProps;
+}): JSX.Element => {
+ return (
+ <>
+ {translate('preferences.workspace.billing.members.expandNumber')}
+
+
+
+
{seats.currentAmountOfSeats}
+
{translate('preferences.workspace.billing.membersLabel')}
+
+
+
+
{seats.updatedAmountOfSeats}
+
{translate('preferences.workspace.billing.membersLabel')}
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/app/newSettings/Sections/Workspace/Billing/containers/BillingWorkspaceOverview.tsx b/src/app/newSettings/Sections/Workspace/Billing/containers/BillingWorkspaceOverview.tsx
index 6d73bfb71..0bc49bfef 100644
--- a/src/app/newSettings/Sections/Workspace/Billing/containers/BillingWorkspaceOverview.tsx
+++ b/src/app/newSettings/Sections/Workspace/Billing/containers/BillingWorkspaceOverview.tsx
@@ -15,21 +15,26 @@ interface BillingWorkspaceOverviewProps {
const BillingWorkspaceOverview = ({ plan }: BillingWorkspaceOverviewProps) => {
const local = localStorageService.get('i18nextLng') ?? navigator.language.split('-')[0];
- const isFreeSuscription = plan.businessSubscription?.type === 'free';
+ const isFreeSubscription = plan.businessSubscription?.type === 'free';
const subscriptionData: { amountInterval: string; interval: 'monthly' | 'yearly'; renewDate: string } | undefined =
getSubscriptionData({ userSubscription: plan.businessSubscription, plan, local, userType: UserType.Business });
const nextBillingDate = getNextBillingDate(plan.businessSubscription);
const [integerPart, decimalPart] = subscriptionData?.amountInterval?.split('.') ?? [];
+ const totalStorageInBytes =
+ plan.businessPlan && bytesToString(plan.businessPlan?.storageLimit * plan.businessPlan?.amountOfSeats);
+ const totalMembersPerPlan = plan.businessPlan?.amountOfSeats;
+ const storagePerUserInBytes = plan.businessPlan && bytesToString(plan.businessPlan?.storageLimit);
+
return (
- {!isFreeSuscription ? (
+ {!isFreeSubscription ? (
nextBillingDate &&
integerPart &&
decimalPart && (
- <>
-
+
+
{subscriptionData?.renewDate}
@@ -37,17 +42,31 @@ const BillingWorkspaceOverview = ({ plan }: BillingWorkspaceOverviewProps) => {
-
+
{integerPart}.{decimalPart}
- {t('preferences.workspace.billing.planLimit', { planLimit: bytesToString(plan.businessPlanLimit) })}
+ {t('preferences.workspace.billing.planLimit', {
+ planLimit: totalStorageInBytes,
+ })}
+
+
+
+
+
+
+ {totalMembersPerPlan}{' '}
+ {t('preferences.workspace.billing.membersLabel')}
+
+
{plan.businessPlan?.name}
+
+ {storagePerUserInBytes + ' ' + t('preferences.workspace.billing.perUser')}
- >
+
)
) : (
diff --git a/src/app/newSettings/Sections/Workspace/Overview/OverviewSection.tsx b/src/app/newSettings/Sections/Workspace/Overview/OverviewSection.tsx
index 093b32b92..c40eaa465 100644
--- a/src/app/newSettings/Sections/Workspace/Overview/OverviewSection.tsx
+++ b/src/app/newSettings/Sections/Workspace/Overview/OverviewSection.tsx
@@ -423,7 +423,7 @@ const WorkspaceProfileCard: React.FC = ({