@moontra/moonui 2.3.8 → 2.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui",
3
- "version": "2.3.8",
3
+ "version": "2.3.9",
4
4
  "description": "Premium React component library with modern design and customization",
5
5
  "author": "MoonUI",
6
6
  "license": "MIT",
@@ -1,261 +0,0 @@
1
- "use client"
2
-
3
- // Pro Component Wrapper - Simplified Version
4
- // Development: CLI auth required
5
- // Production: License key validation with 24h cache
6
-
7
- import React, { useState, useEffect } from 'react'
8
- import { cn } from '../../lib/utils'
9
- import { Badge } from './badge'
10
- import { Lock, Terminal, AlertCircle } from 'lucide-react'
11
-
12
- interface ProComponentWrapperProps {
13
- children: React.ReactNode
14
- componentId: string
15
- componentName?: string
16
- className?: string
17
- fallback?: React.ReactNode
18
- }
19
-
20
- interface LicenseCache {
21
- timestamp: number
22
- hasProAccess: boolean
23
- }
24
-
25
- const CACHE_KEY = 'moonui_license_cache'
26
- const CACHE_DURATION = 24 * 60 * 60 * 1000 // 24 hours
27
-
28
- export function ProComponentWrapper({
29
- children,
30
- componentId,
31
- componentName,
32
- className,
33
- fallback
34
- }: ProComponentWrapperProps) {
35
- const [state, setState] = useState<{
36
- hasAccess: boolean
37
- loading: boolean
38
- message?: string
39
- }>({
40
- hasAccess: false,
41
- loading: true
42
- })
43
-
44
- useEffect(() => {
45
- // Check if development environment
46
- const isDevelopment = () => {
47
- if (typeof window === 'undefined') return false
48
-
49
- const isLocalhost =
50
- window.location.hostname === 'localhost' ||
51
- window.location.hostname === '127.0.0.1' ||
52
- window.location.hostname.includes('.local')
53
-
54
- const isDevPort =
55
- window.location.port === '3000' ||
56
- window.location.port === '3001' ||
57
- window.location.port === '8080' ||
58
- window.location.port === '5173'
59
-
60
- // Must be localhost with dev port
61
- return process.env.NODE_ENV === 'development' && isLocalhost && isDevPort
62
- }
63
-
64
- // DEVELOPMENT: Check CLI auth
65
- if (isDevelopment()) {
66
- const checkDevAuth = () => {
67
- const cliToken = localStorage.getItem('moonui_cli_token')
68
- const deviceId = localStorage.getItem('moonui_device_id')
69
-
70
- if (!cliToken || !deviceId) {
71
- setState({
72
- hasAccess: false,
73
- loading: false,
74
- message: 'CLI authentication required'
75
- })
76
- return
77
- }
78
-
79
- // Token exists - allow access
80
- setState({
81
- hasAccess: true,
82
- loading: false
83
- })
84
- }
85
-
86
- checkDevAuth()
87
- return
88
- }
89
-
90
- // PRODUCTION: Check license cache
91
- const checkProdLicense = () => {
92
- try {
93
- // Check cache first
94
- const cached = localStorage.getItem(CACHE_KEY)
95
- if (cached) {
96
- const data = JSON.parse(cached) as LicenseCache
97
- const now = Date.now()
98
-
99
- // Cache still valid (24 hours)
100
- if (data.timestamp && (now - data.timestamp) < CACHE_DURATION) {
101
- setState({
102
- hasAccess: data.hasProAccess,
103
- loading: false
104
- })
105
- return
106
- }
107
- }
108
-
109
- // No valid cache - need license key
110
- const licenseKey = process.env.NEXT_PUBLIC_MOONUI_LICENSE_KEY
111
-
112
- if (!licenseKey) {
113
- setState({
114
- hasAccess: false,
115
- loading: false,
116
- message: 'No license key configured'
117
- })
118
- return
119
- }
120
-
121
- // Validate license async
122
- validateLicense(licenseKey).then(result => {
123
- // Save to cache
124
- const cacheData: LicenseCache = {
125
- timestamp: Date.now(),
126
- hasProAccess: result.hasProAccess
127
- }
128
- localStorage.setItem(CACHE_KEY, JSON.stringify(cacheData))
129
-
130
- setState({
131
- hasAccess: result.hasProAccess,
132
- loading: false
133
- })
134
- }).catch(error => {
135
- console.error('License validation failed:', error)
136
-
137
- // Try expired cache as fallback
138
- const cached = localStorage.getItem(CACHE_KEY)
139
- if (cached) {
140
- const data = JSON.parse(cached) as LicenseCache
141
- setState({
142
- hasAccess: data.hasProAccess,
143
- loading: false,
144
- message: 'Using cached license'
145
- })
146
- } else {
147
- setState({
148
- hasAccess: false,
149
- loading: false,
150
- message: 'License validation failed'
151
- })
152
- }
153
- })
154
-
155
- } catch (error) {
156
- console.error('License check error:', error)
157
- setState({
158
- hasAccess: false,
159
- loading: false,
160
- message: 'License check failed'
161
- })
162
- }
163
- }
164
-
165
- checkProdLicense()
166
- }, [])
167
-
168
- // Loading state
169
- if (state.loading) {
170
- return (
171
- <div className={cn("animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-32", className)}>
172
- <div className="flex items-center justify-center h-full">
173
- <div className="text-sm text-gray-500">Loading...</div>
174
- </div>
175
- </div>
176
- )
177
- }
178
-
179
- // Access granted
180
- if (state.hasAccess) {
181
- return <>{children}</>
182
- }
183
-
184
- // Development: Show CLI auth required
185
- if (state.message === 'CLI authentication required') {
186
- return (
187
- <div className={cn("relative", className)}>
188
- <div className="blur-sm grayscale opacity-60 pointer-events-none">
189
- {fallback || children}
190
- </div>
191
- <div className="absolute inset-0 bg-gradient-to-br from-blue-500/10 via-transparent to-purple-500/10 border-2 border-dashed border-blue-400/30 rounded-lg flex items-center justify-center">
192
- <div className="text-center space-y-3 p-6 bg-white/90 dark:bg-gray-900/90 rounded-lg">
193
- <Badge variant="secondary" className="mb-2">
194
- <Terminal className="w-3 h-3 mr-1" />
195
- DEV AUTH REQUIRED
196
- </Badge>
197
- <h3 className="font-semibold">CLI Authentication Required</h3>
198
- <p className="text-sm text-gray-600 dark:text-gray-400 max-w-xs">
199
- Login with MoonUI CLI to use Pro components in development
200
- </p>
201
- <code className="block bg-black text-green-400 p-2 rounded text-xs font-mono">
202
- npx moonui auth login
203
- </code>
204
- </div>
205
- </div>
206
- </div>
207
- )
208
- }
209
-
210
- // Production: Show license required
211
- return (
212
- <div className={cn("relative", className)}>
213
- <div className="blur-sm grayscale opacity-60 pointer-events-none">
214
- {fallback || children}
215
- </div>
216
- <div className="absolute inset-0 bg-gradient-to-br from-amber-500/10 via-transparent to-orange-500/10 border-2 border-dashed border-amber-400/30 rounded-lg flex items-center justify-center">
217
- <div className="text-center space-y-3 p-6 bg-white/90 dark:bg-gray-900/90 rounded-lg">
218
- <Badge variant="destructive" className="mb-2">
219
- <AlertCircle className="w-3 h-3 mr-1" />
220
- LICENSE REQUIRED
221
- </Badge>
222
- <h3 className="font-semibold">{componentName || componentId}</h3>
223
- <p className="text-sm text-gray-600 dark:text-gray-400 max-w-xs">
224
- {state.message || 'Pro license required to use this component'}
225
- </p>
226
- <a
227
- href="https://moonui.dev/pricing"
228
- target="_blank"
229
- rel="noopener noreferrer"
230
- className="inline-block bg-gradient-to-r from-amber-500 to-orange-500 text-white px-4 py-2 rounded-lg text-sm font-medium hover:from-amber-600 hover:to-orange-600 transition-colors"
231
- >
232
- Get Pro License
233
- </a>
234
- </div>
235
- </div>
236
- </div>
237
- )
238
- }
239
-
240
- // Validate license with API
241
- async function validateLicense(licenseKey: string): Promise<{ hasProAccess: boolean }> {
242
- const response = await fetch('/api/v1/license/validate', {
243
- method: 'POST',
244
- headers: {
245
- 'Content-Type': 'application/json'
246
- },
247
- body: JSON.stringify({
248
- licenseKey,
249
- domain: window.location.hostname
250
- })
251
- })
252
-
253
- if (!response.ok) {
254
- throw new Error('License validation failed')
255
- }
256
-
257
- const data = await response.json()
258
- return {
259
- hasProAccess: data.hasProAccess || false
260
- }
261
- }