Skip to content

Commit

Permalink
Augment SubscriptionCard component
Browse files Browse the repository at this point in the history
-Implement conditional rendering for unverified user
-Now the card becomes half disabled and is themed red with an Alert warning to strongly remind the user to verify their email
  • Loading branch information
haoyangw committed Oct 31, 2024
1 parent b79fae6 commit 7b3d003
Showing 1 changed file with 52 additions and 29 deletions.
81 changes: 52 additions & 29 deletions frontend/components/billing/subscription-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import JippyIconMd from "@/public/jippy-icon/jippy-icon-md";
import { JippyTierID, stripeSubscriptionStatusToTierStatus, SubscriptionPeriod, tierIDToPrice, tierIDToTierName } from "@/types/billing";
import { JippyTier, JippyTierID, stripeSubscriptionStatusToTierStatus, SubscriptionPeriod, tierIDToPrice, tierIDToTierName } from "@/types/billing";
import { Button } from "@/components/ui/button";
import Chip from "@/components/display/chip";
import { CalendarIcon, CircleDollarSignIcon } from "lucide-react";
import { CalendarIcon, CircleAlert, CircleDollarSignIcon } from "lucide-react";
import { UserPublic } from "@/client/types.gen";
import { useMemo } from "react";
import { useCreateStripeCustomerPortalSession } from "@/queries/billing";
import { Alert, AlertDescription } from "../ui/alert";

const MAX_CARD_HEIGHT_PX = 400;
const TIER_STATUS_ACTIVE = "active";
const UNVERIFIED_TIER_ID = 4;

export interface SubscriptionInfo {
user: UserPublic | undefined;
Expand Down Expand Up @@ -56,49 +58,70 @@ const SubscriptionCard = ({user}: SubscriptionInfo) => {
const tierSubscriptionPeriod = SubscriptionPeriod.Month;
const actionDescription = "Manage Subscription";

const isUserUnverified = user?.verified === false || user?.tier_id === UNVERIFIED_TIER_ID;

const stripeCustomerPortalMutation = useCreateStripeCustomerPortalSession();

const onClickManageSubscription = () => {
stripeCustomerPortalMutation.mutate();
};

return (
<Card className="flex flex-col items-stretch w-full" style={{ maxWidth: `${MAX_CARD_HEIGHT_PX}px` }}>
<Card className={`flex flex-col items-stretch w-full ${isUserUnverified && "border-red-500"}`} style={{ maxWidth: `${MAX_CARD_HEIGHT_PX}px` }}>
<CardHeader className="gap-y-4">
<CardTitle className="flex flex-row gap-x-4">
{/* TODO: Consider one day making an icon just for Jippy-branded subscriptions */}
<JippyIconMd />
<span className="grow text-start">Your Jippy</span>
</CardTitle>
<CardDescription className="flex flex-col gap-y-2 items-stretch h-fit">
<div className="flex flex-row gap-x-2 justify-start items-center">
<span className="text-lg">{currentTierName} Tier</span>
<Chip
className="w-fit"
label={tierStatus}
size="lg"
variant="primary"
/>
</div>
{ user?.subscription &&
<Button className="w-fit" onClick={onClickManageSubscription} variant="default">
{actionDescription}
</Button>
}
{!isUserUnverified ? (
<>
<div className="flex flex-row gap-x-2 justify-start items-center">
<span className="text-lg">{currentTierName} Tier</span>
<Chip
className="w-fit"
label={tierStatus}
size="lg"
variant="primary"
/>
</div>
{ user?.subscription &&
<Button className="w-fit" onClick={onClickManageSubscription} variant="default">
{actionDescription}
</Button>
}
</>
) : (
<div className="flex flex-col gap-y-2">
<span className="text-lg line-through">{JippyTier.Free} Tier</span>
<Alert className="flex flex-row items-center gap-x-4" variant="destructive">
<div className="flex items-center flex-shrink-0">
<CircleAlert className="h-5 w-5 stroke-red-500" />
</div>
<AlertDescription className="grow">
Unverified email. Verify your email now to enjoy full {JippyTier.Free} Tier access.
</AlertDescription>
</Alert>
</div>
)}
</CardDescription>
</CardHeader>
<hr />
<CardContent className="flex flex-col py-2">
<SubscriptionDetail
DetailIcon={CircleDollarSignIcon}
detailDescription={`$${tierPrice} per ${tierSubscriptionPeriod}`} />
{ tierEndDate &&
<SubscriptionDetail
DetailIcon={CalendarIcon}
detailDescription={`Renews ${tierEndDate.toLocaleDateString()}`}
/>
}
</CardContent>
{ !isUserUnverified && (
<>
<hr />
<CardContent className="flex flex-col py-2">
<SubscriptionDetail
DetailIcon={CircleDollarSignIcon}
detailDescription={`$${tierPrice} per ${tierSubscriptionPeriod}`} />
{tierEndDate &&
<SubscriptionDetail
DetailIcon={CalendarIcon}
detailDescription={`Renews ${tierEndDate.toLocaleDateString()}`} />
}
</CardContent>
</>
)}
</Card>
);
};
Expand Down

0 comments on commit 7b3d003

Please sign in to comment.