[web] Update storage card when family member's storage limit is configured

Sibling of https://github.com/ente-io/ente/pull/5123
This commit is contained in:
Manav Rathi
2025-02-21 17:14:09 +05:30
parent 5e32e975df
commit 8830deb619
2 changed files with 71 additions and 33 deletions

View File

@@ -3,6 +3,7 @@ import type { ButtonishProps } from "@/base/components/mui";
import { UnstyledButton } from "@/new/photos/components/UnstyledButton";
import type { UserDetails } from "@/new/photos/services/user-details";
import {
familyMemberStorageLimit,
familyUsage,
isPartOfFamilyWithOtherMembers,
} from "@/new/photos/services/user-details";
@@ -118,42 +119,63 @@ interface SubscriptionCardContentOverlayProps {
export const SubscriptionCardContentOverlay: React.FC<
SubscriptionCardContentOverlayProps
> = ({ userDetails }) => (
<Overlay>
<Stack
sx={{
height: "100%",
justifyContent: "space-between",
padding: "20px 16px",
}}
>
{isPartOfFamilyWithOtherMembers(userDetails) ? (
<FamilySubscriptionCardContents userDetails={userDetails} />
) : (
<IndividualSubscriptionCardContents userDetails={userDetails} />
)}
</Stack>
</Overlay>
);
const IndividualSubscriptionCardContents: React.FC<
SubscriptionCardContentOverlayProps
> = ({ userDetails }) => {
const totalStorage =
userDetails.subscription.storage + userDetails.storageBonus;
const inFamily = isPartOfFamilyWithOtherMembers(userDetails);
const storageLimit = inFamily
? familyMemberStorageLimit(userDetails)
: undefined;
return (
<>
<StorageSection storage={totalStorage} usage={userDetails.usage} />
<IndividualUsageSection
usage={userDetails.usage}
fileCount={userDetails.fileCount}
storage={totalStorage}
/>
</>
<Overlay>
<Stack
sx={{
height: "100%",
justifyContent: "space-between",
padding: "20px 16px",
}}
>
{inFamily ? (
storageLimit ? (
<UserSubscriptionCardContents
userDetails={userDetails}
totalStorage={storageLimit}
/>
) : (
<FamilySubscriptionCardContents
userDetails={userDetails}
/>
)
) : (
<UserSubscriptionCardContents
userDetails={userDetails}
totalStorage={
userDetails.subscription.storage +
userDetails.storageBonus
}
/>
)}
</Stack>
</Overlay>
);
};
type UserSubscriptionCardContentsProps = SubscriptionCardContentOverlayProps & {
totalStorage: number;
};
const UserSubscriptionCardContents: React.FC<
UserSubscriptionCardContentsProps
> = ({ userDetails, totalStorage }) => (
<>
<StorageSection storage={totalStorage} usage={userDetails.usage} />
<IndividualUsageSection
usage={userDetails.usage}
fileCount={userDetails.fileCount}
storage={totalStorage}
/>
</>
);
interface StorageSectionProps {
usage: number;
storage: number;

View File

@@ -56,6 +56,12 @@ const FamilyMember = z.object({
* Email address of the family member.
*/
email: z.string(),
/**
* `true` if this is the admin.
*
* This field will not be sent for invited members until they accept.
*/
isAdmin: z.boolean().nullish().transform(nullToUndefined),
/**
* Storage used by the family member.
*
@@ -63,11 +69,13 @@ const FamilyMember = z.object({
*/
usage: z.number().nullish().transform(nullToUndefined),
/**
* `true` if this is the admin.
* Storage limit allocated to the family member.
*
* This field will not be sent for invited members until they accept.
* This field will not be present unless the admin for the family plan has
* configured a member specific limit, in which case this will be the limit
* (in bytes) specifying the storage which this member can use.
*/
isAdmin: z.boolean().nullish().transform(nullToUndefined),
storageLimit: z.number().nullish().transform(nullToUndefined),
});
type FamilyMember = z.infer<typeof FamilyMember>;
@@ -484,6 +492,14 @@ export const isPartOfFamilyWithOtherMembers = (userDetails: UserDetails) =>
export const isFamilyAdmin = (userDetails: UserDetails) =>
userDetails.email == familyAdminEmail(userDetails);
/**
* Return the member specific storage limit for the user (represented by the
* given {@link userDetails}).
*/
export const familyMemberStorageLimit = (userDetails: UserDetails) =>
userDetails.familyData?.members.find((m) => m.email == userDetails.email)
?.storageLimit;
/**
* Return the email of the admin for the family plan, if any, that the user
* (represented by the given {@link userDetails}) is a part of.