102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
import React from 'react';
|
|
import { Card, CardContent, Typography, Button, Box, Chip, List, ListItem, ListItemIcon, ListItemText } from '@mui/material';
|
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
|
import type { SubscriptionPlan, BillingCycle } from '../types/subscription.types';
|
|
|
|
interface TierCardProps {
|
|
plan: SubscriptionPlan;
|
|
billingCycle: BillingCycle;
|
|
currentTier?: string;
|
|
isLoading?: boolean;
|
|
onUpgrade: () => void;
|
|
}
|
|
|
|
export const TierCard: React.FC<TierCardProps> = ({
|
|
plan,
|
|
billingCycle,
|
|
currentTier,
|
|
isLoading = false,
|
|
onUpgrade,
|
|
}) => {
|
|
const isCurrent = currentTier === plan.tier;
|
|
const price = billingCycle === 'monthly' ? plan.monthlyPrice : plan.yearlyPrice;
|
|
const priceLabel = billingCycle === 'monthly' ? '/month' : '/year';
|
|
|
|
return (
|
|
<Card
|
|
sx={{
|
|
height: '100%',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
position: 'relative',
|
|
border: isCurrent ? 2 : 1,
|
|
borderColor: isCurrent ? 'primary.main' : 'divider',
|
|
}}
|
|
>
|
|
{isCurrent && (
|
|
<Chip
|
|
label="Current Plan"
|
|
color="primary"
|
|
size="small"
|
|
sx={{
|
|
position: 'absolute',
|
|
top: 16,
|
|
right: 16,
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
<CardContent sx={{ flexGrow: 1, pt: isCurrent ? 6 : 3 }}>
|
|
<Typography variant="h5" component="h3" gutterBottom fontWeight="bold">
|
|
{plan.name}
|
|
</Typography>
|
|
|
|
<Box sx={{ my: 3 }}>
|
|
<Typography variant="h3" component="div" fontWeight="bold">
|
|
${price.toFixed(2)}
|
|
</Typography>
|
|
<Typography variant="body2" color="text.secondary">
|
|
{priceLabel}
|
|
</Typography>
|
|
</Box>
|
|
|
|
<List dense>
|
|
{plan.features.map((feature, index) => (
|
|
<ListItem key={index} disableGutters>
|
|
<ListItemIcon sx={{ minWidth: 36 }}>
|
|
<CheckCircleIcon color="primary" fontSize="small" />
|
|
</ListItemIcon>
|
|
<ListItemText
|
|
primary={feature}
|
|
primaryTypographyProps={{ variant: 'body2' }}
|
|
/>
|
|
</ListItem>
|
|
))}
|
|
</List>
|
|
</CardContent>
|
|
|
|
<CardContent sx={{ pt: 0 }}>
|
|
{isCurrent ? (
|
|
<Button
|
|
variant="outlined"
|
|
fullWidth
|
|
disabled
|
|
>
|
|
Current Plan
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
variant={plan.tier === 'enterprise' ? 'contained' : 'outlined'}
|
|
color="primary"
|
|
fullWidth
|
|
disabled={isLoading}
|
|
onClick={onUpgrade}
|
|
>
|
|
{plan.tier === 'free' ? 'Downgrade' : 'Upgrade'}
|
|
</Button>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
};
|