"use client" // Locked Component UI // Pro componentlerin locked state'ini gösteren wrapper component import React, { useState, useEffect } from 'react' import { cn } from '../../lib/utils' import { Button } from './button' import { Badge } from './badge' import { Lock, Crown, Zap, AlertCircle } from 'lucide-react' interface LockedComponentProps { children: React.ReactNode componentName: string className?: string showPreview?: boolean previewDuration?: number // ms } export function LockedComponent({ children, componentName, className, showPreview = true, previewDuration = 2000 }: LockedComponentProps) { const [isPreviewActive, setIsPreviewActive] = useState(false) const [previewTimeout, setPreviewTimeout] = useState(null) const handleMouseEnter = () => { if (!showPreview) return setIsPreviewActive(true) // Clear existing timeout if (previewTimeout) { clearTimeout(previewTimeout) } // Set new timeout const timeout = setTimeout(() => { setIsPreviewActive(false) }, previewDuration) setPreviewTimeout(timeout) } const handleMouseLeave = () => { if (previewTimeout) { clearTimeout(previewTimeout) setPreviewTimeout(null) } setIsPreviewActive(false) } return (
{/* Component Content */}
{children}
{/* Overlay */}
{/* Pro Badge */}
PRO ONLY
{/* Lock Icon */}
{/* Component Name */}

{componentName}

{/* Description */}

This premium component is available with Pro subscription

{/* Upgrade Button */}
{/* Preview Hint */} {showPreview && !isPreviewActive && (
Hover to preview
)}
) } // Pro Component Wrapper - Otomatik erişim kontrolü ile interface ProComponentWrapperProps { children: React.ReactNode componentId: string componentName?: string className?: string fallback?: React.ReactNode requireCLI?: boolean } export function ProComponentWrapper({ children, componentId, componentName, className, fallback, requireCLI = true }: ProComponentWrapperProps) { const [authState, setAuthState] = useState<{ isAuthenticated: boolean deviceValid: boolean hasProAccess: boolean loading: boolean }>({ isAuthenticated: false, deviceValid: false, hasProAccess: false, loading: true }) useEffect(() => { // Enhanced environment detection - prevent manipulation const isDevelopment = () => { // Check multiple indicators to prevent spoofing const checks = { nodeEnv: process.env.NODE_ENV === 'development', nextPublicEnv: process.env.NEXT_PUBLIC_VERCEL_ENV === 'development', localhost: typeof window !== 'undefined' && ( window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' || window.location.hostname.includes('.local') ), port: typeof window !== 'undefined' && ( window.location.port === '3000' || window.location.port === '3001' || window.location.port === '8080' ), vercelEnv: !process.env.VERCEL, ciEnv: !process.env.CI, deploymentEnv: !process.env.DEPLOYMENT_ENV } // If running on Vercel, Netlify, or any deployment platform - it's production if (process.env.VERCEL || process.env.NETLIFY || process.env.RENDER || process.env.RAILWAY_ENVIRONMENT || process.env.FLY_APP_NAME || process.env.DEPLOYMENT_ENV === 'production') { return false } // Must be localhost AND development env return checks.nodeEnv && checks.localhost && !checks.vercelEnv && !checks.ciEnv } // Skip checks only in true production or if not requiring CLI if (!isDevelopment() || !requireCLI) { setAuthState({ isAuthenticated: true, deviceValid: true, hasProAccess: true, loading: false }) return } // Check CLI authentication in development async function checkAuth() { try { const cliToken = localStorage.getItem('moonui_cli_token') const deviceId = localStorage.getItem('moonui_device_id') if (!cliToken || !deviceId) { setAuthState({ isAuthenticated: false, deviceValid: false, hasProAccess: false, loading: false }) return } // Validate token and device with API const response = await fetch('/api/device/validate', { method: 'POST', headers: { 'Authorization': `Bearer ${cliToken}`, 'X-Device-ID': deviceId, 'Content-Type': 'application/json' }, body: JSON.stringify({ environment: { nodeEnv: process.env.NODE_ENV, hostname: window.location.hostname, port: window.location.port, protocol: window.location.protocol } }) }) if (response.ok) { const data = await response.json() setAuthState({ isAuthenticated: true, deviceValid: data.valid, hasProAccess: data.hasProAccess, loading: false }) } else { setAuthState({ isAuthenticated: false, deviceValid: false, hasProAccess: false, loading: false }) } } catch (error) { setAuthState({ isAuthenticated: false, deviceValid: false, hasProAccess: false, loading: false }) } } checkAuth() }, [requireCLI]) // Loading state if (authState.loading) { return (
Loading...
) } // Development mode checks - use same enhanced detection const isDevelopment = () => { const checks = { nodeEnv: process.env.NODE_ENV === 'development', localhost: typeof window !== 'undefined' && ( window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' || window.location.hostname.includes('.local') ), port: typeof window !== 'undefined' && ( window.location.port === '3000' || window.location.port === '3001' || window.location.port === '8080' ) } if (process.env.VERCEL || process.env.NETLIFY || process.env.RENDER || process.env.RAILWAY_ENVIRONMENT || process.env.FLY_APP_NAME) { return false } return checks.nodeEnv && checks.localhost } if (isDevelopment() && requireCLI) { // Not authenticated if (!authState.isAuthenticated) { return (
{fallback || children}
CLI AUTH REQUIRED

CLI Authentication Required

Run the following command to authenticate:

npx moonui auth login
) } // Device not valid if (!authState.deviceValid) { return (
{fallback || children}
DEVICE LIMIT

Device Limit Exceeded

This device is not registered or you've reached your device limit

) } // No pro access if (!authState.hasProAccess) { return ( {fallback || children} ) } } // All checks passed - show component return
{children}
} // Pro Badge Component export function ProBadge({ className }: { className?: string }) { return ( PRO ) } // Free Badge Component export function FreeBadge({ className }: { className?: string }) { return ( FREE ) }