@moontra/moonui-pro 2.20.2 → 2.20.3

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 +176 -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,418 +0,0 @@
1
- "use client"
2
-
3
- import React from 'react'
4
- import { motion, AnimatePresence } from 'framer-motion'
5
- import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card'
6
- import { Button } from '../../ui/button'
7
- import { cn } from '../../../lib/utils'
8
- import {
9
- LineChart,
10
- Line,
11
- BarChart,
12
- Bar,
13
- AreaChart,
14
- Area,
15
- PieChart,
16
- Pie,
17
- RadarChart,
18
- PolarGrid,
19
- PolarAngleAxis,
20
- PolarRadiusAxis,
21
- Radar,
22
- XAxis,
23
- YAxis,
24
- CartesianGrid,
25
- Tooltip,
26
- Legend,
27
- ResponsiveContainer,
28
- Cell
29
- } from 'recharts'
30
- import {
31
- MoreVertical,
32
- Download,
33
- Maximize2,
34
- RefreshCw,
35
- Palette,
36
- Settings,
37
- Filter
38
- } from 'lucide-react'
39
- import {
40
- DropdownMenu,
41
- DropdownMenuContent,
42
- DropdownMenuItem,
43
- DropdownMenuSeparator,
44
- DropdownMenuTrigger,
45
- DropdownMenuSub,
46
- DropdownMenuSubContent,
47
- DropdownMenuSubTrigger,
48
- } from '../../ui/dropdown-menu'
49
- import { ChartData } from '../types'
50
-
51
- interface ChartWidgetProps {
52
- id: string
53
- title: string
54
- description?: string
55
- data: ChartData
56
- className?: string
57
- height?: number
58
- onAction?: (action: string, data?: any) => void
59
- loading?: boolean
60
- refreshing?: boolean
61
- glassmorphism?: boolean
62
- interactive?: boolean
63
- }
64
-
65
- // Renk paleti
66
- const CHART_COLORS = {
67
- default: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899'],
68
- pastel: ['#93c5fd', '#86efac', '#fcd34d', '#fca5a5', '#c4b5fd', '#fbcfe8'],
69
- vibrant: ['#2563eb', '#059669', '#d97706', '#dc2626', '#7c3aed', '#db2777'],
70
- monochrome: ['#1f2937', '#374151', '#4b5563', '#6b7280', '#9ca3af', '#d1d5db']
71
- }
72
-
73
- export function ChartWidget({
74
- id,
75
- title,
76
- description,
77
- data,
78
- className,
79
- height = 300,
80
- onAction,
81
- loading = false,
82
- refreshing = false,
83
- glassmorphism = false,
84
- interactive = true
85
- }: ChartWidgetProps) {
86
- const [colorScheme, setColorScheme] = React.useState<keyof typeof CHART_COLORS>('default')
87
- const [isFullscreen, setIsFullscreen] = React.useState(false)
88
-
89
- const colors = CHART_COLORS[colorScheme]
90
-
91
- // Custom tooltip
92
- const CustomTooltip = ({ active, payload, label }: any) => {
93
- if (!active || !payload) return null
94
-
95
- return (
96
- <motion.div
97
- initial={{ opacity: 0, scale: 0.9 }}
98
- animate={{ opacity: 1, scale: 1 }}
99
- className={cn(
100
- "p-3 rounded-lg shadow-lg",
101
- glassmorphism
102
- ? "bg-background/80 backdrop-blur-md border border-white/10"
103
- : "bg-background border"
104
- )}
105
- >
106
- <p className="text-sm font-medium">{label}</p>
107
- {payload.map((entry: any, index: number) => (
108
- <p key={index} className="text-sm mt-1">
109
- <span
110
- className="inline-block w-3 h-3 rounded-full mr-2"
111
- style={{ backgroundColor: entry.color }}
112
- />
113
- {entry.name}: {entry.value}
114
- </p>
115
- ))}
116
- </motion.div>
117
- )
118
- }
119
-
120
- // Chart renderer
121
- const renderChart = () => {
122
- if (!data.data || data.data.length === 0) {
123
- return (
124
- <div className="flex items-center justify-center h-full text-muted-foreground">
125
- No data available
126
- </div>
127
- )
128
- }
129
-
130
- const chartProps = {
131
- data: data.data,
132
- margin: { top: 5, right: 30, left: 20, bottom: 5 }
133
- }
134
-
135
- switch (data.type) {
136
- case 'line':
137
- return (
138
- <ResponsiveContainer width="100%" height={height}>
139
- <LineChart {...chartProps}>
140
- <CartesianGrid strokeDasharray="3 3" className="opacity-30" />
141
- <XAxis dataKey="name" />
142
- <YAxis />
143
- <Tooltip content={<CustomTooltip />} />
144
- {interactive && <Legend />}
145
- {Object.keys(data.data[0])
146
- .filter(key => key !== 'name')
147
- .map((key, index) => (
148
- <Line
149
- key={key}
150
- type="monotone"
151
- dataKey={key}
152
- stroke={colors[index % colors.length]}
153
- strokeWidth={2}
154
- dot={{ r: 4 }}
155
- activeDot={{ r: 6 }}
156
- />
157
- ))}
158
- </LineChart>
159
- </ResponsiveContainer>
160
- )
161
-
162
- case 'bar':
163
- return (
164
- <ResponsiveContainer width="100%" height={height}>
165
- <BarChart {...chartProps}>
166
- <CartesianGrid strokeDasharray="3 3" className="opacity-30" />
167
- <XAxis dataKey="name" />
168
- <YAxis />
169
- <Tooltip content={<CustomTooltip />} />
170
- {interactive && <Legend />}
171
- {Object.keys(data.data[0])
172
- .filter(key => key !== 'name')
173
- .map((key, index) => (
174
- <Bar
175
- key={key}
176
- dataKey={key}
177
- fill={colors[index % colors.length]}
178
- radius={[4, 4, 0, 0]}
179
- />
180
- ))}
181
- </BarChart>
182
- </ResponsiveContainer>
183
- )
184
-
185
- case 'area':
186
- return (
187
- <ResponsiveContainer width="100%" height={height}>
188
- <AreaChart {...chartProps}>
189
- <CartesianGrid strokeDasharray="3 3" className="opacity-30" />
190
- <XAxis dataKey="name" />
191
- <YAxis />
192
- <Tooltip content={<CustomTooltip />} />
193
- {interactive && <Legend />}
194
- {Object.keys(data.data[0])
195
- .filter(key => key !== 'name')
196
- .map((key, index) => (
197
- <Area
198
- key={key}
199
- type="monotone"
200
- dataKey={key}
201
- stroke={colors[index % colors.length]}
202
- fill={colors[index % colors.length]}
203
- fillOpacity={0.2}
204
- />
205
- ))}
206
- </AreaChart>
207
- </ResponsiveContainer>
208
- )
209
-
210
- case 'pie':
211
- case 'donut':
212
- return (
213
- <ResponsiveContainer width="100%" height={height}>
214
- <PieChart>
215
- <Pie
216
- data={data.data}
217
- cx="50%"
218
- cy="50%"
219
- labelLine={false}
220
- label={interactive}
221
- outerRadius={data.type === 'donut' ? 80 : 100}
222
- innerRadius={data.type === 'donut' ? 50 : 0}
223
- fill="#8884d8"
224
- dataKey="value"
225
- >
226
- {data.data.map((entry: any, index: number) => (
227
- <Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
228
- ))}
229
- </Pie>
230
- <Tooltip content={<CustomTooltip />} />
231
- {interactive && <Legend />}
232
- </PieChart>
233
- </ResponsiveContainer>
234
- )
235
-
236
- case 'radar':
237
- return (
238
- <ResponsiveContainer width="100%" height={height}>
239
- <RadarChart data={data.data}>
240
- <PolarGrid />
241
- <PolarAngleAxis dataKey="subject" />
242
- <PolarRadiusAxis />
243
- {Object.keys(data.data[0])
244
- .filter(key => key !== 'subject')
245
- .map((key, index) => (
246
- <Radar
247
- key={key}
248
- name={key}
249
- dataKey={key}
250
- stroke={colors[index % colors.length]}
251
- fill={colors[index % colors.length]}
252
- fillOpacity={0.3}
253
- />
254
- ))}
255
- <Tooltip content={<CustomTooltip />} />
256
- {interactive && <Legend />}
257
- </RadarChart>
258
- </ResponsiveContainer>
259
- )
260
-
261
- default:
262
- return null
263
- }
264
- }
265
-
266
- // Card variants
267
- const cardVariants = {
268
- initial: { opacity: 0, scale: 0.95 },
269
- animate: {
270
- opacity: 1,
271
- scale: 1,
272
- transition: { duration: 0.3, ease: "easeOut" }
273
- }
274
- }
275
-
276
- return (
277
- <motion.div
278
- variants={cardVariants}
279
- initial="initial"
280
- animate="animate"
281
- className={cn(isFullscreen && "fixed inset-4 z-50")}
282
- >
283
- <Card className={cn(
284
- "relative overflow-hidden transition-all duration-300",
285
- glassmorphism && "bg-background/60 backdrop-blur-md border-white/10",
286
- isFullscreen && "h-full",
287
- className
288
- )}>
289
- {/* Header */}
290
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
291
- <div>
292
- <CardTitle className="text-base font-semibold">{title}</CardTitle>
293
- {description && (
294
- <p className="text-sm text-muted-foreground mt-1">{description}</p>
295
- )}
296
- </div>
297
-
298
- {/* Actions */}
299
- <div className="flex items-center gap-2">
300
- {refreshing && (
301
- <motion.div
302
- animate={{ rotate: 360 }}
303
- transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
304
- >
305
- <RefreshCw className="h-4 w-4 text-muted-foreground" />
306
- </motion.div>
307
- )}
308
-
309
- {interactive && (
310
- <DropdownMenu>
311
- <DropdownMenuTrigger asChild>
312
- <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
313
- <MoreVertical className="h-4 w-4" />
314
- </Button>
315
- </DropdownMenuTrigger>
316
- <DropdownMenuContent align="end" className="w-48">
317
- <DropdownMenuItem onClick={() => {
318
- setIsFullscreen(!isFullscreen)
319
- onAction?.('fullscreen', { fullscreen: !isFullscreen })
320
- }}>
321
- <Maximize2 className="mr-2 h-4 w-4" />
322
- {isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}
323
- </DropdownMenuItem>
324
-
325
- <DropdownMenuSub>
326
- <DropdownMenuSubTrigger>
327
- <Palette className="mr-2 h-4 w-4" />
328
- Color Scheme
329
- </DropdownMenuSubTrigger>
330
- <DropdownMenuSubContent>
331
- {Object.keys(CHART_COLORS).map((scheme) => (
332
- <DropdownMenuItem
333
- key={scheme}
334
- onClick={() => setColorScheme(scheme as keyof typeof CHART_COLORS)}
335
- >
336
- <div className="flex items-center gap-2">
337
- <div className="flex gap-1">
338
- {CHART_COLORS[scheme as keyof typeof CHART_COLORS].slice(0, 3).map((color, i) => (
339
- <div
340
- key={i}
341
- className="w-3 h-3 rounded-full"
342
- style={{ backgroundColor: color }}
343
- />
344
- ))}
345
- </div>
346
- <span className="capitalize">{scheme}</span>
347
- </div>
348
- </DropdownMenuItem>
349
- ))}
350
- </DropdownMenuSubContent>
351
- </DropdownMenuSub>
352
-
353
- <DropdownMenuSeparator />
354
-
355
- <DropdownMenuItem onClick={() => onAction?.('export', { format: 'png' })}>
356
- <Download className="mr-2 h-4 w-4" />
357
- Export as PNG
358
- </DropdownMenuItem>
359
-
360
- <DropdownMenuItem onClick={() => onAction?.('export', { format: 'csv' })}>
361
- <Download className="mr-2 h-4 w-4" />
362
- Export Data
363
- </DropdownMenuItem>
364
-
365
- <DropdownMenuSeparator />
366
-
367
- <DropdownMenuItem onClick={() => onAction?.('filter')}>
368
- <Filter className="mr-2 h-4 w-4" />
369
- Filter Data
370
- </DropdownMenuItem>
371
-
372
- <DropdownMenuItem onClick={() => onAction?.('settings')}>
373
- <Settings className="mr-2 h-4 w-4" />
374
- Chart Settings
375
- </DropdownMenuItem>
376
- </DropdownMenuContent>
377
- </DropdownMenu>
378
- )}
379
- </div>
380
- </CardHeader>
381
-
382
- {/* Chart Content */}
383
- <CardContent className="p-0 px-4 pb-4">
384
- <AnimatePresence mode="wait">
385
- {loading ? (
386
- <motion.div
387
- key="loading"
388
- initial={{ opacity: 0 }}
389
- animate={{ opacity: 1 }}
390
- exit={{ opacity: 0 }}
391
- className="flex items-center justify-center"
392
- style={{ height }}
393
- >
394
- <div className="space-y-2">
395
- <div className="animate-pulse bg-muted h-4 w-32 rounded" />
396
- <div className="animate-pulse bg-muted h-4 w-24 rounded" />
397
- <div className="animate-pulse bg-muted h-4 w-28 rounded" />
398
- </div>
399
- </motion.div>
400
- ) : (
401
- <motion.div
402
- key="chart"
403
- initial={{ opacity: 0, y: 10 }}
404
- animate={{ opacity: 1, y: 0 }}
405
- exit={{ opacity: 0, y: -10 }}
406
- transition={{ duration: 0.3 }}
407
- >
408
- {renderChart()}
409
- </motion.div>
410
- )}
411
- </AnimatePresence>
412
- </CardContent>
413
- </Card>
414
- </motion.div>
415
- )
416
- }
417
-
418
- export default ChartWidget
@@ -1,177 +0,0 @@
1
- "use client"
2
-
3
- import React from 'react'
4
- import { motion } from 'framer-motion'
5
- import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card'
6
- import { cn } from '../../../lib/utils'
7
- import { ComparisonData } from '../types'
8
- import { ArrowUpRight, ArrowDownRight, Minus, BarChart3 } from 'lucide-react'
9
- import { Badge } from '../../ui/badge'
10
-
11
- interface ComparisonWidgetProps {
12
- data: ComparisonData
13
- title?: string
14
- className?: string
15
- glassmorphism?: boolean
16
- }
17
-
18
- export function ComparisonWidget({
19
- data,
20
- title = "Comparison",
21
- className,
22
- glassmorphism = false
23
- }: ComparisonWidgetProps) {
24
- const [isMounted, setIsMounted] = React.useState(false)
25
-
26
- React.useEffect(() => {
27
- setIsMounted(true)
28
- }, [])
29
-
30
- // En yüksek değeri bul
31
- const maxValue = Math.max(...data.periods.map(p => p.value))
32
-
33
- // İlk iki period arasındaki değişimi hesapla
34
- const change = data.periods.length >= 2
35
- ? ((data.periods[0].value - data.periods[1].value) / data.periods[1].value) * 100
36
- : 0
37
-
38
- const changeType = change > 0 ? 'increase' : change < 0 ? 'decrease' : 'neutral'
39
-
40
- // Değer formatla
41
- const formatValue = (value: number) => {
42
- if (!isMounted) return value.toString()
43
-
44
- if (value >= 1000000) {
45
- return (value / 1000000).toFixed(1) + 'M'
46
- } else if (value >= 1000) {
47
- return (value / 1000).toFixed(0) + 'K'
48
- }
49
- return value.toLocaleString()
50
- }
51
-
52
- return (
53
- <Card className={cn(
54
- "h-full flex flex-col overflow-hidden",
55
- glassmorphism && "bg-background/60 backdrop-blur-md border-white/10",
56
- className
57
- )}>
58
- <CardHeader className="flex-shrink-0 pb-3 px-4">
59
- <div className="flex items-start justify-between gap-2">
60
- <div className="flex-1 min-w-0">
61
- <CardTitle className="text-sm font-semibold flex items-center gap-2">
62
- <BarChart3 className="h-4 w-4 text-muted-foreground flex-shrink-0" />
63
- <span className="truncate">{title}</span>
64
- </CardTitle>
65
- {data.metric && (
66
- <p className="text-xs text-muted-foreground mt-1 truncate">{data.metric}</p>
67
- )}
68
- </div>
69
- {change !== 0 && (
70
- <div
71
- className={cn(
72
- "inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-xs font-medium flex-shrink-0",
73
- changeType === 'increase' && "bg-green-500/10 text-green-600 dark:text-green-400 border border-green-500/20",
74
- changeType === 'decrease' && "bg-red-500/10 text-red-600 dark:text-red-400 border border-red-500/20",
75
- changeType === 'neutral' && "bg-muted text-muted-foreground border border-border"
76
- )}
77
- >
78
- {changeType === 'increase' ? <ArrowUpRight className="h-3 w-3" /> :
79
- changeType === 'decrease' ? <ArrowDownRight className="h-3 w-3" /> :
80
- <Minus className="h-3 w-3" />}
81
- <span>
82
- {Math.abs(change).toFixed(1)}%
83
- </span>
84
- </div>
85
- )}
86
- </div>
87
- </CardHeader>
88
-
89
- <CardContent className="flex-1 px-4 pb-4 overflow-hidden flex flex-col gap-3">
90
- {/* Bar list görünümü - scrollable area */}
91
- <div className="flex-1 min-h-0 overflow-y-auto overflow-x-hidden pr-2 -mr-2">
92
- <div className="space-y-2.5">
93
- {data.periods.map((period, index) => {
94
- const percentage = (period.value / maxValue) * 100
95
- const isHighest = period.value === maxValue
96
-
97
- return (
98
- <motion.div
99
- key={period.label}
100
- initial={{ opacity: 0, x: -20 }}
101
- animate={{ opacity: 1, x: 0 }}
102
- transition={{ delay: index * 0.05 }}
103
- >
104
- {/* Label ve değer */}
105
- <div className="flex items-center justify-between gap-3 mb-1">
106
- <span className={cn(
107
- "text-xs font-medium truncate flex-1",
108
- isHighest ? "text-foreground" : "text-muted-foreground"
109
- )}>
110
- {period.label}
111
- </span>
112
- <span className={cn(
113
- "text-xs font-semibold tabular-nums flex-shrink-0",
114
- isHighest && "text-primary"
115
- )}>
116
- {formatValue(period.value)}
117
- </span>
118
- </div>
119
-
120
- {/* Progress bar */}
121
- <div className="w-full bg-muted rounded-full h-1.5 overflow-hidden">
122
- <motion.div
123
- className={cn(
124
- "h-full rounded-full transition-colors",
125
- isHighest ? "bg-primary" : "bg-primary/60"
126
- )}
127
- initial={{ width: 0 }}
128
- animate={{ width: `${Math.min(percentage, 100)}%` }}
129
- transition={{ duration: 0.5, delay: index * 0.05 }}
130
- />
131
- </div>
132
- </motion.div>
133
- )
134
- })}
135
- </div>
136
- </div>
137
-
138
- {/* Compact chart view - fixed height */}
139
- {data.showChart && (
140
- <div className="flex-shrink-0 pt-3 border-t">
141
- <div className="h-14 flex items-end justify-between gap-1">
142
- {data.periods.slice(0, 5).map((period, index) => {
143
- const height = (period.value / maxValue) * 100
144
- const isHighest = period.value === maxValue
145
-
146
- return (
147
- <motion.div
148
- key={period.label}
149
- className="flex-1 flex flex-col items-center gap-0.5"
150
- initial={{ opacity: 0 }}
151
- animate={{ opacity: 1 }}
152
- transition={{ delay: index * 0.05 }}
153
- >
154
- <div className="w-full h-10 flex items-end justify-center px-0.5">
155
- <motion.div
156
- className={cn(
157
- "w-full max-w-[20px] rounded-t transition-colors",
158
- isHighest ? "bg-primary" : "bg-primary/40"
159
- )}
160
- initial={{ height: 0 }}
161
- animate={{ height: `${height}%` }}
162
- transition={{ duration: 0.5, delay: index * 0.05 }}
163
- />
164
- </div>
165
- <span className="text-[9px] text-muted-foreground">
166
- {period.label.slice(0, 3)}
167
- </span>
168
- </motion.div>
169
- )
170
- })}
171
- </div>
172
- </div>
173
- )}
174
- </CardContent>
175
- </Card>
176
- )
177
- }
@@ -1,5 +0,0 @@
1
- export { MetricCard } from './metric-card'
2
- export { ChartWidget } from './chart-widget'
3
- export { ActivityFeed } from './activity-feed'
4
- export { ProgressWidget } from './progress-widget'
5
- export { ComparisonWidget } from './comparison-widget'