helix-lang 11.0.0

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 (193) hide show
  1. package/README.md +168 -0
  2. package/dist/architect.d.ts +14 -0
  3. package/dist/architect.d.ts.map +1 -0
  4. package/dist/architect.js +127 -0
  5. package/dist/architect.js.map +1 -0
  6. package/dist/bin/helix.d.ts +20 -0
  7. package/dist/bin/helix.d.ts.map +1 -0
  8. package/dist/bin/helix.js +921 -0
  9. package/dist/bin/helix.js.map +1 -0
  10. package/dist/commands/collaborate/index.d.ts +2 -0
  11. package/dist/commands/collaborate/index.d.ts.map +1 -0
  12. package/dist/commands/collaborate/index.js +129 -0
  13. package/dist/commands/collaborate/index.js.map +1 -0
  14. package/dist/commands/collaborate/server.d.ts +31 -0
  15. package/dist/commands/collaborate/server.d.ts.map +1 -0
  16. package/dist/commands/collaborate/server.js +159 -0
  17. package/dist/commands/collaborate/server.js.map +1 -0
  18. package/dist/commands/deploy/index.d.ts +25 -0
  19. package/dist/commands/deploy/index.d.ts.map +1 -0
  20. package/dist/commands/deploy/index.js +130 -0
  21. package/dist/commands/deploy/index.js.map +1 -0
  22. package/dist/commands/deploy/platforms/fly.d.ts +9 -0
  23. package/dist/commands/deploy/platforms/fly.d.ts.map +1 -0
  24. package/dist/commands/deploy/platforms/fly.js +68 -0
  25. package/dist/commands/deploy/platforms/fly.js.map +1 -0
  26. package/dist/commands/deploy/platforms/railway.d.ts +9 -0
  27. package/dist/commands/deploy/platforms/railway.d.ts.map +1 -0
  28. package/dist/commands/deploy/platforms/railway.js +115 -0
  29. package/dist/commands/deploy/platforms/railway.js.map +1 -0
  30. package/dist/commands/deploy/platforms/vercel.d.ts +10 -0
  31. package/dist/commands/deploy/platforms/vercel.d.ts.map +1 -0
  32. package/dist/commands/deploy/platforms/vercel.js +126 -0
  33. package/dist/commands/deploy/platforms/vercel.js.map +1 -0
  34. package/dist/commands/deploy.d.ts +6 -0
  35. package/dist/commands/deploy.d.ts.map +1 -0
  36. package/dist/commands/deploy.js +56 -0
  37. package/dist/commands/deploy.js.map +1 -0
  38. package/dist/commands/evolve/analyzers/performance.d.ts +13 -0
  39. package/dist/commands/evolve/analyzers/performance.d.ts.map +1 -0
  40. package/dist/commands/evolve/analyzers/performance.js +591 -0
  41. package/dist/commands/evolve/analyzers/performance.js.map +1 -0
  42. package/dist/commands/evolve/analyzers/security.d.ts +21 -0
  43. package/dist/commands/evolve/analyzers/security.d.ts.map +1 -0
  44. package/dist/commands/evolve/analyzers/security.js +280 -0
  45. package/dist/commands/evolve/analyzers/security.js.map +1 -0
  46. package/dist/commands/evolve/index.d.ts +2 -0
  47. package/dist/commands/evolve/index.d.ts.map +1 -0
  48. package/dist/commands/evolve/index.js +122 -0
  49. package/dist/commands/evolve/index.js.map +1 -0
  50. package/dist/commands/generate.d.ts +6 -0
  51. package/dist/commands/generate.d.ts.map +1 -0
  52. package/dist/commands/generate.js +277 -0
  53. package/dist/commands/generate.js.map +1 -0
  54. package/dist/commands/install.d.ts +2 -0
  55. package/dist/commands/install.d.ts.map +1 -0
  56. package/dist/commands/install.js +176 -0
  57. package/dist/commands/install.js.map +1 -0
  58. package/dist/commands/library/index.d.ts +27 -0
  59. package/dist/commands/library/index.d.ts.map +1 -0
  60. package/dist/commands/library/index.js +126 -0
  61. package/dist/commands/library/index.js.map +1 -0
  62. package/dist/commands/migrate.d.ts +5 -0
  63. package/dist/commands/migrate.d.ts.map +1 -0
  64. package/dist/commands/migrate.js +258 -0
  65. package/dist/commands/migrate.js.map +1 -0
  66. package/dist/commands/new.d.ts +6 -0
  67. package/dist/commands/new.d.ts.map +1 -0
  68. package/dist/commands/new.js +195 -0
  69. package/dist/commands/new.js.map +1 -0
  70. package/dist/commands/preflight.d.ts +20 -0
  71. package/dist/commands/preflight.d.ts.map +1 -0
  72. package/dist/commands/preflight.js +182 -0
  73. package/dist/commands/preflight.js.map +1 -0
  74. package/dist/commands/preview.d.ts +13 -0
  75. package/dist/commands/preview.d.ts.map +1 -0
  76. package/dist/commands/preview.js +260 -0
  77. package/dist/commands/preview.js.map +1 -0
  78. package/dist/commands/run.d.ts +6 -0
  79. package/dist/commands/run.d.ts.map +1 -0
  80. package/dist/commands/run.js +96 -0
  81. package/dist/commands/run.js.map +1 -0
  82. package/dist/commands/spawn.d.ts +11 -0
  83. package/dist/commands/spawn.d.ts.map +1 -0
  84. package/dist/commands/spawn.js +916 -0
  85. package/dist/commands/spawn.js.map +1 -0
  86. package/dist/compiler.d.ts +12 -0
  87. package/dist/compiler.d.ts.map +1 -0
  88. package/dist/compiler.js +92 -0
  89. package/dist/compiler.js.map +1 -0
  90. package/dist/core/file-writer.d.ts +36 -0
  91. package/dist/core/file-writer.d.ts.map +1 -0
  92. package/dist/core/file-writer.js +268 -0
  93. package/dist/core/file-writer.js.map +1 -0
  94. package/dist/core/registry.d.ts +57 -0
  95. package/dist/core/registry.d.ts.map +1 -0
  96. package/dist/core/registry.js +222 -0
  97. package/dist/core/registry.js.map +1 -0
  98. package/dist/core/self-healing.d.ts +47 -0
  99. package/dist/core/self-healing.d.ts.map +1 -0
  100. package/dist/core/self-healing.js +250 -0
  101. package/dist/core/self-healing.js.map +1 -0
  102. package/dist/core/types.d.ts +126 -0
  103. package/dist/core/types.d.ts.map +1 -0
  104. package/dist/core/types.js +7 -0
  105. package/dist/core/types.js.map +1 -0
  106. package/dist/generators/databases/mongodb.d.ts +10 -0
  107. package/dist/generators/databases/mongodb.d.ts.map +1 -0
  108. package/dist/generators/databases/mongodb.js +83 -0
  109. package/dist/generators/databases/mongodb.js.map +1 -0
  110. package/dist/generators/databases/redis.d.ts +2 -0
  111. package/dist/generators/databases/redis.d.ts.map +1 -0
  112. package/dist/generators/databases/redis.js +140 -0
  113. package/dist/generators/databases/redis.js.map +1 -0
  114. package/dist/generators/flutter.d.ts +32 -0
  115. package/dist/generators/flutter.d.ts.map +1 -0
  116. package/dist/generators/flutter.js +628 -0
  117. package/dist/generators/flutter.js.map +1 -0
  118. package/dist/openrouter.d.ts +68 -0
  119. package/dist/openrouter.d.ts.map +1 -0
  120. package/dist/openrouter.js +241 -0
  121. package/dist/openrouter.js.map +1 -0
  122. package/dist/page-generator.d.ts +22 -0
  123. package/dist/page-generator.d.ts.map +1 -0
  124. package/dist/page-generator.js +192 -0
  125. package/dist/page-generator.js.map +1 -0
  126. package/dist/parser.d.ts +76 -0
  127. package/dist/parser.d.ts.map +1 -0
  128. package/dist/parser.js +691 -0
  129. package/dist/parser.js.map +1 -0
  130. package/dist/prompts/master-architect.d.ts +9 -0
  131. package/dist/prompts/master-architect.d.ts.map +1 -0
  132. package/dist/prompts/master-architect.js +150 -0
  133. package/dist/prompts/master-architect.js.map +1 -0
  134. package/dist/researcher.d.ts +12 -0
  135. package/dist/researcher.d.ts.map +1 -0
  136. package/dist/researcher.js +85 -0
  137. package/dist/researcher.js.map +1 -0
  138. package/dist/self-heal.d.ts +29 -0
  139. package/dist/self-heal.d.ts.map +1 -0
  140. package/dist/self-heal.js +260 -0
  141. package/dist/self-heal.js.map +1 -0
  142. package/dist/services/SupabaseDeployer.d.ts +9 -0
  143. package/dist/services/SupabaseDeployer.d.ts.map +1 -0
  144. package/dist/services/SupabaseDeployer.js +50 -0
  145. package/dist/services/SupabaseDeployer.js.map +1 -0
  146. package/dist/test-generator.d.ts +18 -0
  147. package/dist/test-generator.d.ts.map +1 -0
  148. package/dist/test-generator.js +180 -0
  149. package/dist/test-generator.js.map +1 -0
  150. package/dist/themes/index.d.ts +52 -0
  151. package/dist/themes/index.d.ts.map +1 -0
  152. package/dist/themes/index.js +273 -0
  153. package/dist/themes/index.js.map +1 -0
  154. package/dist/types.d.ts +9 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +81 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils/constitutional-validator.d.ts +73 -0
  159. package/dist/utils/constitutional-validator.d.ts.map +1 -0
  160. package/dist/utils/constitutional-validator.js +249 -0
  161. package/dist/utils/constitutional-validator.js.map +1 -0
  162. package/library/auth-flow/app/api/auth/[...nextauth]/route.ts +31 -0
  163. package/library/auth-flow/app/api/auth/login/route.ts +90 -0
  164. package/library/auth-flow/app/api/auth/register/route.ts +91 -0
  165. package/library/auth-flow/components/auth/AuthMiddleware.tsx +139 -0
  166. package/library/auth-flow/components/auth/LoginForm.tsx +125 -0
  167. package/library/auth-flow/components/auth/RegisterForm.tsx +168 -0
  168. package/library/auth-flow/components/auth/nextauth-config.ts +99 -0
  169. package/library/auth-flow/manifest.json +29 -0
  170. package/library/auth-flow/schema.prisma +45 -0
  171. package/library/dashboard-analytics/components/dashboard/ActivityFeed.tsx +109 -0
  172. package/library/dashboard-analytics/components/dashboard/LineChart.tsx +180 -0
  173. package/library/dashboard-analytics/components/dashboard/StatsCard.tsx +47 -0
  174. package/library/dashboard-analytics/components/dashboard/SummaryGrid.tsx +39 -0
  175. package/library/dashboard-analytics/manifest.json +19 -0
  176. package/library/data-table/components/table/BulkActions.tsx +59 -0
  177. package/library/data-table/components/table/ColumnToggle.tsx +65 -0
  178. package/library/data-table/components/table/DataTable.tsx +318 -0
  179. package/library/data-table/components/table/ExportCSV.tsx +52 -0
  180. package/library/data-table/components/table/SearchFilter.tsx +48 -0
  181. package/library/data-table/manifest.json +20 -0
  182. package/library/file-upload/app/api/upload/route.ts +107 -0
  183. package/library/file-upload/components/upload/DropZone.tsx +268 -0
  184. package/library/file-upload/components/upload/FilePreview.tsx +82 -0
  185. package/library/file-upload/components/upload/UploadProgress.tsx +92 -0
  186. package/library/file-upload/components/upload/fileStorage.ts +142 -0
  187. package/library/file-upload/manifest.json +21 -0
  188. package/library/notification-system/app/api/notifications/route.ts +121 -0
  189. package/library/notification-system/components/notifications/NotificationBell.tsx +154 -0
  190. package/library/notification-system/components/notifications/NotificationProvider.tsx +161 -0
  191. package/library/notification-system/components/notifications/Toast.tsx +112 -0
  192. package/library/notification-system/manifest.json +20 -0
  193. package/package.json +66 -0
@@ -0,0 +1,109 @@
1
+ 'use client';
2
+
3
+ export interface ActivityItem {
4
+ id: string;
5
+ user: string;
6
+ action: string;
7
+ target?: string;
8
+ timestamp: string | Date;
9
+ avatar?: string;
10
+ }
11
+
12
+ interface ActivityFeedProps {
13
+ items: ActivityItem[];
14
+ title?: string;
15
+ maxItems?: number;
16
+ onViewAll?: () => void;
17
+ }
18
+
19
+ function formatRelativeTime(date: string | Date): string {
20
+ const now = Date.now();
21
+ const then = new Date(date).getTime();
22
+ const diffMs = now - then;
23
+ const diffSec = Math.floor(diffMs / 1000);
24
+ const diffMin = Math.floor(diffSec / 60);
25
+ const diffHour = Math.floor(diffMin / 60);
26
+ const diffDay = Math.floor(diffHour / 24);
27
+
28
+ if (diffSec < 60) return 'just now';
29
+ if (diffMin < 60) return `${diffMin}m ago`;
30
+ if (diffHour < 24) return `${diffHour}h ago`;
31
+ if (diffDay < 7) return `${diffDay}d ago`;
32
+ return new Date(date).toLocaleDateString();
33
+ }
34
+
35
+ function getInitials(name: string): string {
36
+ return name
37
+ .split(' ')
38
+ .map((part) => part[0])
39
+ .join('')
40
+ .toUpperCase()
41
+ .slice(0, 2);
42
+ }
43
+
44
+ export default function ActivityFeed({
45
+ items,
46
+ title = 'Recent Activity',
47
+ maxItems = 10,
48
+ onViewAll,
49
+ }: ActivityFeedProps) {
50
+ const displayItems = items.slice(0, maxItems);
51
+
52
+ return (
53
+ <div className="backdrop-blur-xl bg-white/5 border border-white/10 rounded-2xl p-6">
54
+ <div className="flex items-center justify-between mb-5">
55
+ <h3 className="text-lg font-semibold text-white">{title}</h3>
56
+ {onViewAll && (
57
+ <button
58
+ onClick={onViewAll}
59
+ className="text-sm text-cyan-400 hover:text-cyan-300 transition-colors"
60
+ >
61
+ View all
62
+ </button>
63
+ )}
64
+ </div>
65
+
66
+ {displayItems.length === 0 ? (
67
+ <p className="text-white/30 text-sm py-8 text-center">No recent activity</p>
68
+ ) : (
69
+ <div className="space-y-4">
70
+ {displayItems.map((item) => (
71
+ <div
72
+ key={item.id}
73
+ className="flex items-start gap-3 group"
74
+ >
75
+ {/* Avatar */}
76
+ <div className="flex-shrink-0 w-8 h-8 rounded-full bg-cyan-500/10 border border-cyan-500/20 flex items-center justify-center">
77
+ {item.avatar ? (
78
+ <img
79
+ src={item.avatar}
80
+ alt={item.user}
81
+ className="w-8 h-8 rounded-full object-cover"
82
+ />
83
+ ) : (
84
+ <span className="text-xs font-medium text-cyan-400">
85
+ {getInitials(item.user)}
86
+ </span>
87
+ )}
88
+ </div>
89
+
90
+ {/* Content */}
91
+ <div className="flex-1 min-w-0">
92
+ <p className="text-sm text-white/80">
93
+ <span className="font-medium text-white">{item.user}</span>{' '}
94
+ {item.action}
95
+ {item.target && (
96
+ <span className="font-medium text-cyan-400"> {item.target}</span>
97
+ )}
98
+ </p>
99
+ <p className="text-xs text-white/30 mt-0.5">
100
+ {formatRelativeTime(item.timestamp)}
101
+ </p>
102
+ </div>
103
+ </div>
104
+ ))}
105
+ </div>
106
+ )}
107
+ </div>
108
+ );
109
+ }
@@ -0,0 +1,180 @@
1
+ 'use client';
2
+
3
+ import { useMemo } from 'react';
4
+
5
+ export interface DataPoint {
6
+ label: string;
7
+ value: number;
8
+ }
9
+
10
+ interface LineChartProps {
11
+ data: DataPoint[];
12
+ title?: string;
13
+ height?: number;
14
+ color?: string;
15
+ showGrid?: boolean;
16
+ showLabels?: boolean;
17
+ }
18
+
19
+ export default function LineChart({
20
+ data,
21
+ title,
22
+ height = 200,
23
+ color = '#06b6d4',
24
+ showGrid = true,
25
+ showLabels = true,
26
+ }: LineChartProps) {
27
+ const chartData = useMemo(() => {
28
+ if (data.length === 0) return null;
29
+
30
+ const values = data.map((d) => d.value);
31
+ const maxVal = Math.max(...values);
32
+ const minVal = Math.min(...values);
33
+ const range = maxVal - minVal || 1;
34
+
35
+ const padding = { top: 20, right: 20, bottom: 40, left: 50 };
36
+ const chartWidth = 600;
37
+ const chartHeight = height;
38
+ const innerWidth = chartWidth - padding.left - padding.right;
39
+ const innerHeight = chartHeight - padding.top - padding.bottom;
40
+
41
+ const points = data.map((d, i) => ({
42
+ x: padding.left + (i / Math.max(data.length - 1, 1)) * innerWidth,
43
+ y: padding.top + innerHeight - ((d.value - minVal) / range) * innerHeight,
44
+ label: d.label,
45
+ value: d.value,
46
+ }));
47
+
48
+ const pathD = points
49
+ .map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`)
50
+ .join(' ');
51
+
52
+ const areaD =
53
+ pathD +
54
+ ` L ${points[points.length - 1].x} ${padding.top + innerHeight}` +
55
+ ` L ${points[0].x} ${padding.top + innerHeight} Z`;
56
+
57
+ const gridLines = [];
58
+ const gridCount = 4;
59
+ for (let i = 0; i <= gridCount; i++) {
60
+ const y = padding.top + (i / gridCount) * innerHeight;
61
+ const val = maxVal - (i / gridCount) * range;
62
+ gridLines.push({ y, label: val.toFixed(0) });
63
+ }
64
+
65
+ return {
66
+ points,
67
+ pathD,
68
+ areaD,
69
+ gridLines,
70
+ chartWidth,
71
+ chartHeight,
72
+ padding,
73
+ innerHeight,
74
+ };
75
+ }, [data, height]);
76
+
77
+ if (!chartData || data.length === 0) {
78
+ return (
79
+ <div className="backdrop-blur-xl bg-white/5 border border-white/10 rounded-2xl p-6">
80
+ {title && <h3 className="text-lg font-semibold text-white mb-4">{title}</h3>}
81
+ <div
82
+ className="flex items-center justify-center text-white/30"
83
+ style={{ height }}
84
+ >
85
+ No data available
86
+ </div>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ return (
92
+ <div className="backdrop-blur-xl bg-white/5 border border-white/10 rounded-2xl p-6">
93
+ {title && <h3 className="text-lg font-semibold text-white mb-4">{title}</h3>}
94
+
95
+ <svg
96
+ viewBox={`0 0 ${chartData.chartWidth} ${chartData.chartHeight}`}
97
+ className="w-full"
98
+ style={{ height }}
99
+ >
100
+ {/* Gradient fill */}
101
+ <defs>
102
+ <linearGradient id="areaGradient" x1="0" y1="0" x2="0" y2="1">
103
+ <stop offset="0%" stopColor={color} stopOpacity="0.3" />
104
+ <stop offset="100%" stopColor={color} stopOpacity="0" />
105
+ </linearGradient>
106
+ </defs>
107
+
108
+ {/* Grid lines */}
109
+ {showGrid &&
110
+ chartData.gridLines.map((line, i) => (
111
+ <g key={i}>
112
+ <line
113
+ x1={chartData.padding.left}
114
+ y1={line.y}
115
+ x2={chartData.chartWidth - chartData.padding.right}
116
+ y2={line.y}
117
+ stroke="rgba(255,255,255,0.06)"
118
+ strokeDasharray="4 4"
119
+ />
120
+ <text
121
+ x={chartData.padding.left - 10}
122
+ y={line.y + 4}
123
+ textAnchor="end"
124
+ fill="rgba(255,255,255,0.3)"
125
+ fontSize="11"
126
+ >
127
+ {line.label}
128
+ </text>
129
+ </g>
130
+ ))}
131
+
132
+ {/* Area fill */}
133
+ <path d={chartData.areaD} fill="url(#areaGradient)" />
134
+
135
+ {/* Line */}
136
+ <path
137
+ d={chartData.pathD}
138
+ fill="none"
139
+ stroke={color}
140
+ strokeWidth="2.5"
141
+ strokeLinecap="round"
142
+ strokeLinejoin="round"
143
+ />
144
+
145
+ {/* Data points */}
146
+ {chartData.points.map((point, i) => (
147
+ <circle
148
+ key={i}
149
+ cx={point.x}
150
+ cy={point.y}
151
+ r="3.5"
152
+ fill="#0f172a"
153
+ stroke={color}
154
+ strokeWidth="2"
155
+ />
156
+ ))}
157
+
158
+ {/* X-axis labels */}
159
+ {showLabels &&
160
+ chartData.points
161
+ .filter((_, i) => {
162
+ const step = Math.max(1, Math.floor(data.length / 6));
163
+ return i % step === 0 || i === data.length - 1;
164
+ })
165
+ .map((point, i) => (
166
+ <text
167
+ key={i}
168
+ x={point.x}
169
+ y={chartData.chartHeight - 8}
170
+ textAnchor="middle"
171
+ fill="rgba(255,255,255,0.3)"
172
+ fontSize="11"
173
+ >
174
+ {point.label}
175
+ </text>
176
+ ))}
177
+ </svg>
178
+ </div>
179
+ );
180
+ }
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+
3
+ interface StatsCardProps {
4
+ title: string;
5
+ value: string | number;
6
+ change?: number;
7
+ changeLabel?: string;
8
+ icon?: React.ReactNode;
9
+ }
10
+
11
+ export default function StatsCard({
12
+ title,
13
+ value,
14
+ change,
15
+ changeLabel = 'vs last period',
16
+ icon,
17
+ }: StatsCardProps) {
18
+ const isPositive = change !== undefined && change >= 0;
19
+ const changeColor = isPositive ? 'text-emerald-400' : 'text-red-400';
20
+ const changeIcon = isPositive ? '\u2191' : '\u2193';
21
+
22
+ return (
23
+ <div className="backdrop-blur-xl bg-white/5 border border-white/10 rounded-2xl p-6 hover:bg-white/[0.07] transition-all group">
24
+ <div className="flex items-start justify-between mb-4">
25
+ <p className="text-sm font-medium text-white/50 uppercase tracking-wider">
26
+ {title}
27
+ </p>
28
+ {icon && (
29
+ <div className="p-2 bg-cyan-500/10 rounded-lg text-cyan-400 group-hover:bg-cyan-500/20 transition-colors">
30
+ {icon}
31
+ </div>
32
+ )}
33
+ </div>
34
+
35
+ <p className="text-3xl font-bold text-white mb-2">{value}</p>
36
+
37
+ {change !== undefined && (
38
+ <div className="flex items-center gap-1.5">
39
+ <span className={`text-sm font-medium ${changeColor}`}>
40
+ {changeIcon} {Math.abs(change).toFixed(1)}%
41
+ </span>
42
+ <span className="text-xs text-white/30">{changeLabel}</span>
43
+ </div>
44
+ )}
45
+ </div>
46
+ );
47
+ }
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+
3
+ interface SummaryGridProps {
4
+ children: React.ReactNode;
5
+ columns?: 2 | 3 | 4;
6
+ title?: string;
7
+ subtitle?: string;
8
+ }
9
+
10
+ const columnClasses: Record<number, string> = {
11
+ 2: 'grid-cols-1 sm:grid-cols-2',
12
+ 3: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3',
13
+ 4: 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-4',
14
+ };
15
+
16
+ export default function SummaryGrid({
17
+ children,
18
+ columns = 4,
19
+ title,
20
+ subtitle,
21
+ }: SummaryGridProps) {
22
+ return (
23
+ <div>
24
+ {(title || subtitle) && (
25
+ <div className="mb-6">
26
+ {title && (
27
+ <h2 className="text-xl font-bold text-white">{title}</h2>
28
+ )}
29
+ {subtitle && (
30
+ <p className="text-sm text-white/50 mt-1">{subtitle}</p>
31
+ )}
32
+ </div>
33
+ )}
34
+ <div className={`grid ${columnClasses[columns]} gap-4`}>
35
+ {children}
36
+ </div>
37
+ </div>
38
+ );
39
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "dashboard-analytics",
3
+ "version": "1.0.0",
4
+ "description": "Analytics dashboard with stats cards, line charts, activity feed, and summary grid",
5
+ "author": "AD AI Engine",
6
+ "category": "dashboard",
7
+ "dependencies": [],
8
+ "files": {
9
+ "components": [
10
+ "components/dashboard/StatsCard.tsx",
11
+ "components/dashboard/LineChart.tsx",
12
+ "components/dashboard/ActivityFeed.tsx",
13
+ "components/dashboard/SummaryGrid.tsx"
14
+ ],
15
+ "api": []
16
+ },
17
+ "schema": null,
18
+ "instructions": "1. Import components into your dashboard page\n2. Pass data props to each component\n3. Use SummaryGrid as the layout wrapper for StatsCards\n4. LineChart accepts an array of { label, value } data points\n5. ActivityFeed accepts an array of activity items with timestamp, user, and action"
19
+ }
@@ -0,0 +1,59 @@
1
+ 'use client';
2
+
3
+ interface BulkActionsProps {
4
+ selectedCount: number;
5
+ totalCount: number;
6
+ onSelectAll: () => void;
7
+ onDeselectAll: () => void;
8
+ onDeleteSelected: () => void;
9
+ allSelected: boolean;
10
+ }
11
+
12
+ export default function BulkActions({
13
+ selectedCount,
14
+ totalCount,
15
+ onSelectAll,
16
+ onDeselectAll,
17
+ onDeleteSelected,
18
+ allSelected,
19
+ }: BulkActionsProps) {
20
+ if (selectedCount === 0) return null;
21
+
22
+ return (
23
+ <div className="flex items-center gap-3 px-4 py-2.5 bg-cyan-500/10 border border-cyan-500/20 rounded-lg">
24
+ <span className="text-sm text-cyan-400 font-medium">
25
+ {selectedCount} of {totalCount} selected
26
+ </span>
27
+
28
+ <div className="h-4 w-px bg-white/10" />
29
+
30
+ {!allSelected ? (
31
+ <button
32
+ onClick={onSelectAll}
33
+ className="text-sm text-white/60 hover:text-white transition-colors"
34
+ >
35
+ Select all
36
+ </button>
37
+ ) : (
38
+ <button
39
+ onClick={onDeselectAll}
40
+ className="text-sm text-white/60 hover:text-white transition-colors"
41
+ >
42
+ Deselect all
43
+ </button>
44
+ )}
45
+
46
+ <div className="ml-auto">
47
+ <button
48
+ onClick={onDeleteSelected}
49
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500/10 border border-red-500/20 rounded-lg text-sm text-red-400 hover:bg-red-500/20 transition-all"
50
+ >
51
+ <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
52
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
53
+ </svg>
54
+ Delete selected
55
+ </button>
56
+ </div>
57
+ </div>
58
+ );
59
+ }
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+
3
+ import { useState, useRef, useEffect } from 'react';
4
+
5
+ interface ColumnToggleProps {
6
+ columns: { key: string; label: string }[];
7
+ visibleColumns: Set<string>;
8
+ onToggle: (key: string) => void;
9
+ }
10
+
11
+ export default function ColumnToggle({
12
+ columns,
13
+ visibleColumns,
14
+ onToggle,
15
+ }: ColumnToggleProps) {
16
+ const [open, setOpen] = useState(false);
17
+ const ref = useRef<HTMLDivElement>(null);
18
+
19
+ useEffect(() => {
20
+ function handleClickOutside(e: MouseEvent) {
21
+ if (ref.current && !ref.current.contains(e.target as Node)) {
22
+ setOpen(false);
23
+ }
24
+ }
25
+ document.addEventListener('mousedown', handleClickOutside);
26
+ return () => document.removeEventListener('mousedown', handleClickOutside);
27
+ }, []);
28
+
29
+ return (
30
+ <div className="relative" ref={ref}>
31
+ <button
32
+ onClick={() => setOpen(!open)}
33
+ className="flex items-center gap-2 px-3 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-white/70 hover:bg-white/10 hover:text-white transition-all"
34
+ >
35
+ <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
36
+ <path strokeLinecap="round" strokeLinejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
37
+ <path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
38
+ </svg>
39
+ Columns
40
+ </button>
41
+
42
+ {open && (
43
+ <div className="absolute right-0 top-full mt-2 w-56 backdrop-blur-xl bg-gray-900/95 border border-white/10 rounded-lg shadow-xl z-50 py-2">
44
+ <p className="px-3 py-1.5 text-xs font-medium text-white/40 uppercase tracking-wider">
45
+ Toggle columns
46
+ </p>
47
+ {columns.map((col) => (
48
+ <label
49
+ key={col.key}
50
+ className="flex items-center gap-2.5 px-3 py-2 hover:bg-white/5 cursor-pointer transition-colors"
51
+ >
52
+ <input
53
+ type="checkbox"
54
+ checked={visibleColumns.has(col.key)}
55
+ onChange={() => onToggle(col.key)}
56
+ className="w-4 h-4 rounded border-white/20 bg-white/5 text-cyan-500 focus:ring-cyan-500/50 focus:ring-offset-0"
57
+ />
58
+ <span className="text-sm text-white/70">{col.label}</span>
59
+ </label>
60
+ ))}
61
+ </div>
62
+ )}
63
+ </div>
64
+ );
65
+ }