@pattern-stack/frontend-patterns 0.0.6 → 0.1.1

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 (86) hide show
  1. package/dist/atoms/composed/index.d.ts +0 -1
  2. package/dist/atoms/composed/index.d.ts.map +1 -1
  3. package/dist/atoms/types/index.d.ts +0 -2
  4. package/dist/atoms/types/index.d.ts.map +1 -1
  5. package/dist/atoms/ui/ErrorBoundary.d.ts +1 -1
  6. package/dist/atoms/ui/button.d.ts +1 -1
  7. package/dist/atoms/utils/utils.d.ts +0 -2
  8. package/dist/atoms/utils/utils.d.ts.map +1 -1
  9. package/dist/features/auth/components/ProtectedRoute.d.ts +1 -1
  10. package/dist/frontend-patterns.css +1 -1
  11. package/dist/index.es.js +15 -403
  12. package/dist/index.es.js.map +1 -1
  13. package/dist/index.js +14 -403
  14. package/dist/index.js.map +1 -1
  15. package/dist/molecules/layout/Sidebar.d.ts.map +1 -1
  16. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts +0 -2
  17. package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts.map +1 -1
  18. package/dist/molecules/layout/index.d.ts +0 -3
  19. package/dist/molecules/layout/index.d.ts.map +1 -1
  20. package/dist/templates/factory.d.ts +1 -2
  21. package/dist/templates/factory.d.ts.map +1 -1
  22. package/dist/templates/index.d.ts.map +1 -1
  23. package/package.json +3 -7
  24. package/src/App.tsx +1 -11
  25. package/src/atoms/composed/index.ts +0 -1
  26. package/src/atoms/types/index.ts +1 -3
  27. package/src/atoms/utils/utils.ts +2 -4
  28. package/src/molecules/layout/Sidebar.tsx +23 -10
  29. package/src/molecules/layout/SidebarButton/SidebarButton.tsx +10 -32
  30. package/src/molecules/layout/index.ts +1 -4
  31. package/src/organisms/index.ts +1 -5
  32. package/src/pages/AdminShowcase/AdminDashboardShowcase.tsx +75 -77
  33. package/src/pages/AdminShowcase/index.tsx +1 -2
  34. package/src/pages/index.ts +1 -2
  35. package/src/templates/factory.tsx +7 -14
  36. package/src/templates/index.ts +0 -4
  37. package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts +0 -19
  38. package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts.map +0 -1
  39. package/dist/atoms/composed/SalesPanel/index.d.ts +0 -2
  40. package/dist/atoms/composed/SalesPanel/index.d.ts.map +0 -1
  41. package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts +0 -63
  42. package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts.map +0 -1
  43. package/dist/atoms/types/entity-config.d.ts +0 -117
  44. package/dist/atoms/types/entity-config.d.ts.map +0 -1
  45. package/dist/atoms/types/navigation.d.ts +0 -30
  46. package/dist/atoms/types/navigation.d.ts.map +0 -1
  47. package/dist/atoms/utils/icon-resolver.d.ts +0 -72
  48. package/dist/atoms/utils/icon-resolver.d.ts.map +0 -1
  49. package/dist/atoms/utils/metric-engine.d.ts +0 -30
  50. package/dist/atoms/utils/metric-engine.d.ts.map +0 -1
  51. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts +0 -16
  52. package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts.map +0 -1
  53. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts +0 -2
  54. package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts.map +0 -1
  55. package/dist/molecules/layout/NavigationContext.d.ts +0 -15
  56. package/dist/molecules/layout/NavigationContext.d.ts.map +0 -1
  57. package/src/__tests__/atoms/composed/databadge.test.tsx +0 -106
  58. package/src/__tests__/atoms/composed/statcard.test.tsx +0 -133
  59. package/src/__tests__/atoms/utils/icon-resolver.test.tsx +0 -140
  60. package/src/atoms/composed/SalesPanel/SalesPanel.tsx +0 -116
  61. package/src/atoms/composed/SalesPanel/index.ts +0 -1
  62. package/src/atoms/composed/SalesPanel/mockSalesData.ts +0 -151
  63. package/src/atoms/types/entity-config.ts +0 -127
  64. package/src/atoms/types/navigation.ts +0 -43
  65. package/src/atoms/utils/icon-resolver.tsx +0 -54
  66. package/src/atoms/utils/metric-engine.ts +0 -236
  67. package/src/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.tsx +0 -42
  68. package/src/molecules/layout/DashboardWithSidePanel/index.ts +0 -1
  69. package/src/molecules/layout/NavigationContext.tsx +0 -63
  70. package/src/organisms/entity/CategoryBreakdownPanel.tsx +0 -427
  71. package/src/organisms/entity/EntityListPanel.tsx +0 -339
  72. package/src/organisms/entity/MetricsOverviewPanel.tsx +0 -236
  73. package/src/organisms/entity/TrendAnalysisPanel.tsx +0 -337
  74. package/src/organisms/entity/index.ts +0 -4
  75. package/src/pages/AdminShowcase/SalesPerformanceDashboard.tsx +0 -158
  76. package/src/pages/EntityShowcase/EntityManagementShowcase.tsx +0 -137
  77. package/src/pages/EntityShowcase/EntityPerformanceShowcase.tsx +0 -117
  78. package/src/pages/EntityShowcase/index.ts +0 -2
  79. package/src/pages/EntityTemplateExample.tsx +0 -229
  80. package/src/pages/TestEntityTemplate.tsx +0 -40
  81. package/src/templates/entity/EntityManagementTemplate.tsx +0 -430
  82. package/src/templates/entity/EntityPerformanceDashboardTemplate.tsx +0 -277
  83. package/src/templates/entity/configs/financial-config.ts +0 -141
  84. package/src/templates/entity/configs/index.ts +0 -1
  85. package/src/templates/entity/index.ts +0 -3
  86. package/src/templates/financial/FinancialDashboardTemplate.tsx +0 -326
@@ -1,337 +0,0 @@
1
- import React, { useMemo, useState } from 'react';
2
- import { Chart } from '../../atoms/composed/Chart';
3
- import type { ChartDataPoint, ChartType } from '../../atoms/composed/Chart';
4
- import { Card } from '../../atoms/ui/card';
5
- import { Button } from '../../atoms/ui/button';
6
- import { Select } from '../../atoms/ui/Select';
7
- import { Badge } from '../../atoms/ui/Badge';
8
- import { MetricCalculationEngine } from '../../atoms/utils/metric-engine';
9
- import type { MetricConfig, EntityData, TemporalConfig, TemporalCycle } from '../../atoms/types';
10
- import { cn } from '../../atoms/utils/utils';
11
- import { TrendingUp, BarChart3, LineChart, AreaChart, Download } from 'lucide-react';
12
-
13
- export interface TrendAnalysisPanelProps {
14
- metrics: MetricConfig[];
15
- data: EntityData[];
16
- temporal?: TemporalConfig;
17
- isLoading?: boolean;
18
- className?: string;
19
- category?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
20
-
21
- // Chart configuration
22
- defaultChartType?: ChartType;
23
- dateField?: string;
24
- enablePeriodSelection?: boolean;
25
- enableChartTypeSelection?: boolean;
26
- enableMetricSelection?: boolean;
27
- showComparisons?: boolean;
28
-
29
- // Extension points
30
- renderHeader?: () => React.ReactNode;
31
- renderFooter?: () => React.ReactNode;
32
- renderCustomChart?: (metric: MetricConfig, chartData: ChartDataPoint[], chartType: ChartType) => React.ReactNode;
33
- headerSlot?: React.ReactNode;
34
- footerSlot?: React.ReactNode;
35
-
36
- // Event handlers
37
- onMetricChange?: (metric: MetricConfig) => void;
38
- onPeriodChange?: (period: TemporalCycle) => void;
39
- onChartTypeChange?: (chartType: ChartType) => void;
40
- onExport?: (data: ChartDataPoint[], metric: MetricConfig) => void;
41
- }
42
-
43
- export const TrendAnalysisPanel: React.FC<TrendAnalysisPanelProps> = ({
44
- metrics,
45
- data,
46
- temporal,
47
- isLoading = false,
48
- className,
49
- category,
50
- defaultChartType = 'line',
51
- dateField = 'date',
52
- enablePeriodSelection = true,
53
- enableChartTypeSelection = true,
54
- enableMetricSelection = true,
55
- showComparisons = true,
56
- renderHeader,
57
- renderFooter,
58
- renderCustomChart,
59
- headerSlot,
60
- footerSlot,
61
- onMetricChange,
62
- onPeriodChange,
63
- onChartTypeChange,
64
- onExport
65
- }) => {
66
- const [selectedMetric, setSelectedMetric] = useState<MetricConfig>(metrics[0]);
67
- const [selectedPeriod, setSelectedPeriod] = useState<TemporalCycle>(temporal?.defaultCycle || 'monthly');
68
- const [selectedChartType, setSelectedChartType] = useState<ChartType>(defaultChartType);
69
- const [showForecast, setShowForecast] = useState(false);
70
-
71
- // Calculate trend data for selected metric
72
- const trendData = useMemo(() => {
73
- if (!selectedMetric || !data.length) return [];
74
-
75
- // Determine periods to show based on selected cycle
76
- const periods = selectedPeriod === 'yearly' ? 5 :
77
- selectedPeriod === 'quarterly' ? 8 :
78
- selectedPeriod === 'monthly' ? 12 :
79
- selectedPeriod === 'weekly' ? 12 : 30;
80
-
81
- return MetricCalculationEngine.calculateTrendData(
82
- selectedMetric,
83
- data,
84
- dateField,
85
- periods
86
- );
87
- }, [selectedMetric, data, dateField, selectedPeriod]);
88
-
89
- // Convert trend data to chart format
90
- const chartData = useMemo((): ChartDataPoint[] => {
91
- return trendData.map(point => ({
92
- label: point.label || point.date,
93
- value: point.value,
94
- category: category
95
- }));
96
- }, [trendData, category]);
97
-
98
- // Calculate trend percentage
99
- const trendPercentage = useMemo(() => {
100
- if (chartData.length < 2) return null;
101
-
102
- const first = chartData[0].value;
103
- const last = chartData[chartData.length - 1].value;
104
-
105
- if (first === 0) return null;
106
-
107
- return ((last - first) / Math.abs(first)) * 100;
108
- }, [chartData]);
109
-
110
- // Generate forecast data if enabled
111
- const forecastData = useMemo(() => {
112
- if (!showForecast || !temporal?.forecasting?.enabled || chartData.length < 3) {
113
- return [];
114
- }
115
-
116
- const periods = temporal?.forecasting?.periods || 3;
117
- const lastValue = chartData[chartData.length - 1].value;
118
- const trend = trendPercentage ? trendPercentage / 100 : 0;
119
-
120
- return Array.from({ length: periods }, (_, index) => ({
121
- label: `Future ${index + 1}`,
122
- value: lastValue * (1 + trend * (index + 1) / chartData.length),
123
- category: 8 as const // Use category 8 for forecast
124
- }));
125
- }, [showForecast, temporal?.forecasting, chartData, trendPercentage]);
126
-
127
- // Combined chart data with forecast
128
- const combinedChartData = useMemo(() => {
129
- if (forecastData.length === 0) return chartData;
130
- return [...chartData, ...forecastData];
131
- }, [chartData, forecastData]);
132
-
133
- const handleMetricChange = (metricKey: string) => {
134
- const metric = metrics.find(m => m.key === metricKey);
135
- if (metric) {
136
- setSelectedMetric(metric);
137
- onMetricChange?.(metric);
138
- }
139
- };
140
-
141
- const handlePeriodChange = (period: TemporalCycle) => {
142
- setSelectedPeriod(period);
143
- onPeriodChange?.(period);
144
- };
145
-
146
- const handleChartTypeChange = (chartType: ChartType) => {
147
- setSelectedChartType(chartType);
148
- onChartTypeChange?.(chartType);
149
- };
150
-
151
- const handleExport = () => {
152
- if (onExport) {
153
- onExport(combinedChartData, selectedMetric);
154
- } else {
155
- // Default CSV export
156
- const csvContent = [
157
- 'Date,Value',
158
- ...combinedChartData.map(point => `${point.label},${point.value}`)
159
- ].join('\n');
160
-
161
- const blob = new Blob([csvContent], { type: 'text/csv' });
162
- const url = URL.createObjectURL(blob);
163
- const a = document.createElement('a');
164
- a.href = url;
165
- a.download = `${selectedMetric.label}-trend-data.csv`;
166
- a.click();
167
- URL.revokeObjectURL(url);
168
- }
169
- };
170
-
171
- const renderControls = () => {
172
- return (
173
- <div className="flex items-center justify-between mb-4">
174
- <div className="flex items-center gap-4">
175
- <div className="flex items-center gap-2">
176
- <TrendingUp className="w-4 h-4 text-muted-foreground" />
177
- <h3 className="text-lg font-semibold text-foreground">Trend Analysis</h3>
178
- </div>
179
-
180
- {trendPercentage !== null && (
181
- <Badge variant={trendPercentage > 0 ? 'default' : 'destructive'}>
182
- {trendPercentage > 0 ? '+' : ''}{trendPercentage.toFixed(1)}%
183
- </Badge>
184
- )}
185
- </div>
186
-
187
- <div className="flex items-center gap-2">
188
- {enableMetricSelection && metrics.length > 1 && (
189
- <Select
190
- value={selectedMetric.key}
191
- onValueChange={handleMetricChange}
192
- >
193
- {metrics.map(metric => (
194
- <option key={metric.key} value={metric.key}>
195
- {metric.label}
196
- </option>
197
- ))}
198
- </Select>
199
- )}
200
-
201
- {enablePeriodSelection && (
202
- <Select
203
- value={selectedPeriod}
204
- onValueChange={(value) => handlePeriodChange(value as TemporalCycle)}
205
- >
206
- {(temporal?.cycles || ['daily', 'weekly', 'monthly', 'quarterly', 'yearly']).map(cycle => (
207
- <option key={cycle} value={cycle}>
208
- {cycle.charAt(0).toUpperCase() + cycle.slice(1)}
209
- </option>
210
- ))}
211
- </Select>
212
- )}
213
-
214
- {enableChartTypeSelection && (
215
- <div className="flex items-center border rounded">
216
- <Button
217
- variant={selectedChartType === 'line' ? 'default' : 'ghost'}
218
- size="sm"
219
- onClick={() => handleChartTypeChange('line')}
220
- >
221
- <LineChart className="w-4 h-4" />
222
- </Button>
223
- <Button
224
- variant={selectedChartType === 'bar' ? 'default' : 'ghost'}
225
- size="sm"
226
- onClick={() => handleChartTypeChange('bar')}
227
- >
228
- <BarChart3 className="w-4 h-4" />
229
- </Button>
230
- <Button
231
- variant={selectedChartType === 'area' ? 'default' : 'ghost'}
232
- size="sm"
233
- onClick={() => handleChartTypeChange('area')}
234
- >
235
- <AreaChart className="w-4 h-4" />
236
- </Button>
237
- </div>
238
- )}
239
-
240
- {temporal?.forecasting?.enabled && (
241
- <Button
242
- variant={showForecast ? 'default' : 'outline'}
243
- size="sm"
244
- onClick={() => setShowForecast(!showForecast)}
245
- >
246
- Forecast
247
- </Button>
248
- )}
249
-
250
- <Button
251
- variant="outline"
252
- size="sm"
253
- onClick={handleExport}
254
- disabled={chartData.length === 0}
255
- >
256
- <Download className="w-4 h-4" />
257
- </Button>
258
- </div>
259
- </div>
260
- );
261
- };
262
-
263
- const renderChart = () => {
264
- if (renderCustomChart) {
265
- const customChart = renderCustomChart(selectedMetric, combinedChartData, selectedChartType);
266
- if (customChart) return customChart;
267
- }
268
-
269
- return (
270
- <Chart
271
- title={selectedMetric.label}
272
- subtitle={`${selectedPeriod} trend analysis`}
273
- data={combinedChartData}
274
- type={selectedChartType}
275
- category={category}
276
- showTrend={true}
277
- trend={trendPercentage !== null ? {
278
- value: trendPercentage,
279
- label: 'overall trend'
280
- } : undefined}
281
- height="large"
282
- isLoading={isLoading}
283
- noWrapper={true}
284
- showLegend={forecastData.length > 0}
285
- />
286
- );
287
- };
288
-
289
- const renderComparisons = () => {
290
- if (!showComparisons || !temporal?.enableComparisons || chartData.length === 0) {
291
- return null;
292
- }
293
-
294
- const currentValue = chartData[chartData.length - 1]?.value || 0;
295
- const previousValue = chartData[chartData.length - 2]?.value || 0;
296
- const periodChange = previousValue !== 0 ? ((currentValue - previousValue) / Math.abs(previousValue)) * 100 : 0;
297
-
298
- return (
299
- <div className="border-t pt-4 mt-4">
300
- <h4 className="text-sm font-semibold text-foreground mb-3">Period Comparisons</h4>
301
- <div className="grid grid-cols-3 gap-4">
302
- <div className="text-center">
303
- <div className="text-2xl font-bold">{currentValue.toFixed(0)}</div>
304
- <div className="text-xs text-muted-foreground">Current</div>
305
- </div>
306
- <div className="text-center">
307
- <div className="text-2xl font-bold">{previousValue.toFixed(0)}</div>
308
- <div className="text-xs text-muted-foreground">Previous</div>
309
- </div>
310
- <div className="text-center">
311
- <div className={cn(
312
- "text-2xl font-bold",
313
- periodChange > 0 ? 'text-status-success' : periodChange < 0 ? 'text-status-error' : 'text-muted-foreground'
314
- )}>
315
- {periodChange > 0 ? '+' : ''}{periodChange.toFixed(1)}%
316
- </div>
317
- <div className="text-xs text-muted-foreground">Change</div>
318
- </div>
319
- </div>
320
- </div>
321
- );
322
- };
323
-
324
- return (
325
- <Card className={cn('p-6', className)} category={category} data-component-name="TrendAnalysisPanel">
326
- {headerSlot}
327
- {renderHeader && renderHeader()}
328
-
329
- {renderControls()}
330
- {renderChart()}
331
- {renderComparisons()}
332
-
333
- {renderFooter && renderFooter()}
334
- {footerSlot}
335
- </Card>
336
- );
337
- };
@@ -1,4 +0,0 @@
1
- export * from './MetricsOverviewPanel';
2
- export * from './EntityListPanel';
3
- export * from './TrendAnalysisPanel';
4
- export * from './CategoryBreakdownPanel';
@@ -1,158 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { DashboardWithSidePanel } from '../../molecules/layout';
3
- import { SalesPanel } from '../../atoms/composed/SalesPanel';
4
- import { DataTable, StatCard, Chart } from '../../atoms/composed';
5
- import { Card } from '../../atoms/ui/card';
6
- import { mockSalesData } from '../../atoms/composed/SalesPanel/mockSalesData';
7
- import { Button } from '../../atoms/ui/button';
8
- import { Eye, Filter, Calendar, TrendingUp, Users, Target, DollarSign } from 'lucide-react';
9
-
10
-
11
- // Mock data for main dashboard
12
- const salesMetrics = [
13
- { title: 'Total Revenue', value: '$1.2M', trend: { value: 15.3, label: 'from last month' }, icon: <DollarSign className="w-5 h-5" />, category: 2 as const },
14
- { title: 'Deals Closed', value: '47', trend: { value: 12.8, label: 'from last month' }, icon: <Target className="w-5 h-5" />, category: 3 as const },
15
- { title: 'Conversion Rate', value: '24.5%', trend: { value: -2.1, label: 'from last month' }, icon: <TrendingUp className="w-5 h-5" />, category: 1 as const },
16
- { title: 'Active Prospects', value: '156', trend: { value: 8.7, label: 'from last month' }, icon: <Users className="w-5 h-5" />, category: 4 as const }
17
- ];
18
-
19
- const salesTrendData = [
20
- { label: 'Jan', value: 85000 },
21
- { label: 'Feb', value: 92000 },
22
- { label: 'Mar', value: 108000 },
23
- { label: 'Apr', value: 125000 },
24
- { label: 'May', value: 118000 },
25
- { label: 'Jun', value: 135000 }
26
- ];
27
-
28
- const allSalesColumns = [
29
- { key: 'customer', header: 'Customer', render: (value: string) => <div className="font-medium">{value}</div> },
30
- { key: 'product', header: 'Product', render: (value: string) => <div className="text-sm">{value}</div> },
31
- { key: 'amount', header: 'Value', render: (value: number) => <div className="font-semibold text-green-600">${value.toLocaleString()}</div> },
32
- { key: 'stage', header: 'Stage', render: (value: string) => <span className="text-sm">{value}</span> },
33
- { key: 'salesperson', header: 'Sales Rep', render: (value: string) => <div className="text-sm">{value}</div> },
34
- { key: 'region', header: 'Region', render: (value: string) => <div className="text-sm">{value}</div> }
35
- ];
36
-
37
- export const SalesPerformanceDashboard: React.FC = () => {
38
- const [showSidePanel, setShowSidePanel] = useState(true);
39
-
40
- const handleSaleClick = (sale: any) => {
41
- console.log('Deal selected:', sale);
42
- };
43
-
44
- return (
45
- <DashboardWithSidePanel
46
- showSidePanel={showSidePanel}
47
- sidePanel={
48
- <SalesPanel
49
- sales={mockSalesData}
50
- onSaleClick={handleSaleClick}
51
- onClose={() => setShowSidePanel(false)}
52
- />
53
- }
54
- >
55
- <div className="p-6 space-y-6">
56
- {/* Header */}
57
- <div className="flex items-center justify-between">
58
- <div>
59
- <h1 className="text-2xl font-bold">Sales Performance</h1>
60
- <p className="text-muted-foreground">Monitor sales metrics, team performance, and revenue trends</p>
61
- </div>
62
- <div className="flex gap-2">
63
- <Button
64
- variant="outline"
65
- size="sm"
66
- onClick={() => setShowSidePanel(!showSidePanel)}
67
- >
68
- <Eye className="w-4 h-4 mr-2" />
69
- {showSidePanel ? 'Hide' : 'Show'} Pipeline
70
- </Button>
71
- <Button variant="outline" size="sm">
72
- <Filter className="w-4 h-4 mr-2" />
73
- Filter by Region
74
- </Button>
75
- <Button variant="outline" size="sm">
76
- <Calendar className="w-4 h-4 mr-2" />
77
- Date Range
78
- </Button>
79
- </div>
80
- </div>
81
-
82
- {/* Metrics */}
83
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
84
- {salesMetrics.map((metric, index) => (
85
- <StatCard
86
- key={index}
87
- title={metric.title}
88
- value={metric.value}
89
- trend={metric.trend}
90
- icon={metric.icon}
91
- category={metric.category}
92
- />
93
- ))}
94
- </div>
95
-
96
- {/* Charts */}
97
- <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
98
- <Card className="p-6">
99
- <Chart
100
- title="Revenue Trend"
101
- type="line"
102
- data={salesTrendData}
103
- category={2}
104
- noWrapper={true}
105
- />
106
- </Card>
107
-
108
- <Card className="p-6">
109
- <h3 className="font-semibold mb-4">Sales by Region</h3>
110
- <div className="space-y-3">
111
- <div className="flex justify-between items-center">
112
- <span>North America</span>
113
- <div className="flex items-center gap-2">
114
- <div className="w-24 h-2 bg-muted rounded-full overflow-hidden">
115
- <div className="w-3/5 h-full bg-category-2 rounded-full"></div>
116
- </div>
117
- <span className="text-sm font-medium">$750K</span>
118
- </div>
119
- </div>
120
- <div className="flex justify-between items-center">
121
- <span>Europe</span>
122
- <div className="flex items-center gap-2">
123
- <div className="w-24 h-2 bg-muted rounded-full overflow-hidden">
124
- <div className="w-2/5 h-full bg-category-1 rounded-full"></div>
125
- </div>
126
- <span className="text-sm font-medium">$320K</span>
127
- </div>
128
- </div>
129
- <div className="flex justify-between items-center">
130
- <span>Asia Pacific</span>
131
- <div className="flex items-center gap-2">
132
- <div className="w-24 h-2 bg-muted rounded-full overflow-hidden">
133
- <div className="w-1/4 h-full bg-category-3 rounded-full"></div>
134
- </div>
135
- <span className="text-sm font-medium">$130K</span>
136
- </div>
137
- </div>
138
- </div>
139
- </Card>
140
- </div>
141
-
142
- {/* Detailed Sales Table */}
143
- <Card className="p-6">
144
- <h3 className="font-semibold mb-4">All Sales Opportunities</h3>
145
- <DataTable
146
- data={mockSalesData}
147
- columns={allSalesColumns}
148
- showSearch={true}
149
- searchPlaceholder="Search deals, customers, or products..."
150
- onRowClick={handleSaleClick}
151
- />
152
- </Card>
153
- </div>
154
- </DashboardWithSidePanel>
155
- );
156
- };
157
-
158
- export default SalesPerformanceDashboard;
@@ -1,137 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { EntityListPanel } from '../../organisms/entity';
3
- import { financialConfig, sampleFinancialData, type FinancialTransaction } from '../../templates/entity/configs/financial-config';
4
- import { ShowcaseSection } from '../../molecules/layout/ShowcaseSection';
5
- import { IconBadge } from '../../atoms/composed/IconBadge';
6
- import { Switch } from '../../atoms/ui/Switch';
7
- import { Button } from '../../atoms/ui/button';
8
- import { Database, Filter, Search, Download, Plus, Layers } from 'lucide-react';
9
-
10
- export const EntityManagementShowcase: React.FC = () => {
11
- const [enableSearch, setEnableSearch] = useState(true);
12
- const [enableFiltering, setEnableFiltering] = useState(true);
13
- const [enableBulkActions, setEnableBulkActions] = useState(true);
14
- const [enableExport, setEnableExport] = useState(true);
15
-
16
- return (
17
- <div className="min-h-screen bg-background">
18
- <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-12">
19
- <div className="flex items-center justify-between mb-12">
20
- <div className="flex items-center space-x-4">
21
- <IconBadge
22
- variant="category"
23
- category={7}
24
- size="lg"
25
- icon={<Database className="w-6 h-6" />}
26
- />
27
- <div>
28
- <h1 className="text-4xl font-bold text-foreground">Entity Management</h1>
29
- <p className="text-lg text-muted-foreground mt-2">
30
- Cross-domain template for CRUD operations with intelligent search, filtering, and bulk actions
31
- </p>
32
- </div>
33
- </div>
34
-
35
- <div className="flex items-center space-x-3">
36
- <Button variant="outline" size="sm">
37
- <Plus className="w-4 h-4 mr-2" />
38
- Add Transaction
39
- </Button>
40
- <div className="flex items-center gap-3 bg-card/80 backdrop-blur-sm border border-border/50 rounded px-3 py-2">
41
- <Layers className="w-4 h-4 text-muted-foreground" />
42
- <span className="text-sm font-medium text-foreground">Demo Mode</span>
43
- <Switch checked={true} disabled />
44
- </div>
45
- </div>
46
- </div>
47
-
48
- {/* Feature Toggles */}
49
- <div className="mb-8">
50
- <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
51
- <div className="flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border/30 rounded px-3 py-2">
52
- <Search className="w-4 h-4 text-muted-foreground" />
53
- <span className="text-sm font-medium text-foreground">Search</span>
54
- <Switch
55
- checked={enableSearch}
56
- onCheckedChange={setEnableSearch}
57
- />
58
- </div>
59
- <div className="flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border/30 rounded px-3 py-2">
60
- <Filter className="w-4 h-4 text-muted-foreground" />
61
- <span className="text-sm font-medium text-foreground">Filters</span>
62
- <Switch
63
- checked={enableFiltering}
64
- onCheckedChange={setEnableFiltering}
65
- />
66
- </div>
67
- <div className="flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border/30 rounded px-3 py-2">
68
- <Database className="w-4 h-4 text-muted-foreground" />
69
- <span className="text-sm font-medium text-foreground">Bulk Actions</span>
70
- <Switch
71
- checked={enableBulkActions}
72
- onCheckedChange={setEnableBulkActions}
73
- />
74
- </div>
75
- <div className="flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border/30 rounded px-3 py-2">
76
- <Download className="w-4 h-4 text-muted-foreground" />
77
- <span className="text-sm font-medium text-foreground">Export</span>
78
- <Switch
79
- checked={enableExport}
80
- onCheckedChange={setEnableExport}
81
- />
82
- </div>
83
- </div>
84
- </div>
85
-
86
- <div className="space-y-12">
87
- <ShowcaseSection
88
- title="Entity List with Advanced Features"
89
- description="Smart data table with domain-aware column rendering, search, filtering, and bulk operations"
90
- badge={{
91
- text: "Full Featured",
92
- variant: "category",
93
- category: 3
94
- }}
95
- >
96
- <EntityListPanel
97
- config={financialConfig}
98
- data={sampleFinancialData}
99
- isLoading={false}
100
- enableSearch={enableSearch}
101
- enableFiltering={enableFiltering}
102
- enableBulkActions={enableBulkActions}
103
- enableExport={enableExport}
104
- onItemClick={(item: FinancialTransaction) => {
105
- console.log('Item clicked:', item);
106
- }}
107
- onItemEdit={(item: FinancialTransaction) => {
108
- console.log('Item edit:', item);
109
- }}
110
- onItemDelete={(item: FinancialTransaction) => {
111
- console.log('Item delete:', item);
112
- }}
113
- onBulkAction={(action: string, items: FinancialTransaction[]) => {
114
- console.log('Bulk action:', action, items);
115
- }}
116
- onSearch={(query: string) => {
117
- console.log('Search:', query);
118
- }}
119
- onFilter={(filters: Record<string, any>) => {
120
- console.log('Filter:', filters);
121
- }}
122
- onSort={(field: string, direction: 'asc' | 'desc') => {
123
- console.log('Sort:', field, direction);
124
- }}
125
- onExport={(format: 'csv' | 'json' | 'xlsx') => {
126
- console.log('Export:', format);
127
- return Promise.resolve();
128
- }}
129
- />
130
- </ShowcaseSection>
131
- </div>
132
- </div>
133
- </div>
134
- );
135
- };
136
-
137
- export default EntityManagementShowcase;