- accent.amber/amberDim/amberGlow -> accent.main/dim/glow 91건 (34파일). theme.ts의 @deprecated 별칭 참조 제거 (본체 main 사용). - inline fontSize/fontWeight -> d3roTypo, borderRadius -> d3roRadius 토큰 37건. - P4: 화면 고유 수치(스탯 fontSize, 레이아웃 width)는 토큰화 제외. 정책: docs/REFACTOR_POLICY.md DP1, 이식 인사이트 P4
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
// src/renderer/components/ProBadge.tsx
|
|
// Feature gate badge: renders children normally if unlocked,
|
|
// shows lock overlay with PRO badge if locked.
|
|
|
|
import { Box, Typography } from '@mui/material'
|
|
import { Lock } from 'lucide-react'
|
|
import { d3roPalette, d3roFontMono, d3roTypo, d3roRadius } from '@d3ro/ui/theme'
|
|
import { useProFeature } from '../hooks/useProFeature'
|
|
import { useI18n } from '@d3ro/i18n'
|
|
import type { Feature } from '@d3ro/core/types'
|
|
|
|
interface ProBadgeProps {
|
|
feature: Feature
|
|
children: React.ReactNode
|
|
}
|
|
|
|
export function ProBadge({ feature, children }: ProBadgeProps): React.ReactElement {
|
|
const { t } = useI18n()
|
|
const { unlocked, loading, showUpgrade } = useProFeature(feature)
|
|
|
|
// While loading or if unlocked, render children normally
|
|
if (loading || unlocked) {
|
|
return <>{children}</>
|
|
}
|
|
|
|
return (
|
|
<Box sx={{ position: 'relative' }}>
|
|
{/* Children rendered with reduced opacity */}
|
|
<Box sx={{ opacity: 0.35, pointerEvents: 'none', filter: 'grayscale(0.6)' }}>
|
|
{children}
|
|
</Box>
|
|
|
|
{/* Lock overlay */}
|
|
<Box
|
|
onClick={showUpgrade}
|
|
sx={{
|
|
position: 'absolute',
|
|
inset: 0,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
cursor: 'pointer',
|
|
borderRadius: d3roRadius.inner,
|
|
transition: 'background-color 0.15s ease',
|
|
'&:hover': {
|
|
bgcolor: d3roPalette.accent.dim,
|
|
},
|
|
}}
|
|
>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 0.5,
|
|
px: 1.5,
|
|
py: 0.5,
|
|
borderRadius: d3roRadius.small,
|
|
bgcolor: d3roPalette.bg.elevated,
|
|
border: `1px solid ${d3roPalette.border.default}`,
|
|
}}
|
|
>
|
|
<Lock size={14} style={{ color: d3roPalette.accent.main }} />
|
|
<Typography
|
|
sx={{
|
|
fontFamily: d3roFontMono,
|
|
fontSize: d3roTypo.small.size,
|
|
fontWeight: d3roTypo.small.weight,
|
|
letterSpacing: d3roTypo.small.spacing,
|
|
color: d3roPalette.accent.main,
|
|
}}
|
|
>
|
|
{t('license.pro.required')}
|
|
</Typography>
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
)
|
|
}
|