@moontra/moonui-pro 2.20.2 → 2.20.4

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.
Files changed (153) hide show
  1. package/package.json +8 -3
  2. package/plugin/index.d.ts +86 -0
  3. package/plugin/index.js +308 -0
  4. package/scripts/postinstall.js +191 -23
  5. package/src/components/advanced-chart/index.tsx +0 -1246
  6. package/src/components/advanced-forms/index.tsx +0 -585
  7. package/src/components/animated-button/index.tsx +0 -385
  8. package/src/components/calendar/event-dialog.tsx +0 -377
  9. package/src/components/calendar/index.tsx +0 -1220
  10. package/src/components/calendar-pro/index.tsx +0 -1697
  11. package/src/components/color-picker/index.tsx +0 -432
  12. package/src/components/credit-card-input/index.tsx +0 -406
  13. package/src/components/dashboard/dashboard-grid.tsx +0 -480
  14. package/src/components/dashboard/demo.tsx +0 -425
  15. package/src/components/dashboard/index.tsx +0 -1046
  16. package/src/components/dashboard/time-range-picker.tsx +0 -336
  17. package/src/components/dashboard/types.ts +0 -225
  18. package/src/components/dashboard/widgets/activity-feed.tsx +0 -349
  19. package/src/components/dashboard/widgets/chart-widget.tsx +0 -418
  20. package/src/components/dashboard/widgets/comparison-widget.tsx +0 -177
  21. package/src/components/dashboard/widgets/index.ts +0 -5
  22. package/src/components/dashboard/widgets/metric-card.tsx +0 -363
  23. package/src/components/dashboard/widgets/progress-widget.tsx +0 -113
  24. package/src/components/data-table/data-table-bulk-actions.tsx +0 -204
  25. package/src/components/data-table/data-table-column-toggle.tsx +0 -169
  26. package/src/components/data-table/data-table-export.ts +0 -156
  27. package/src/components/data-table/data-table-filter-drawer.tsx +0 -448
  28. package/src/components/data-table/index.tsx +0 -845
  29. package/src/components/draggable-list/index.tsx +0 -100
  30. package/src/components/error-boundary/index.tsx +0 -232
  31. package/src/components/file-upload/index.tsx +0 -1660
  32. package/src/components/floating-action-button/index.tsx +0 -206
  33. package/src/components/form-wizard/form-wizard-context.tsx +0 -335
  34. package/src/components/form-wizard/form-wizard-navigation.tsx +0 -118
  35. package/src/components/form-wizard/form-wizard-progress.tsx +0 -329
  36. package/src/components/form-wizard/form-wizard-step.tsx +0 -111
  37. package/src/components/form-wizard/index.tsx +0 -102
  38. package/src/components/form-wizard/types.ts +0 -77
  39. package/src/components/gesture-drawer/index.tsx +0 -551
  40. package/src/components/github-stars/github-api.ts +0 -426
  41. package/src/components/github-stars/hooks.ts +0 -517
  42. package/src/components/github-stars/index.tsx +0 -375
  43. package/src/components/github-stars/types.ts +0 -148
  44. package/src/components/github-stars/variants.tsx +0 -515
  45. package/src/components/health-check/index.tsx +0 -439
  46. package/src/components/hover-card-3d/index.tsx +0 -529
  47. package/src/components/index.ts +0 -130
  48. package/src/components/internal/index.ts +0 -78
  49. package/src/components/kanban/add-card-modal.tsx +0 -502
  50. package/src/components/kanban/card-detail-modal.tsx +0 -761
  51. package/src/components/kanban/index.ts +0 -13
  52. package/src/components/kanban/kanban.tsx +0 -1689
  53. package/src/components/kanban/types.ts +0 -168
  54. package/src/components/lazy-component/index.tsx +0 -823
  55. package/src/components/license-error/index.tsx +0 -31
  56. package/src/components/magnetic-button/index.tsx +0 -216
  57. package/src/components/memory-efficient-data/index.tsx +0 -1018
  58. package/src/components/moonui-quiz-form/index.tsx +0 -817
  59. package/src/components/navbar/index.tsx +0 -781
  60. package/src/components/optimized-image/index.tsx +0 -425
  61. package/src/components/performance-debugger/index.tsx +0 -613
  62. package/src/components/performance-monitor/index.tsx +0 -808
  63. package/src/components/phone-number-input/index.tsx +0 -343
  64. package/src/components/phone-number-input/phone-number-input-simple.tsx +0 -167
  65. package/src/components/pinch-zoom/index.tsx +0 -566
  66. package/src/components/quiz-form/index.tsx +0 -479
  67. package/src/components/rich-text-editor/index.tsx +0 -2322
  68. package/src/components/rich-text-editor/slash-commands-extension.ts +0 -230
  69. package/src/components/rich-text-editor/slash-commands.css +0 -35
  70. package/src/components/rich-text-editor/table-styles.css +0 -65
  71. package/src/components/sidebar/index.tsx +0 -884
  72. package/src/components/spotlight-card/index.tsx +0 -191
  73. package/src/components/swipeable-card/index.tsx +0 -100
  74. package/src/components/timeline/index.tsx +0 -1183
  75. package/src/components/ui/accordion.tsx +0 -581
  76. package/src/components/ui/alert-dialog.tsx +0 -141
  77. package/src/components/ui/alert.tsx +0 -141
  78. package/src/components/ui/aspect-ratio.tsx +0 -245
  79. package/src/components/ui/avatar.tsx +0 -155
  80. package/src/components/ui/badge.tsx +0 -230
  81. package/src/components/ui/breadcrumb.tsx +0 -216
  82. package/src/components/ui/button.tsx +0 -228
  83. package/src/components/ui/calendar.tsx +0 -387
  84. package/src/components/ui/card.tsx +0 -216
  85. package/src/components/ui/checkbox.tsx +0 -259
  86. package/src/components/ui/collapsible.tsx +0 -631
  87. package/src/components/ui/color-picker.tsx +0 -97
  88. package/src/components/ui/command.tsx +0 -948
  89. package/src/components/ui/dialog.tsx +0 -752
  90. package/src/components/ui/dropdown-menu.tsx +0 -706
  91. package/src/components/ui/gesture-drawer.tsx +0 -11
  92. package/src/components/ui/hover-card.tsx +0 -29
  93. package/src/components/ui/index.ts +0 -222
  94. package/src/components/ui/input.tsx +0 -224
  95. package/src/components/ui/label.tsx +0 -29
  96. package/src/components/ui/lightbox.tsx +0 -606
  97. package/src/components/ui/magnetic-button.tsx +0 -129
  98. package/src/components/ui/media-gallery.tsx +0 -611
  99. package/src/components/ui/navigation-menu.tsx +0 -130
  100. package/src/components/ui/pagination.tsx +0 -125
  101. package/src/components/ui/popover.tsx +0 -185
  102. package/src/components/ui/progress.tsx +0 -30
  103. package/src/components/ui/radio-group.tsx +0 -257
  104. package/src/components/ui/scroll-area.tsx +0 -47
  105. package/src/components/ui/select.tsx +0 -378
  106. package/src/components/ui/separator.tsx +0 -145
  107. package/src/components/ui/sheet.tsx +0 -139
  108. package/src/components/ui/skeleton.tsx +0 -20
  109. package/src/components/ui/slider.tsx +0 -354
  110. package/src/components/ui/spotlight-card.tsx +0 -119
  111. package/src/components/ui/switch.tsx +0 -86
  112. package/src/components/ui/table.tsx +0 -331
  113. package/src/components/ui/tabs-pro.tsx +0 -542
  114. package/src/components/ui/tabs.tsx +0 -54
  115. package/src/components/ui/textarea.tsx +0 -28
  116. package/src/components/ui/toast.tsx +0 -317
  117. package/src/components/ui/toggle.tsx +0 -119
  118. package/src/components/ui/tooltip.tsx +0 -151
  119. package/src/components/virtual-list/index.tsx +0 -668
  120. package/src/hooks/use-chart.ts +0 -205
  121. package/src/hooks/use-data-table.ts +0 -182
  122. package/src/hooks/use-docs-pro-access.ts +0 -13
  123. package/src/hooks/use-license-check.ts +0 -65
  124. package/src/hooks/use-subscription.ts +0 -19
  125. package/src/hooks/use-toast.ts +0 -15
  126. package/src/index.ts +0 -22
  127. package/src/lib/ai-providers.ts +0 -377
  128. package/src/lib/component-metadata.ts +0 -18
  129. package/src/lib/micro-interactions.ts +0 -255
  130. package/src/lib/paddle.ts +0 -17
  131. package/src/lib/utils.ts +0 -6
  132. package/src/patterns/login-form/index.tsx +0 -276
  133. package/src/patterns/login-form/types.ts +0 -67
  134. package/src/setupTests.ts +0 -41
  135. package/src/styles/advanced-chart.css +0 -239
  136. package/src/styles/calendar.css +0 -35
  137. package/src/styles/design-system.css +0 -363
  138. package/src/styles/index.css +0 -681
  139. package/src/styles/tailwind.css +0 -7
  140. package/src/styles/tokens.css +0 -455
  141. package/src/types/next-auth.d.ts +0 -21
  142. package/src/use-intersection-observer.tsx +0 -154
  143. package/src/use-local-storage.tsx +0 -71
  144. package/src/use-paddle.ts +0 -138
  145. package/src/use-performance-optimizer.ts +0 -389
  146. package/src/use-pro-access.ts +0 -141
  147. package/src/use-scroll-animation.ts +0 -219
  148. package/src/use-subscription.ts +0 -37
  149. package/src/use-toast.ts +0 -32
  150. package/src/utils/chart-helpers.ts +0 -357
  151. package/src/utils/cn.ts +0 -6
  152. package/src/utils/data-processing.ts +0 -151
  153. package/src/utils/license-validator.tsx +0 -183
@@ -1,517 +0,0 @@
1
- import { useState, useEffect, useCallback, useRef } from "react"
2
- import {
3
- GitHubRepository,
4
- GitHubStats,
5
- RateLimitInfo,
6
- StarHistory,
7
- Milestone,
8
- } from "./types"
9
- import {
10
- fetchUserRepositories,
11
- fetchRepository,
12
- fetchContributorsCount,
13
- fetchStarHistory,
14
- calculateStats,
15
- getRateLimitInfo,
16
- clearCache,
17
- } from "./github-api"
18
-
19
- interface UseGitHubDataOptions {
20
- username?: string
21
- repository?: string
22
- repositories?: string[]
23
- token?: string
24
- autoRefresh?: boolean
25
- refreshInterval?: number
26
- sortBy?: string
27
- maxItems?: number
28
- onError?: (error: Error) => void
29
- onDataUpdate?: (stats: GitHubStats) => void
30
- onMilestoneReached?: (milestone: Milestone) => void
31
- milestones?: number[]
32
- // For docs mode optimizations
33
- docsMode?: boolean
34
- mockDataFallback?: boolean
35
- forceMockData?: boolean // Force mock data instead of API
36
- }
37
-
38
- export function useGitHubData({
39
- username,
40
- repository,
41
- repositories,
42
- token,
43
- autoRefresh = false,
44
- refreshInterval = 300000,
45
- sortBy = "stars",
46
- maxItems,
47
- onError,
48
- onDataUpdate,
49
- onMilestoneReached,
50
- milestones = [10, 50, 100, 500, 1000, 5000, 10000],
51
- docsMode = false,
52
- mockDataFallback = true,
53
- forceMockData = false,
54
- }: UseGitHubDataOptions) {
55
- // Docs mode detection
56
- const isDocsMode = docsMode || (typeof window !== "undefined" &&
57
- (window.location.pathname.includes("/docs/") ||
58
- window.location.pathname.includes("/components/")))
59
-
60
- // Disable autoRefresh in docs mode
61
- const effectiveAutoRefresh = isDocsMode ? false : autoRefresh
62
- const [repos, setRepos] = useState<GitHubRepository[]>([])
63
- const [stats, setStats] = useState<GitHubStats | null>(null)
64
- const [loading, setLoading] = useState(true)
65
- const [error, setError] = useState<string | null>(null)
66
- const [rateLimitInfo, setRateLimitInfo] = useState<RateLimitInfo | null>(null)
67
- const [lastUpdated, setLastUpdated] = useState<Date | null>(null)
68
-
69
- const refreshTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)
70
- const previousStarsRef = useRef<Map<string, number>>(new Map())
71
- const errorCountRef = useRef<number>(0) // Hata sayısını takip et
72
- const maxErrorCount = isDocsMode ? 1 : 2 // Fewer retries in docs mode
73
- const hasInitialFetchedRef = useRef(false) // İlk fetch yapıldı mı?
74
- const docsDataCacheRef = useRef<GitHubRepository[] | null>(null) // Docs mode cache
75
-
76
- // Store checkMilestones function as ref - this way it won't be recreated on every render
77
- const milestonesRef = useRef(milestones)
78
- const onMilestoneReachedRef = useRef(onMilestoneReached)
79
-
80
- // Ref'leri güncelle
81
- useEffect(() => {
82
- milestonesRef.current = milestones
83
- }, [milestones])
84
-
85
- useEffect(() => {
86
- onMilestoneReachedRef.current = onMilestoneReached
87
- }, [onMilestoneReached])
88
-
89
- const checkMilestones = useCallback((repos: GitHubRepository[]) => {
90
- if (!onMilestoneReachedRef.current) return
91
-
92
- repos.forEach(repo => {
93
- const previousStars = previousStarsRef.current.get(repo.full_name) || 0
94
- const currentStars = repo.stargazers_count
95
-
96
- milestonesRef.current.forEach(milestone => {
97
- if (previousStars < milestone && currentStars >= milestone) {
98
- onMilestoneReachedRef.current?.({
99
- count: milestone,
100
- reached: true,
101
- date: new Date().toISOString(),
102
- celebration: true,
103
- })
104
- }
105
- })
106
-
107
- previousStarsRef.current.set(repo.full_name, currentStars)
108
- })
109
- }, []) // Boş dependency array - fonksiyon asla yeniden oluşturulmaz
110
-
111
- const fetchData = useCallback(async () => {
112
- // If forceMockData is true, always return mock data
113
- if (forceMockData) {
114
- console.log("[Mock Mode] Using mock data")
115
- const mockData = getMockGitHubData(username, repository, repositories)
116
- setRepos(mockData)
117
- const calculatedStats = calculateStats(mockData)
118
- setStats(calculatedStats)
119
- setError(null)
120
- setLoading(false)
121
- return
122
- }
123
-
124
- // Docs modunda ve daha önce fetch yapıldıysa, cache'den döndür
125
- if (isDocsMode && hasInitialFetchedRef.current && docsDataCacheRef.current) {
126
- console.log("[Docs Mode] Returning cached data, skipping API request")
127
- setRepos(docsDataCacheRef.current)
128
- const calculatedStats = calculateStats(docsDataCacheRef.current)
129
- setStats(calculatedStats)
130
- setLoading(false)
131
- return
132
- }
133
-
134
- // Hata limiti aşıldıysa istek yapma
135
- if (errorCountRef.current >= maxErrorCount) {
136
- console.warn("Maximum error count reached. Stopping requests.")
137
-
138
- // Show mock data if in docs mode and mockDataFallback is active
139
- if (isDocsMode && mockDataFallback) {
140
- const mockData = getMockGitHubData(username, repository, repositories)
141
- setRepos(mockData)
142
- const calculatedStats = calculateStats(mockData)
143
- setStats(calculatedStats)
144
- setError(null)
145
- } else {
146
- setError("Maximum retry limit exceeded. Please check your configuration.")
147
- }
148
-
149
- setLoading(false)
150
- return
151
- }
152
-
153
- // Don't make requests if required info is missing
154
- const hasValidInput =
155
- (username && repository) || // Tek repository modu
156
- (username && repositories && repositories.length > 0) || // Çoklu repository modu
157
- (repositories && repositories.length > 0 && repositories.every(r => r.includes('/'))) || // Full path repositories
158
- username // Kullanıcının tüm repositoryleri
159
-
160
- if (!hasValidInput) {
161
- console.warn("No valid input provided. Skipping API request.")
162
- setLoading(false)
163
- setError(null)
164
- setRepos([])
165
- setStats(null)
166
- return
167
- }
168
-
169
- try {
170
- setLoading(true)
171
- setError(null)
172
-
173
- // Check rate limit first
174
- try {
175
- const rateLimit = await getRateLimitInfo(token)
176
- setRateLimitInfo(rateLimit)
177
-
178
- if (rateLimit.remaining < 10) {
179
- console.warn(`Low GitHub API rate limit: ${rateLimit.remaining} requests remaining`)
180
- }
181
- } catch (error) {
182
- console.error("Failed to fetch rate limit:", error)
183
- }
184
-
185
- let fetchedRepos: GitHubRepository[] = []
186
-
187
- // Single repository mode
188
- if (repository && username) {
189
- const repo = await fetchRepository(username, repository, token)
190
- fetchedRepos = [repo]
191
- }
192
- // Multiple specific repositories with full paths
193
- else if (repositories && repositories.length > 0 && repositories.every(r => r.includes('/'))) {
194
- const repoPromises = repositories.map(fullPath => {
195
- const [owner, name] = fullPath.split('/')
196
- return fetchRepository(owner, name, token)
197
- })
198
- fetchedRepos = await Promise.all(repoPromises)
199
- }
200
- // Multiple specific repositories with username
201
- else if (repositories && repositories.length > 0 && username) {
202
- const repoPromises = repositories.map(repoName =>
203
- fetchRepository(username, repoName, token)
204
- )
205
- fetchedRepos = await Promise.all(repoPromises)
206
- }
207
- // All user repositories
208
- else if (username) {
209
- fetchedRepos = await fetchUserRepositories(username, token, {
210
- sort: sortBy,
211
- per_page: 100,
212
- })
213
- }
214
-
215
- // Sort repositories
216
- fetchedRepos.sort((a, b) => {
217
- switch (sortBy) {
218
- case "stars":
219
- return b.stargazers_count - a.stargazers_count
220
- case "forks":
221
- return b.forks_count - a.forks_count
222
- case "updated":
223
- return new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()
224
- case "created":
225
- return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
226
- case "name":
227
- return a.name.localeCompare(b.name)
228
- case "issues":
229
- return b.open_issues_count - a.open_issues_count
230
- default:
231
- return 0
232
- }
233
- })
234
-
235
- // Limit results
236
- if (maxItems && maxItems > 0) {
237
- fetchedRepos = fetchedRepos.slice(0, maxItems)
238
- }
239
-
240
- // Fetch additional data for detailed view
241
- const enhancedRepos = await Promise.all(
242
- fetchedRepos.map(async repo => {
243
- try {
244
- const contributorsCount = await fetchContributorsCount(
245
- repo.owner.login,
246
- repo.name,
247
- token
248
- )
249
- return { ...repo, contributors_count: contributorsCount }
250
- } catch (error) {
251
- console.error(`Failed to fetch contributors for ${repo.full_name}:`, error)
252
- return repo
253
- }
254
- })
255
- )
256
-
257
- setRepos(enhancedRepos)
258
-
259
- // Calculate statistics
260
- const calculatedStats = calculateStats(enhancedRepos)
261
- setStats(calculatedStats)
262
-
263
- // Check milestones
264
- checkMilestones(enhancedRepos)
265
-
266
- // Notify data update
267
- if (onDataUpdate) {
268
- onDataUpdate(calculatedStats)
269
- }
270
-
271
- setLastUpdated(new Date())
272
- // Reset error counter on success
273
- errorCountRef.current = 0
274
-
275
- // Cache successful data in docs mode
276
- if (isDocsMode) {
277
- hasInitialFetchedRef.current = true
278
- docsDataCacheRef.current = enhancedRepos
279
- }
280
- } catch (err) {
281
- const errorMessage = err instanceof Error ? err.message : "Failed to fetch data"
282
- setError(errorMessage)
283
-
284
- // Hata sayacını artır
285
- errorCountRef.current += 1
286
- console.error(`GitHub API error (${errorCountRef.current}/${maxErrorCount}):`, errorMessage)
287
-
288
- // Show mock data if in docs mode and mockDataFallback is active
289
- if (isDocsMode && mockDataFallback && !hasInitialFetchedRef.current) {
290
- console.warn("[Docs Mode] API failed, using mock data")
291
- const mockData = getMockGitHubData(username, repository, repositories)
292
- setRepos(mockData)
293
- const calculatedStats = calculateStats(mockData)
294
- setStats(calculatedStats)
295
- setError(null)
296
- hasInitialFetchedRef.current = true
297
- docsDataCacheRef.current = mockData
298
- } else if (onError) {
299
- onError(err instanceof Error ? err : new Error(errorMessage))
300
- }
301
- } finally {
302
- setLoading(false)
303
- }
304
- }, [
305
- username,
306
- repository,
307
- repositories?.join(','), // Convert array to string to keep reference stable
308
- token,
309
- sortBy,
310
- maxItems,
311
- checkMilestones, // Now stable
312
- onDataUpdate,
313
- onError,
314
- isDocsMode,
315
- mockDataFallback,
316
- forceMockData,
317
- ])
318
-
319
- // Initial fetch
320
- useEffect(() => {
321
- // Only fetch if there's valid input
322
- const hasValidInput =
323
- (username && repository) ||
324
- (username && repositories && repositories.length > 0) ||
325
- (repositories && repositories.length > 0 && repositories.every(r => r.includes('/'))) ||
326
- username
327
-
328
- if (hasValidInput) {
329
- fetchData()
330
- } else {
331
- setLoading(false)
332
- }
333
- }, [fetchData])
334
-
335
- // Auto-refresh
336
- useEffect(() => {
337
- // Completely disable auto-refresh in docs mode
338
- if (!effectiveAutoRefresh) return
339
-
340
- const scheduleRefresh = () => {
341
- refreshTimeoutRef.current = setTimeout(() => {
342
- fetchData()
343
- scheduleRefresh()
344
- }, refreshInterval)
345
- }
346
-
347
- scheduleRefresh()
348
-
349
- return () => {
350
- if (refreshTimeoutRef.current) {
351
- clearTimeout(refreshTimeoutRef.current)
352
- }
353
- }
354
- }, [effectiveAutoRefresh, refreshInterval, fetchData])
355
-
356
- const refresh = useCallback(() => {
357
- // Limit refresh in docs mode
358
- if (isDocsMode && hasInitialFetchedRef.current) {
359
- console.warn("[Docs Mode] Refresh disabled after initial fetch")
360
- return Promise.resolve()
361
- }
362
-
363
- // Hata limiti aşıldıysa refresh yapma
364
- if (errorCountRef.current >= maxErrorCount) {
365
- console.warn("Cannot refresh: maximum error count reached")
366
- return Promise.resolve()
367
- }
368
-
369
- clearCache()
370
- return fetchData()
371
- }, [fetchData, isDocsMode])
372
-
373
- return {
374
- repos,
375
- stats,
376
- loading,
377
- error,
378
- rateLimitInfo,
379
- lastUpdated,
380
- refresh,
381
- }
382
- }
383
-
384
- // Hook for star history
385
- export function useStarHistory(
386
- owner: string,
387
- repo: string,
388
- token?: string
389
- ) {
390
- const [history, setHistory] = useState<StarHistory[]>([])
391
- const [loading, setLoading] = useState(true)
392
- const [error, setError] = useState<string | null>(null)
393
-
394
- useEffect(() => {
395
- const fetchHistory = async () => {
396
- try {
397
- setLoading(true)
398
- setError(null)
399
- const data = await fetchStarHistory(owner, repo, token)
400
- setHistory(data)
401
- } catch (err) {
402
- setError(err instanceof Error ? err.message : "Failed to fetch star history")
403
- } finally {
404
- setLoading(false)
405
- }
406
- }
407
-
408
- if (owner && repo) {
409
- fetchHistory()
410
- }
411
- }, [owner, repo, token])
412
-
413
- return { history, loading, error }
414
- }
415
-
416
- // Hook for notifications
417
- export function useGitHubNotifications(enabled: boolean = true) {
418
- const [permission, setPermission] = useState<NotificationPermission>("default")
419
-
420
- useEffect(() => {
421
- if (!enabled || typeof window === "undefined" || !("Notification" in window)) {
422
- return
423
- }
424
-
425
- setPermission(Notification.permission)
426
-
427
- if (Notification.permission === "default") {
428
- Notification.requestPermission().then(setPermission)
429
- }
430
- }, [enabled])
431
-
432
- const notify = useCallback(
433
- (title: string, options?: NotificationOptions) => {
434
- if (!enabled || permission !== "granted") return
435
-
436
- try {
437
- new Notification(title, {
438
- icon: "/icon-192x192.png",
439
- badge: "/icon-192x192.png",
440
- ...options,
441
- })
442
- } catch (error) {
443
- console.error("Failed to show notification:", error)
444
- }
445
- },
446
- [enabled, permission]
447
- )
448
-
449
- return { permission, notify }
450
- }
451
-
452
- // Mock data generator for docs mode
453
- function getMockGitHubData(
454
- username?: string,
455
- repository?: string,
456
- repositories?: string[]
457
- ): GitHubRepository[] {
458
- const defaultRepos: GitHubRepository[] = [
459
- {
460
- id: 1,
461
- name: repository || "awesome-project",
462
- full_name: `${username || "moonui"}/${repository || "awesome-project"}`,
463
- description: "An amazing open source project with great features",
464
- html_url: `https://github.com/${username || "moonui"}/${repository || "awesome-project"}`,
465
- private: false,
466
- homepage: "https://awesome-project.dev",
467
- stargazers_count: 12453,
468
- watchers_count: 543,
469
- forks_count: 2341,
470
- language: "TypeScript",
471
- topics: ["react", "ui", "components", "typescript"],
472
- created_at: "2022-01-15T10:30:00Z",
473
- updated_at: new Date().toISOString(),
474
- pushed_at: new Date().toISOString(),
475
- size: 4567,
476
- open_issues_count: 23,
477
- license: {
478
- key: "mit",
479
- name: "MIT License",
480
- spdx_id: "MIT",
481
- url: "https://api.github.com/licenses/mit",
482
- },
483
- owner: {
484
- login: username || "moonui",
485
- avatar_url: `https://github.com/${username || "moonui"}.png`,
486
- html_url: `https://github.com/${username || "moonui"}`,
487
- type: "Organization",
488
- },
489
- contributors_count: 89,
490
- },
491
- ]
492
-
493
- if (repositories && repositories.length > 0) {
494
- return repositories.map((repo, index) => {
495
- const [owner, name] = repo.includes('/') ? repo.split('/') : [username || "moonui", repo]
496
- return {
497
- ...defaultRepos[0],
498
- id: index + 1,
499
- name: name,
500
- full_name: `${owner}/${name}`,
501
- html_url: `https://github.com/${owner}/${name}`,
502
- stargazers_count: Math.floor(Math.random() * 20000) + 1000,
503
- forks_count: Math.floor(Math.random() * 3000) + 100,
504
- watchers_count: Math.floor(Math.random() * 1000) + 50,
505
- language: ["TypeScript", "JavaScript", "Python", "Go", "Rust"][index % 5],
506
- owner: {
507
- login: owner,
508
- avatar_url: `https://github.com/${owner}.png`,
509
- html_url: `https://github.com/${owner}`,
510
- type: "Organization",
511
- },
512
- }
513
- })
514
- }
515
-
516
- return defaultRepos
517
- }