@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.
- package/dist/atoms/composed/index.d.ts +0 -1
- package/dist/atoms/composed/index.d.ts.map +1 -1
- package/dist/atoms/types/index.d.ts +0 -2
- package/dist/atoms/types/index.d.ts.map +1 -1
- package/dist/atoms/ui/ErrorBoundary.d.ts +1 -1
- package/dist/atoms/ui/button.d.ts +1 -1
- package/dist/atoms/utils/utils.d.ts +0 -2
- package/dist/atoms/utils/utils.d.ts.map +1 -1
- package/dist/features/auth/components/ProtectedRoute.d.ts +1 -1
- package/dist/frontend-patterns.css +1 -1
- package/dist/index.es.js +15 -403
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +14 -403
- package/dist/index.js.map +1 -1
- package/dist/molecules/layout/Sidebar.d.ts.map +1 -1
- package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts +0 -2
- package/dist/molecules/layout/SidebarButton/SidebarButton.d.ts.map +1 -1
- package/dist/molecules/layout/index.d.ts +0 -3
- package/dist/molecules/layout/index.d.ts.map +1 -1
- package/dist/templates/factory.d.ts +1 -2
- package/dist/templates/factory.d.ts.map +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/package.json +3 -7
- package/src/App.tsx +1 -11
- package/src/atoms/composed/index.ts +0 -1
- package/src/atoms/types/index.ts +1 -3
- package/src/atoms/utils/utils.ts +2 -4
- package/src/molecules/layout/Sidebar.tsx +23 -10
- package/src/molecules/layout/SidebarButton/SidebarButton.tsx +10 -32
- package/src/molecules/layout/index.ts +1 -4
- package/src/organisms/index.ts +1 -5
- package/src/pages/AdminShowcase/AdminDashboardShowcase.tsx +75 -77
- package/src/pages/AdminShowcase/index.tsx +1 -2
- package/src/pages/index.ts +1 -2
- package/src/templates/factory.tsx +7 -14
- package/src/templates/index.ts +0 -4
- package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts +0 -19
- package/dist/atoms/composed/SalesPanel/SalesPanel.d.ts.map +0 -1
- package/dist/atoms/composed/SalesPanel/index.d.ts +0 -2
- package/dist/atoms/composed/SalesPanel/index.d.ts.map +0 -1
- package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts +0 -63
- package/dist/atoms/composed/SalesPanel/mockSalesData.d.ts.map +0 -1
- package/dist/atoms/types/entity-config.d.ts +0 -117
- package/dist/atoms/types/entity-config.d.ts.map +0 -1
- package/dist/atoms/types/navigation.d.ts +0 -30
- package/dist/atoms/types/navigation.d.ts.map +0 -1
- package/dist/atoms/utils/icon-resolver.d.ts +0 -72
- package/dist/atoms/utils/icon-resolver.d.ts.map +0 -1
- package/dist/atoms/utils/metric-engine.d.ts +0 -30
- package/dist/atoms/utils/metric-engine.d.ts.map +0 -1
- package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts +0 -16
- package/dist/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.d.ts.map +0 -1
- package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts +0 -2
- package/dist/molecules/layout/DashboardWithSidePanel/index.d.ts.map +0 -1
- package/dist/molecules/layout/NavigationContext.d.ts +0 -15
- package/dist/molecules/layout/NavigationContext.d.ts.map +0 -1
- package/src/__tests__/atoms/composed/databadge.test.tsx +0 -106
- package/src/__tests__/atoms/composed/statcard.test.tsx +0 -133
- package/src/__tests__/atoms/utils/icon-resolver.test.tsx +0 -140
- package/src/atoms/composed/SalesPanel/SalesPanel.tsx +0 -116
- package/src/atoms/composed/SalesPanel/index.ts +0 -1
- package/src/atoms/composed/SalesPanel/mockSalesData.ts +0 -151
- package/src/atoms/types/entity-config.ts +0 -127
- package/src/atoms/types/navigation.ts +0 -43
- package/src/atoms/utils/icon-resolver.tsx +0 -54
- package/src/atoms/utils/metric-engine.ts +0 -236
- package/src/molecules/layout/DashboardWithSidePanel/DashboardWithSidePanel.tsx +0 -42
- package/src/molecules/layout/DashboardWithSidePanel/index.ts +0 -1
- package/src/molecules/layout/NavigationContext.tsx +0 -63
- package/src/organisms/entity/CategoryBreakdownPanel.tsx +0 -427
- package/src/organisms/entity/EntityListPanel.tsx +0 -339
- package/src/organisms/entity/MetricsOverviewPanel.tsx +0 -236
- package/src/organisms/entity/TrendAnalysisPanel.tsx +0 -337
- package/src/organisms/entity/index.ts +0 -4
- package/src/pages/AdminShowcase/SalesPerformanceDashboard.tsx +0 -158
- package/src/pages/EntityShowcase/EntityManagementShowcase.tsx +0 -137
- package/src/pages/EntityShowcase/EntityPerformanceShowcase.tsx +0 -117
- package/src/pages/EntityShowcase/index.ts +0 -2
- package/src/pages/EntityTemplateExample.tsx +0 -229
- package/src/pages/TestEntityTemplate.tsx +0 -40
- package/src/templates/entity/EntityManagementTemplate.tsx +0 -430
- package/src/templates/entity/EntityPerformanceDashboardTemplate.tsx +0 -277
- package/src/templates/entity/configs/financial-config.ts +0 -141
- package/src/templates/entity/configs/index.ts +0 -1
- package/src/templates/entity/index.ts +0 -3
- package/src/templates/financial/FinancialDashboardTemplate.tsx +0 -326
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import './frontend-patterns.css';
|
|
2
1
|
"use strict";
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -7,18 +6,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
7
6
|
const clsx = require("clsx");
|
|
8
7
|
const tailwindMerge = require("tailwind-merge");
|
|
9
8
|
const React = require("react");
|
|
10
|
-
const jsxRuntime = require("react/jsx-runtime");
|
|
11
|
-
const lucideReact = require("lucide-react");
|
|
12
9
|
const classVarianceAuthority = require("class-variance-authority");
|
|
13
10
|
const axios = require("axios");
|
|
14
11
|
const reactQuery = require("@tanstack/react-query");
|
|
12
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
15
13
|
const reactSlot = require("@radix-ui/react-slot");
|
|
16
14
|
const LabelPrimitive = require("@radix-ui/react-label");
|
|
17
15
|
const AvatarPrimitive = require("@radix-ui/react-avatar");
|
|
18
16
|
const DropdownMenuPrimitive = require("@radix-ui/react-dropdown-menu");
|
|
17
|
+
const lucideReact = require("lucide-react");
|
|
19
18
|
const reactDom = require("react-dom");
|
|
20
19
|
const reactRouterDom = require("react-router-dom");
|
|
21
20
|
const client = require("react-dom/client");
|
|
21
|
+
require("@tanstack/react-query-devtools");
|
|
22
22
|
function _interopNamespaceDefault(e) {
|
|
23
23
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
24
24
|
if (e) {
|
|
@@ -264,240 +264,6 @@ const tooltipContent = {
|
|
|
264
264
|
profile: "Profile",
|
|
265
265
|
account: "Account settings"
|
|
266
266
|
};
|
|
267
|
-
class MetricCalculationEngine {
|
|
268
|
-
static calculateMetric(config, data, previousData) {
|
|
269
|
-
const currentValue = this.aggregateValue(config, data);
|
|
270
|
-
const previousValue = previousData ? this.aggregateValue(config, previousData) : void 0;
|
|
271
|
-
const trend = this.calculateTrend(currentValue, previousValue);
|
|
272
|
-
const formattedValue = this.formatValue(currentValue, config.format, config.type);
|
|
273
|
-
const target = typeof config.target === "function" ? config.target(data) : config.target;
|
|
274
|
-
return {
|
|
275
|
-
current: currentValue,
|
|
276
|
-
previous: previousValue,
|
|
277
|
-
trend,
|
|
278
|
-
target,
|
|
279
|
-
formattedValue
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
static aggregateValue(config, data) {
|
|
283
|
-
if (!data.length) return 0;
|
|
284
|
-
const values = data.map((item) => {
|
|
285
|
-
const value = this.extractValue(item, config.key);
|
|
286
|
-
return typeof value === "number" ? value : 0;
|
|
287
|
-
}).filter((value) => !isNaN(value));
|
|
288
|
-
if (!values.length) return 0;
|
|
289
|
-
switch (config.aggregation || "sum") {
|
|
290
|
-
case "sum":
|
|
291
|
-
return values.reduce((sum, value) => sum + value, 0);
|
|
292
|
-
case "avg":
|
|
293
|
-
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
294
|
-
case "count":
|
|
295
|
-
return values.length;
|
|
296
|
-
case "min":
|
|
297
|
-
return Math.min(...values);
|
|
298
|
-
case "max":
|
|
299
|
-
return Math.max(...values);
|
|
300
|
-
default:
|
|
301
|
-
return values.reduce((sum, value) => sum + value, 0);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
static extractValue(item, key) {
|
|
305
|
-
return key.split(".").reduce((obj, k) => obj == null ? void 0 : obj[k], item);
|
|
306
|
-
}
|
|
307
|
-
static calculateTrend(current, previous) {
|
|
308
|
-
if (previous === void 0 || previous === 0) return "neutral";
|
|
309
|
-
const change = (current - previous) / Math.abs(previous) * 100;
|
|
310
|
-
if (change > 1) return "up";
|
|
311
|
-
if (change < -1) return "down";
|
|
312
|
-
return "neutral";
|
|
313
|
-
}
|
|
314
|
-
static formatValue(value, format, type) {
|
|
315
|
-
let formatted = value;
|
|
316
|
-
if ((format == null ? void 0 : format.decimals) !== void 0) {
|
|
317
|
-
formatted = Number(value.toFixed(format.decimals));
|
|
318
|
-
}
|
|
319
|
-
let result = formatted.toString();
|
|
320
|
-
if ((format == null ? void 0 : format.thousands) !== false && Math.abs(formatted) >= 1e3) {
|
|
321
|
-
result = formatted.toLocaleString();
|
|
322
|
-
}
|
|
323
|
-
switch (type) {
|
|
324
|
-
case "currency":
|
|
325
|
-
result = new Intl.NumberFormat("en-US", {
|
|
326
|
-
style: "currency",
|
|
327
|
-
currency: "USD",
|
|
328
|
-
minimumFractionDigits: (format == null ? void 0 : format.decimals) ?? 2,
|
|
329
|
-
maximumFractionDigits: (format == null ? void 0 : format.decimals) ?? 2
|
|
330
|
-
}).format(formatted);
|
|
331
|
-
break;
|
|
332
|
-
case "percentage":
|
|
333
|
-
result = `${formatted.toFixed((format == null ? void 0 : format.decimals) ?? 1)}%`;
|
|
334
|
-
break;
|
|
335
|
-
case "duration":
|
|
336
|
-
result = this.formatDuration(formatted);
|
|
337
|
-
break;
|
|
338
|
-
case "ratio":
|
|
339
|
-
result = `${formatted.toFixed((format == null ? void 0 : format.decimals) ?? 2)}:1`;
|
|
340
|
-
break;
|
|
341
|
-
default:
|
|
342
|
-
if (format == null ? void 0 : format.prefix) result = format.prefix + result;
|
|
343
|
-
if (format == null ? void 0 : format.suffix) result = result + format.suffix;
|
|
344
|
-
}
|
|
345
|
-
return result;
|
|
346
|
-
}
|
|
347
|
-
static formatDuration(minutes) {
|
|
348
|
-
const hours = Math.floor(minutes / 60);
|
|
349
|
-
const mins = Math.floor(minutes % 60);
|
|
350
|
-
if (hours > 0) {
|
|
351
|
-
return `${hours}h ${mins}m`;
|
|
352
|
-
}
|
|
353
|
-
return `${mins}m`;
|
|
354
|
-
}
|
|
355
|
-
static calculateTrendData(config, data, dateField = "date", periods = 12) {
|
|
356
|
-
const groupedData = this.groupByPeriod(data, dateField);
|
|
357
|
-
const sortedDates = Object.keys(groupedData).sort();
|
|
358
|
-
return sortedDates.slice(-periods).map((date) => ({
|
|
359
|
-
date,
|
|
360
|
-
value: this.aggregateValue(config, groupedData[date]),
|
|
361
|
-
label: this.formatDateLabel(date)
|
|
362
|
-
}));
|
|
363
|
-
}
|
|
364
|
-
static groupByPeriod(data, dateField) {
|
|
365
|
-
return data.reduce((groups, item) => {
|
|
366
|
-
const date = this.extractValue(item, dateField);
|
|
367
|
-
if (!date) return groups;
|
|
368
|
-
const period = new Date(date).toISOString().split("T")[0];
|
|
369
|
-
if (!groups[period]) groups[period] = [];
|
|
370
|
-
groups[period].push(item);
|
|
371
|
-
return groups;
|
|
372
|
-
}, {});
|
|
373
|
-
}
|
|
374
|
-
static formatDateLabel(dateString) {
|
|
375
|
-
const date = new Date(dateString);
|
|
376
|
-
return date.toLocaleDateString("en-US", {
|
|
377
|
-
month: "short",
|
|
378
|
-
day: "numeric"
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
static calculateCategoryBreakdown(data, categoryField, valueField, maxCategories = 8) {
|
|
382
|
-
const groups = data.reduce((acc, item) => {
|
|
383
|
-
const category = String(this.extractValue(item, categoryField) || "Unknown");
|
|
384
|
-
const value = this.extractValue(item, valueField) || 0;
|
|
385
|
-
if (!acc[category]) acc[category] = 0;
|
|
386
|
-
acc[category] += typeof value === "number" ? value : 0;
|
|
387
|
-
return acc;
|
|
388
|
-
}, {});
|
|
389
|
-
const total = Object.values(groups).reduce((sum, value) => sum + value, 0);
|
|
390
|
-
let categories = Object.entries(groups).map(([category, value]) => ({
|
|
391
|
-
category,
|
|
392
|
-
value,
|
|
393
|
-
percentage: total > 0 ? value / total * 100 : 0
|
|
394
|
-
})).sort((a, b) => b.value - a.value);
|
|
395
|
-
if (categories.length > maxCategories) {
|
|
396
|
-
const topCategories = categories.slice(0, maxCategories - 1);
|
|
397
|
-
const otherValue = categories.slice(maxCategories - 1).reduce((sum, cat) => sum + cat.value, 0);
|
|
398
|
-
topCategories.push({
|
|
399
|
-
category: "Other",
|
|
400
|
-
value: otherValue,
|
|
401
|
-
percentage: total > 0 ? otherValue / total * 100 : 0
|
|
402
|
-
});
|
|
403
|
-
categories = topCategories;
|
|
404
|
-
}
|
|
405
|
-
return categories;
|
|
406
|
-
}
|
|
407
|
-
static detectInsights(metrics, thresholds = {}) {
|
|
408
|
-
const insights = [];
|
|
409
|
-
for (const [key, metric] of Object.entries(metrics)) {
|
|
410
|
-
const threshold = thresholds[key];
|
|
411
|
-
if (metric.target && metric.current < metric.target * 0.8) {
|
|
412
|
-
insights.push({
|
|
413
|
-
type: "negative",
|
|
414
|
-
message: `${key} is significantly below target`,
|
|
415
|
-
value: metric.current
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
if (metric.trend === "up" && metric.previous && metric.current > metric.previous * 1.2) {
|
|
419
|
-
insights.push({
|
|
420
|
-
type: "positive",
|
|
421
|
-
message: `${key} showing strong growth`,
|
|
422
|
-
value: metric.current
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
if (threshold && metric.current >= threshold.critical) {
|
|
426
|
-
insights.push({
|
|
427
|
-
type: "negative",
|
|
428
|
-
message: `${key} has reached critical threshold`,
|
|
429
|
-
value: metric.current
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return insights.slice(0, 5);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
const iconMap = {
|
|
437
|
-
Palette: lucideReact.Palette,
|
|
438
|
-
Menu: lucideReact.Menu,
|
|
439
|
-
X: lucideReact.X,
|
|
440
|
-
Shield: lucideReact.Shield,
|
|
441
|
-
Users: lucideReact.Users,
|
|
442
|
-
BarChart3: lucideReact.BarChart3,
|
|
443
|
-
Database: lucideReact.Database,
|
|
444
|
-
TrendingUp: lucideReact.TrendingUp,
|
|
445
|
-
Layout: lucideReact.Layout,
|
|
446
|
-
Home: lucideReact.Home,
|
|
447
|
-
Settings: lucideReact.Settings,
|
|
448
|
-
Bell: lucideReact.Bell,
|
|
449
|
-
Search: lucideReact.Search,
|
|
450
|
-
Plus: lucideReact.Plus,
|
|
451
|
-
Edit: lucideReact.Edit,
|
|
452
|
-
Trash2: lucideReact.Trash2,
|
|
453
|
-
Eye: lucideReact.Eye,
|
|
454
|
-
Download: lucideReact.Download,
|
|
455
|
-
Upload: lucideReact.Upload,
|
|
456
|
-
Share: lucideReact.Share,
|
|
457
|
-
Lock: lucideReact.Lock,
|
|
458
|
-
Unlock: lucideReact.Unlock,
|
|
459
|
-
Mail: lucideReact.Mail,
|
|
460
|
-
Phone: lucideReact.Phone,
|
|
461
|
-
Calendar: lucideReact.Calendar,
|
|
462
|
-
Clock: lucideReact.Clock,
|
|
463
|
-
MapPin: lucideReact.MapPin,
|
|
464
|
-
Star: lucideReact.Star,
|
|
465
|
-
Heart: lucideReact.Heart,
|
|
466
|
-
Bookmark: lucideReact.Bookmark,
|
|
467
|
-
Tag: lucideReact.Tag,
|
|
468
|
-
Flag: lucideReact.Flag,
|
|
469
|
-
File: lucideReact.File,
|
|
470
|
-
Folder: lucideReact.Folder,
|
|
471
|
-
Image: lucideReact.Image,
|
|
472
|
-
Video: lucideReact.Video,
|
|
473
|
-
Music: lucideReact.Music,
|
|
474
|
-
ChevronRight: lucideReact.ChevronRight,
|
|
475
|
-
ChevronDown: lucideReact.ChevronDown,
|
|
476
|
-
ChevronLeft: lucideReact.ChevronLeft,
|
|
477
|
-
ChevronUp: lucideReact.ChevronUp,
|
|
478
|
-
ArrowRight: lucideReact.ArrowRight,
|
|
479
|
-
ArrowLeft: lucideReact.ArrowLeft,
|
|
480
|
-
ArrowUp: lucideReact.ArrowUp,
|
|
481
|
-
ArrowDown: lucideReact.ArrowDown,
|
|
482
|
-
Check: lucideReact.Check,
|
|
483
|
-
AlertCircle: lucideReact.AlertCircle,
|
|
484
|
-
Info: lucideReact.Info,
|
|
485
|
-
HelpCircle: lucideReact.HelpCircle
|
|
486
|
-
};
|
|
487
|
-
const Icon = ({ name, className = "w-5 h-5", size, ...props }) => {
|
|
488
|
-
const IconComponent = iconMap[name];
|
|
489
|
-
if (!IconComponent) {
|
|
490
|
-
console.warn(`Icon "${name}" not found. Using default Menu icon.`);
|
|
491
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className, size, ...props });
|
|
492
|
-
}
|
|
493
|
-
return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className, size, ...props });
|
|
494
|
-
};
|
|
495
|
-
const getIcon = (name) => {
|
|
496
|
-
return iconMap[name] || lucideReact.Menu;
|
|
497
|
-
};
|
|
498
|
-
const isValidIcon = (name) => {
|
|
499
|
-
return name in iconMap;
|
|
500
|
-
};
|
|
501
267
|
function cn(...inputs) {
|
|
502
268
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
503
269
|
}
|
|
@@ -1519,83 +1285,6 @@ const DataBadge = ({
|
|
|
1519
1285
|
}
|
|
1520
1286
|
return badge;
|
|
1521
1287
|
};
|
|
1522
|
-
const getStageStatus = (stage) => {
|
|
1523
|
-
switch (stage) {
|
|
1524
|
-
case "Closed Won":
|
|
1525
|
-
return "success";
|
|
1526
|
-
case "Negotiation":
|
|
1527
|
-
return "warning";
|
|
1528
|
-
case "Proposal Sent":
|
|
1529
|
-
return "info";
|
|
1530
|
-
case "Qualified":
|
|
1531
|
-
return "info";
|
|
1532
|
-
case "Discovery":
|
|
1533
|
-
return "neutral";
|
|
1534
|
-
default:
|
|
1535
|
-
return "neutral";
|
|
1536
|
-
}
|
|
1537
|
-
};
|
|
1538
|
-
const SalesPanel = ({
|
|
1539
|
-
sales,
|
|
1540
|
-
onSaleClick,
|
|
1541
|
-
onClose
|
|
1542
|
-
}) => {
|
|
1543
|
-
const topDeals = sales.slice(0, 5);
|
|
1544
|
-
const totalValue = sales.reduce((sum, sale) => sum + sale.amount, 0);
|
|
1545
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed right-0 top-16 h-[calc(100vh-4rem)] w-72 bg-background border-l border-border shadow-lg flex flex-col z-30", children: [
|
|
1546
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1547
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "font-medium flex items-center gap-2", children: [
|
|
1548
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Target, { className: "w-4 h-4" }),
|
|
1549
|
-
"Pipeline"
|
|
1550
|
-
] }),
|
|
1551
|
-
onClose && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, children: "×" })
|
|
1552
|
-
] }) }),
|
|
1553
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1554
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
1555
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Total Value" }),
|
|
1556
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-green-600", children: [
|
|
1557
|
-
"$",
|
|
1558
|
-
totalValue.toLocaleString()
|
|
1559
|
-
] })
|
|
1560
|
-
] }),
|
|
1561
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
1562
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Active Deals" }),
|
|
1563
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: sales.length })
|
|
1564
|
-
] })
|
|
1565
|
-
] }) }),
|
|
1566
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto p-3", children: [
|
|
1567
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-medium mb-3", children: "Recent Opportunities" }),
|
|
1568
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: topDeals.map((sale) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1569
|
-
"div",
|
|
1570
|
-
{
|
|
1571
|
-
className: "p-2 border border-border rounded-md hover:bg-muted/50 cursor-pointer transition-colors",
|
|
1572
|
-
onClick: () => onSaleClick == null ? void 0 : onSaleClick(sale),
|
|
1573
|
-
children: [
|
|
1574
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-start mb-1", children: [
|
|
1575
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1576
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium truncate", children: sale.customer }),
|
|
1577
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground truncate", children: sale.product })
|
|
1578
|
-
] }),
|
|
1579
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right ml-2", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-semibold text-green-600", children: [
|
|
1580
|
-
"$",
|
|
1581
|
-
sale.amount.toLocaleString()
|
|
1582
|
-
] }) })
|
|
1583
|
-
] }),
|
|
1584
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
1585
|
-
/* @__PURE__ */ jsxRuntime.jsx(DataBadge, { variant: "status", status: getStageStatus(sale.stage), children: sale.stage }),
|
|
1586
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: sale.salesperson })
|
|
1587
|
-
] })
|
|
1588
|
-
]
|
|
1589
|
-
},
|
|
1590
|
-
sale.id
|
|
1591
|
-
)) })
|
|
1592
|
-
] }),
|
|
1593
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", className: "w-full", children: [
|
|
1594
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-4 h-4 mr-2" }),
|
|
1595
|
-
"View All Deals"
|
|
1596
|
-
] }) })
|
|
1597
|
-
] });
|
|
1598
|
-
};
|
|
1599
1288
|
const StatCard = ({
|
|
1600
1289
|
title,
|
|
1601
1290
|
value,
|
|
@@ -5860,42 +5549,6 @@ const useSidebar = () => {
|
|
|
5860
5549
|
}
|
|
5861
5550
|
return context;
|
|
5862
5551
|
};
|
|
5863
|
-
const NavigationContext = React.createContext(void 0);
|
|
5864
|
-
const defaultShowcaseNavigation = [
|
|
5865
|
-
{ value: "showcase", label: "Showcase", icon: "Palette", path: "/showcase", category: 5 },
|
|
5866
|
-
{ value: "admin-dashboard", label: "Admin Dashboard", icon: "Shield", path: "/admin/dashboard", category: 2 },
|
|
5867
|
-
{ value: "admin-users", label: "User Management", icon: "Users", path: "/admin/users", category: 3 },
|
|
5868
|
-
{ value: "admin-sales", label: "Sales Dashboard", icon: "TrendingUp", path: "/admin/sales", category: 4 },
|
|
5869
|
-
{ value: "entity-performance", label: "Performance Dashboard", icon: "BarChart3", path: "/entity/performance", category: 6 },
|
|
5870
|
-
{ value: "entity-management", label: "Entity Management", icon: "Database", path: "/entity/management", category: 7 },
|
|
5871
|
-
{ value: "entity-template", label: "Template Example", icon: "Layout", path: "/entity/template-example", category: 1 }
|
|
5872
|
-
];
|
|
5873
|
-
const NavigationProvider = ({ children, initialNavigation }) => {
|
|
5874
|
-
const [navigation, setNavigation] = React.useState(
|
|
5875
|
-
initialNavigation || {
|
|
5876
|
-
items: defaultShowcaseNavigation,
|
|
5877
|
-
showDefaultNavigation: true,
|
|
5878
|
-
defaultExpanded: true
|
|
5879
|
-
}
|
|
5880
|
-
);
|
|
5881
|
-
return /* @__PURE__ */ jsxRuntime.jsx(NavigationContext.Provider, { value: { navigation, setNavigation }, children });
|
|
5882
|
-
};
|
|
5883
|
-
const useNavigation = () => {
|
|
5884
|
-
const context = React.useContext(NavigationContext);
|
|
5885
|
-
if (context === void 0) {
|
|
5886
|
-
throw new Error("useNavigation must be used within a NavigationProvider");
|
|
5887
|
-
}
|
|
5888
|
-
return context;
|
|
5889
|
-
};
|
|
5890
|
-
const getNavigationItems = (config) => {
|
|
5891
|
-
if (config.items.length > 0) {
|
|
5892
|
-
return config.items;
|
|
5893
|
-
}
|
|
5894
|
-
if (config.showDefaultNavigation !== false) {
|
|
5895
|
-
return defaultShowcaseNavigation;
|
|
5896
|
-
}
|
|
5897
|
-
return [];
|
|
5898
|
-
};
|
|
5899
5552
|
const SidebarButton = ({
|
|
5900
5553
|
icon,
|
|
5901
5554
|
label,
|
|
@@ -5903,16 +5556,13 @@ const SidebarButton = ({
|
|
|
5903
5556
|
category = 1,
|
|
5904
5557
|
expanded = false,
|
|
5905
5558
|
onClick,
|
|
5906
|
-
className
|
|
5907
|
-
badge,
|
|
5908
|
-
disabled = false
|
|
5559
|
+
className
|
|
5909
5560
|
}) => {
|
|
5910
5561
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5911
5562
|
Button,
|
|
5912
5563
|
{
|
|
5913
5564
|
variant: active ? "secondary" : "ghost",
|
|
5914
5565
|
onClick,
|
|
5915
|
-
disabled,
|
|
5916
5566
|
tooltip: !expanded ? label : void 0,
|
|
5917
5567
|
className: cn(
|
|
5918
5568
|
"relative w-full justify-start gap-3 h-12",
|
|
@@ -5946,19 +5596,12 @@ const SidebarButton = ({
|
|
|
5946
5596
|
"text-sm font-medium flex-1 text-left",
|
|
5947
5597
|
active ? `text-category-${category}` : "text-foreground"
|
|
5948
5598
|
), children: label }),
|
|
5949
|
-
|
|
5950
|
-
"px-2 py-0.5 text-xs font-medium rounded-full flex-shrink-0",
|
|
5951
|
-
"bg-primary/10 text-primary"
|
|
5952
|
-
), children: badge }) : active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
5599
|
+
active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
5953
5600
|
"w-2 h-2 rounded-full flex-shrink-0",
|
|
5954
5601
|
`bg-category-${category}`
|
|
5955
5602
|
) })
|
|
5956
5603
|
] }),
|
|
5957
|
-
!expanded &&
|
|
5958
|
-
"px-1.5 py-0.5 text-xs font-bold rounded-full",
|
|
5959
|
-
"bg-primary text-primary-foreground",
|
|
5960
|
-
"ring-2 ring-background"
|
|
5961
|
-
), children: badge }) : active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
5604
|
+
!expanded && active && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -right-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
5962
5605
|
"w-2.5 h-2.5 rounded-full",
|
|
5963
5606
|
`bg-category-${category}`,
|
|
5964
5607
|
"ring-2 ring-background"
|
|
@@ -5969,11 +5612,14 @@ const SidebarButton = ({
|
|
|
5969
5612
|
};
|
|
5970
5613
|
const Sidebar = ({ className }) => {
|
|
5971
5614
|
const { isExpanded, toggleSidebar } = useSidebar();
|
|
5972
|
-
const { navigation } = useNavigation();
|
|
5973
5615
|
const location = reactRouterDom.useLocation();
|
|
5974
5616
|
const navigate = reactRouterDom.useNavigate();
|
|
5975
5617
|
const [searchParams] = reactRouterDom.useSearchParams();
|
|
5976
|
-
const items =
|
|
5618
|
+
const items = [
|
|
5619
|
+
{ value: "showcase", label: "Showcase", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: "w-5 h-5" }), path: "/showcase", category: 5 },
|
|
5620
|
+
{ value: "admin-dashboard", label: "Admin Dashboard", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Shield, { className: "w-5 h-5" }), path: "/admin/dashboard", category: 2 },
|
|
5621
|
+
{ value: "admin-users", label: "User Management", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Users, { className: "w-5 h-5" }), path: "/admin/users", category: 3 }
|
|
5622
|
+
];
|
|
5977
5623
|
const handleNavigation = (path) => {
|
|
5978
5624
|
if (path.includes("?")) {
|
|
5979
5625
|
const [basePath, query] = path.split("?");
|
|
@@ -6029,14 +5675,12 @@ const Sidebar = ({ className }) => {
|
|
|
6029
5675
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6030
5676
|
SidebarButton,
|
|
6031
5677
|
{
|
|
6032
|
-
icon:
|
|
5678
|
+
icon: item.icon,
|
|
6033
5679
|
label: item.label,
|
|
6034
5680
|
active: isActive,
|
|
6035
5681
|
category: item.category,
|
|
6036
5682
|
expanded: isExpanded,
|
|
6037
|
-
onClick: () => handleNavigation(item.path)
|
|
6038
|
-
badge: item.badge,
|
|
6039
|
-
disabled: item.disabled
|
|
5683
|
+
onClick: () => handleNavigation(item.path)
|
|
6040
5684
|
},
|
|
6041
5685
|
item.value
|
|
6042
5686
|
);
|
|
@@ -6102,28 +5746,6 @@ const AppLayout = () => {
|
|
|
6102
5746
|
)
|
|
6103
5747
|
] });
|
|
6104
5748
|
};
|
|
6105
|
-
const DashboardWithSidePanel = ({
|
|
6106
|
-
children,
|
|
6107
|
-
sidePanel,
|
|
6108
|
-
showSidePanel = false,
|
|
6109
|
-
sidePanelWidth = 72,
|
|
6110
|
-
className
|
|
6111
|
-
}) => {
|
|
6112
|
-
const marginClass = `pr-${sidePanelWidth}`;
|
|
6113
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative h-full", className), children: [
|
|
6114
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6115
|
-
"div",
|
|
6116
|
-
{
|
|
6117
|
-
className: cn(
|
|
6118
|
-
"transition-all duration-300",
|
|
6119
|
-
showSidePanel ? marginClass : ""
|
|
6120
|
-
),
|
|
6121
|
-
children
|
|
6122
|
-
}
|
|
6123
|
-
),
|
|
6124
|
-
showSidePanel && sidePanel
|
|
6125
|
-
] });
|
|
6126
|
-
};
|
|
6127
5749
|
const SectionHeader = ({
|
|
6128
5750
|
title,
|
|
6129
5751
|
description,
|
|
@@ -8146,7 +7768,6 @@ function createReactApp(config) {
|
|
|
8146
7768
|
enableQuery = true,
|
|
8147
7769
|
enableRouting = true,
|
|
8148
7770
|
auth,
|
|
8149
|
-
navigation,
|
|
8150
7771
|
customProviders = []
|
|
8151
7772
|
} = appConfig;
|
|
8152
7773
|
const queryClient = new reactQuery.QueryClient({
|
|
@@ -8181,7 +7802,7 @@ function createReactApp(config) {
|
|
|
8181
7802
|
tree = /* @__PURE__ */ jsxRuntime.jsx(Provider, { children: tree }, Provider.name);
|
|
8182
7803
|
});
|
|
8183
7804
|
if (enableRouting) {
|
|
8184
|
-
tree = /* @__PURE__ */ jsxRuntime.jsx(
|
|
7805
|
+
tree = /* @__PURE__ */ jsxRuntime.jsx(SidebarProvider, { children: tree });
|
|
8185
7806
|
}
|
|
8186
7807
|
if (enableAuth) {
|
|
8187
7808
|
tree = /* @__PURE__ */ jsxRuntime.jsx(AuthProvider, { config: auth, children: tree });
|
|
@@ -10447,7 +10068,6 @@ exports.DarkModeToggle = DarkModeToggle;
|
|
|
10447
10068
|
exports.DashboardCard = DashboardCard;
|
|
10448
10069
|
exports.DashboardGrid = DashboardGrid;
|
|
10449
10070
|
exports.DashboardTemplate = DashboardTemplate;
|
|
10450
|
-
exports.DashboardWithSidePanel = DashboardWithSidePanel;
|
|
10451
10071
|
exports.DataBadge = DataBadge;
|
|
10452
10072
|
exports.DataDetailTemplate = DataDetailTemplate;
|
|
10453
10073
|
exports.DataTable = DataTable;
|
|
@@ -10475,17 +10095,14 @@ exports.FileUpload = FileUpload;
|
|
|
10475
10095
|
exports.FormField = FormField;
|
|
10476
10096
|
exports.FormGroup = FormGroup;
|
|
10477
10097
|
exports.GlobalSearch = GlobalSearch;
|
|
10478
|
-
exports.Icon = Icon;
|
|
10479
10098
|
exports.IconBadge = IconBadge;
|
|
10480
10099
|
exports.Input = Input;
|
|
10481
10100
|
exports.Label = Label;
|
|
10482
10101
|
exports.Loading = Loading;
|
|
10483
10102
|
exports.LoginForm = LoginForm;
|
|
10484
10103
|
exports.LogoutButton = LogoutButton;
|
|
10485
|
-
exports.MetricCalculationEngine = MetricCalculationEngine;
|
|
10486
10104
|
exports.Modal = Modal;
|
|
10487
10105
|
exports.NavMenu = NavMenu;
|
|
10488
|
-
exports.NavigationProvider = NavigationProvider;
|
|
10489
10106
|
exports.PageTemplate = PageTemplate;
|
|
10490
10107
|
exports.Pagination = Pagination;
|
|
10491
10108
|
exports.PaletteSwitcher = PaletteSwitcher;
|
|
@@ -10493,7 +10110,6 @@ exports.ProgressBar = ProgressBar;
|
|
|
10493
10110
|
exports.ProtectedRoute = ProtectedRoute;
|
|
10494
10111
|
exports.RESPONSIVE_CHART_HEIGHTS = RESPONSIVE_CHART_HEIGHTS;
|
|
10495
10112
|
exports.ROUTES = ROUTES;
|
|
10496
|
-
exports.SalesPanel = SalesPanel;
|
|
10497
10113
|
exports.SearchInput = SearchInput;
|
|
10498
10114
|
exports.SectionHeader = SectionHeader;
|
|
10499
10115
|
exports.Select = Select;
|
|
@@ -10502,7 +10118,6 @@ exports.SelectItem = SelectItem;
|
|
|
10502
10118
|
exports.SelectTrigger = SelectTrigger;
|
|
10503
10119
|
exports.SelectValue = SelectValue;
|
|
10504
10120
|
exports.ShowcaseSection = ShowcaseSection;
|
|
10505
|
-
exports.Sidebar = Sidebar;
|
|
10506
10121
|
exports.SidebarButton = SidebarButton;
|
|
10507
10122
|
exports.SidebarProvider = SidebarProvider;
|
|
10508
10123
|
exports.Skeleton = Skeleton;
|
|
@@ -10538,10 +10153,7 @@ exports.formatNumberWithTooltip = formatNumberWithTooltip;
|
|
|
10538
10153
|
exports.getAnimationClasses = getAnimationClasses;
|
|
10539
10154
|
exports.getChartHeight = getChartHeight;
|
|
10540
10155
|
exports.getContainerHeightClass = getContainerHeightClass;
|
|
10541
|
-
exports.getIcon = getIcon;
|
|
10542
|
-
exports.getNavigationItems = getNavigationItems;
|
|
10543
10156
|
exports.interactionVariants = interactionVariants;
|
|
10544
|
-
exports.isValidIcon = isValidIcon;
|
|
10545
10157
|
exports.legacyPatterns = legacyPatterns;
|
|
10546
10158
|
exports.setGlobalAuthService = setGlobalAuthService;
|
|
10547
10159
|
exports.tooltipContent = tooltipContent;
|
|
@@ -10551,7 +10163,6 @@ exports.useAuth = useAuth;
|
|
|
10551
10163
|
exports.useCreateExample = useCreateExample;
|
|
10552
10164
|
exports.useDeleteExample = useDeleteExample;
|
|
10553
10165
|
exports.useGetExample = useGetExample;
|
|
10554
|
-
exports.useNavigation = useNavigation;
|
|
10555
10166
|
exports.usePermissions = usePermissions;
|
|
10556
10167
|
exports.useSidebar = useSidebar;
|
|
10557
10168
|
exports.useTextOverflow = useTextOverflow;
|