Subscription Guard and Installation Guide

This commit is contained in:
ajaysi
2025-10-13 15:27:48 +05:30
parent c38812b6c5
commit b6debd80b7
13 changed files with 1176 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { Avatar, Box, Menu, MenuItem, Typography, Tooltip } from '@mui/material';
import { Avatar, Box, Menu, MenuItem, Typography, Tooltip, Chip } from '@mui/material';
import { useUser, useClerk } from '@clerk/clerk-react';
import { useSubscription } from '../../contexts/SubscriptionContext';
interface UserBadgeProps {
colorMode?: 'light' | 'dark';
@@ -9,6 +10,7 @@ interface UserBadgeProps {
const UserBadge: React.FC<UserBadgeProps> = ({ colorMode = 'light' }) => {
const { user, isSignedIn } = useUser();
const { signOut } = useClerk();
const { subscription } = useSubscription();
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
@@ -20,6 +22,22 @@ const UserBadge: React.FC<UserBadgeProps> = ({ colorMode = 'light' }) => {
if (!isSignedIn) return null;
// Get plan display info
const getPlanColor = () => {
switch (subscription?.plan) {
case 'free': return '#4caf50';
case 'basic': return '#2196f3';
case 'pro': return '#9c27b0';
case 'enterprise': return '#ff9800';
default: return '#757575';
}
};
const getPlanLabel = () => {
if (!subscription?.active) return 'No Plan';
return subscription.plan.charAt(0).toUpperCase() + subscription.plan.slice(1);
};
const handleOpen = (e: React.MouseEvent<HTMLElement>) => setAnchorEl(e.currentTarget);
const handleClose = () => setAnchorEl(null);
@@ -33,6 +51,20 @@ const UserBadge: React.FC<UserBadgeProps> = ({ colorMode = 'light' }) => {
return (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
{/* Subscription Plan Chip */}
<Chip
label={getPlanLabel()}
size="small"
sx={{
bgcolor: `${getPlanColor()}20`,
border: `1px solid ${getPlanColor()}`,
color: getPlanColor(),
fontWeight: 700,
fontSize: '0.75rem',
height: 24,
}}
/>
<Tooltip title={`${user?.fullName || user?.username || user?.primaryEmailAddress?.emailAddress || 'User'}`}>
<Avatar
onClick={handleOpen}
@@ -49,8 +81,9 @@ const UserBadge: React.FC<UserBadgeProps> = ({ colorMode = 'light' }) => {
{initials}
</Avatar>
</Tooltip>
<Menu anchorEl={anchorEl} open={open} onClose={handleClose} anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} transformOrigin={{ vertical: 'top', horizontal: 'right' }}>
<Box sx={{ px: 2, py: 1 }}>
<Box sx={{ px: 2, py: 1, borderBottom: '1px solid rgba(0,0,0,0.1)' }}>
<Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
{user?.fullName || user?.username || 'User'}
</Typography>
@@ -58,7 +91,28 @@ const UserBadge: React.FC<UserBadgeProps> = ({ colorMode = 'light' }) => {
{user?.primaryEmailAddress?.emailAddress}
</Typography>
</Box>
<MenuItem onClick={handleClose}>Signed in</MenuItem>
{/* Subscription Info in Menu */}
<Box sx={{ px: 2, py: 1.5, bgcolor: 'rgba(0,0,0,0.02)' }}>
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5 }}>
Current Plan
</Typography>
<Chip
label={getPlanLabel()}
size="small"
sx={{
bgcolor: `${getPlanColor()}20`,
border: `1px solid ${getPlanColor()}`,
color: getPlanColor(),
fontWeight: 700,
fontSize: '0.75rem',
}}
/>
</Box>
<MenuItem onClick={() => { handleClose(); window.location.href = '/pricing'; }}>
Manage Subscription
</MenuItem>
<MenuItem onClick={handleSignOut}>Sign out</MenuItem>
</Menu>
</Box>