diff --git a/frontend/src/components/Licensed.jsx b/frontend/src/components/Licensed.jsx new file mode 100644 index 00000000..afc96cea --- /dev/null +++ b/frontend/src/components/Licensed.jsx @@ -0,0 +1,357 @@ + + +import { + CheckCircle, + Warning as AlertCircle, + Shield as ShieldIcon, + Warning as WarningIcon, + ChevronRight as ChevronRightIcon +} from '@mui/icons-material'; +import { useContext, useState } from "react"; +import { Context } from "../context/ContextApi.jsx"; +import { useNavigate } from 'react-router-dom'; + +const Licensed = ({licensed, expanded, showBadge}) => { + + const { themeMode } = useContext(Context); + const navigate = useNavigate() + + + const [isHovered, setIsHovered] = useState(false); + + const theme = { + light: { + cardBg: '#ffffff', + cardBgHover: '#f5f7fa', + border: '#e1e4e8', + textPrimary: '#1f2937', + textSecondary: '#6b7280', + textMuted: '#9ca3af', + success: '#10b981', + successBg: licensed ? 'rgba(5, 150, 105, 0.08)' : '#ddf4ff', + successBorder: 'rgba(5, 150, 105, 0.2)', + warning: '#d97706', + warningBg: licensed ? '#fef3c7' : 'rgba(245, 158, 11, 0.08)', + warningBorder: 'rgba(245, 158, 11, 0.2)', + shadow: 'rgba(0, 0, 0, 0.05)', + }, + dark: { + cardBg: '#1a1a1a', + cardBgHover: '#242424', + border: '#30363d', + textPrimary: '#e6edf3', + textSecondary: '#8b949e', + textMuted: '#6e7681', + success: '#10b981', + successBg: 'rgba(16, 185, 129, 0.1)', + successBorder: 'rgba(16, 185, 129, 0.3)', + warning: '#f59e0b', + warningBg: 'rgba(245, 158, 11, 0.1)', + warningBorder: 'rgba(245, 158, 11, 0.3)', + shadow: 'rgba(0, 0, 0, 0.3)', + }, + }; + + const colors = themeMode === "dark" ? theme.dark : theme.light; + + const statusConfig = licensed + ? { + icon: showBadge ? ShieldIcon : CheckCircle, + text: showBadge ? 'Licensed' : 'Enterprise Licensed', + shortText: 'Licensed', + subtitle: 'Full access', + color: colors.success, + bgColor: colors.successBg, + borderColor: colors.successBorder, + description: 'All features unlocked', + } + : { + icon: showBadge ? WarningIcon : AlertCircle, + text: showBadge ? 'Unlicensed' : 'Activate License', + shortText: 'Inactive', + subtitle: 'Limited access', + color: colors.warning, + bgColor: colors.warningBg, + borderColor: colors.warningBorder, + description: 'Limited access', + }; + + const Icon = statusConfig.icon; + + // Display badge when showing license status only + // Display full component for CTA to license activation + if (showBadge) { + return ( +
{navigate('/admin?admin_tab=billingstats');}} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + style={{ + display: 'inline-flex', + alignItems: 'center', + gap: 8, + padding: '8px 14px', + borderRadius: 12, + cursor: 'pointer', + backgroundColor: statusConfig.bgColor, + border: `1.5px solid ${statusConfig.borderColor}`, + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', + transform: isHovered ? 'translateY(-2px)' : 'translateY(0)', + boxShadow: isHovered + ? `0 4px 12px ${colors.shadow}, 0 0 0 3px ${statusConfig.bgColor}` + : `0 2px 4px ${colors.shadow}`, + position: 'relative', + overflow: 'hidden', + }} + > + {/* Shine effect on hover */} +
+ + {/* Status indicator with pulse */} +
+ + {/* Pulse ring */} + +
+ + + +
+ + {statusConfig.text} + + + {statusConfig.subtitle} + +
+ + +
+ ); + } + + return ( +
{navigate('/admin?admin_tab=billingstats');}} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + style={{ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + gap: expanded ? 12 : 8, + padding: expanded ? '10px 14px' : '10px', + marginBottom: 20, + marginRight: 12, + borderRadius: 10, + cursor: 'pointer', + backgroundColor: isHovered ? colors.cardBgHover : colors.cardBg, + border: `1.5px solid ${licensed ? statusConfig.color : colors.border}`, + boxShadow: `0 1px 3px ${colors.shadow}`, + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', + transform: isHovered ? 'translateY(-1px)' : 'translateY(0)', + position: 'relative', + overflow: 'hidden', + }} + > +
+ + {/* Content */} +
+ {expanded && ( +
+ + {!licensed && ( +
+ )} +
+ )} + + {/* Text content */} + {expanded && ( +
+ + {statusConfig.text} + + + {statusConfig.description} + +
+ )} + + {!expanded && ( + + {licensed ? 'ON' : 'OFF'} + + )} +
+ + {/* Arrow indicator (only when expanded) */} + {expanded && ( + + )} +
+ ); +} + +export default Licensed; \ No newline at end of file