@varity-labs/ui-kit 2.0.0-alpha.1 → 2.0.0-beta.2
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/LICENSE +2 -2
- package/README.md +197 -204
- package/dist/components/Analytics/DataTable.js +1 -1
- package/dist/components/Analytics/DataTable.js.map +1 -1
- package/dist/components/Analytics/EnhancedKPICard.d.ts +21 -0
- package/dist/components/Analytics/EnhancedKPICard.d.ts.map +1 -0
- package/dist/components/Analytics/EnhancedKPICard.js +135 -0
- package/dist/components/Analytics/EnhancedKPICard.js.map +1 -0
- package/dist/components/Analytics/Sparkline.d.ts +44 -0
- package/dist/components/Analytics/Sparkline.d.ts.map +1 -0
- package/dist/components/Analytics/Sparkline.js +90 -0
- package/dist/components/Analytics/Sparkline.js.map +1 -0
- package/dist/components/Analytics/index.d.ts +2 -0
- package/dist/components/Analytics/index.d.ts.map +1 -1
- package/dist/components/Analytics/index.js +2 -0
- package/dist/components/Analytics/index.js.map +1 -1
- package/dist/components/Dashboard/DashboardFooter.d.ts.map +1 -1
- package/dist/components/Dashboard/DashboardFooter.js +22 -6
- package/dist/components/Dashboard/DashboardFooter.js.map +1 -1
- package/dist/components/Dashboard/DashboardHeader.d.ts +10 -0
- package/dist/components/Dashboard/DashboardHeader.d.ts.map +1 -1
- package/dist/components/Dashboard/DashboardHeader.js +188 -55
- package/dist/components/Dashboard/DashboardHeader.js.map +1 -1
- package/dist/components/Dashboard/DashboardLayout.d.ts +11 -1
- package/dist/components/Dashboard/DashboardLayout.d.ts.map +1 -1
- package/dist/components/Dashboard/DashboardLayout.js +8 -3
- package/dist/components/Dashboard/DashboardLayout.js.map +1 -1
- package/dist/components/Dashboard/DashboardSidebar.d.ts.map +1 -1
- package/dist/components/Dashboard/DashboardSidebar.js +41 -12
- package/dist/components/Dashboard/DashboardSidebar.js.map +1 -1
- package/dist/components/Dashboard/EmptyState.js +5 -5
- package/dist/components/Dashboard/EmptyState.js.map +1 -1
- package/dist/components/Dashboard/KPICard.js +5 -5
- package/dist/components/Dashboard/KPICard.js.map +1 -1
- package/dist/components/Display/Avatar.d.ts +21 -0
- package/dist/components/Display/Avatar.d.ts.map +1 -0
- package/dist/components/Display/Avatar.js +71 -0
- package/dist/components/Display/Avatar.js.map +1 -0
- package/dist/components/Display/Badge.d.ts +22 -0
- package/dist/components/Display/Badge.d.ts.map +1 -0
- package/dist/components/Display/Badge.js +60 -0
- package/dist/components/Display/Badge.js.map +1 -0
- package/dist/components/Display/ProgressBar.d.ts +12 -0
- package/dist/components/Display/ProgressBar.d.ts.map +1 -0
- package/dist/components/Display/ProgressBar.js +33 -0
- package/dist/components/Display/ProgressBar.js.map +1 -0
- package/dist/components/Display/index.d.ts +9 -0
- package/dist/components/Display/index.d.ts.map +1 -0
- package/dist/components/Display/index.js +9 -0
- package/dist/components/Display/index.js.map +1 -0
- package/dist/components/Feedback/Skeleton.d.ts +10 -0
- package/dist/components/Feedback/Skeleton.d.ts.map +1 -0
- package/dist/components/Feedback/Skeleton.js +25 -0
- package/dist/components/Feedback/Skeleton.js.map +1 -0
- package/dist/components/Feedback/Toast.d.ts +18 -0
- package/dist/components/Feedback/Toast.d.ts.map +1 -0
- package/dist/components/Feedback/Toast.js +38 -0
- package/dist/components/Feedback/Toast.js.map +1 -0
- package/dist/components/Feedback/ToastProvider.d.ts +11 -0
- package/dist/components/Feedback/ToastProvider.d.ts.map +1 -0
- package/dist/components/Feedback/ToastProvider.js +36 -0
- package/dist/components/Feedback/ToastProvider.js.map +1 -0
- package/dist/components/Feedback/index.d.ts +11 -0
- package/dist/components/Feedback/index.d.ts.map +1 -0
- package/dist/components/Feedback/index.js +9 -0
- package/dist/components/Feedback/index.js.map +1 -0
- package/dist/components/Feedback/useToast.d.ts +3 -0
- package/dist/components/Feedback/useToast.d.ts.map +1 -0
- package/dist/components/Feedback/useToast.js +10 -0
- package/dist/components/Feedback/useToast.js.map +1 -0
- package/dist/components/Form/Button.d.ts +12 -0
- package/dist/components/Form/Button.d.ts.map +1 -0
- package/dist/components/Form/Button.js +22 -0
- package/dist/components/Form/Button.js.map +1 -0
- package/dist/components/Form/Checkbox.d.ts +13 -0
- package/dist/components/Form/Checkbox.d.ts.map +1 -0
- package/dist/components/Form/Checkbox.js +36 -0
- package/dist/components/Form/Checkbox.js.map +1 -0
- package/dist/components/Form/Input.d.ts +9 -0
- package/dist/components/Form/Input.d.ts.map +1 -0
- package/dist/components/Form/Input.js +16 -0
- package/dist/components/Form/Input.js.map +1 -0
- package/dist/components/Form/RadioGroup.d.ts +20 -0
- package/dist/components/Form/RadioGroup.d.ts.map +1 -0
- package/dist/components/Form/RadioGroup.js +43 -0
- package/dist/components/Form/RadioGroup.js.map +1 -0
- package/dist/components/Form/Select.d.ts +12 -0
- package/dist/components/Form/Select.d.ts.map +1 -0
- package/dist/components/Form/Select.js +13 -0
- package/dist/components/Form/Select.js.map +1 -0
- package/dist/components/Form/Textarea.d.ts +8 -0
- package/dist/components/Form/Textarea.d.ts.map +1 -0
- package/dist/components/Form/Textarea.js +13 -0
- package/dist/components/Form/Textarea.js.map +1 -0
- package/dist/components/Form/Toggle.d.ts +12 -0
- package/dist/components/Form/Toggle.d.ts.map +1 -0
- package/dist/components/Form/Toggle.js +48 -0
- package/dist/components/Form/Toggle.js.map +1 -0
- package/dist/components/Form/index.d.ts +13 -0
- package/dist/components/Form/index.d.ts.map +1 -0
- package/dist/components/Form/index.js +13 -0
- package/dist/components/Form/index.js.map +1 -0
- package/dist/components/InAppWallet/InAppWalletProvider.d.ts +4 -4
- package/dist/components/InAppWallet/InAppWalletProvider.d.ts.map +1 -1
- package/dist/components/InAppWallet/InAppWalletProvider.js +15 -28
- package/dist/components/InAppWallet/InAppWalletProvider.js.map +1 -1
- package/dist/components/Navigation/Breadcrumb.d.ts +15 -0
- package/dist/components/Navigation/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Navigation/Breadcrumb.js +28 -0
- package/dist/components/Navigation/Breadcrumb.js.map +1 -0
- package/dist/components/Navigation/CommandPalette.d.ts +26 -0
- package/dist/components/Navigation/CommandPalette.d.ts.map +1 -0
- package/dist/components/Navigation/CommandPalette.js +172 -0
- package/dist/components/Navigation/CommandPalette.js.map +1 -0
- package/dist/components/Navigation/index.d.ts +8 -0
- package/dist/components/Navigation/index.d.ts.map +1 -0
- package/dist/components/Navigation/index.js +8 -0
- package/dist/components/Navigation/index.js.map +1 -0
- package/dist/components/Onramp/BuyUSDCButton.d.ts +8 -6
- package/dist/components/Onramp/BuyUSDCButton.d.ts.map +1 -1
- package/dist/components/Onramp/BuyUSDCButton.js +36 -46
- package/dist/components/Onramp/BuyUSDCButton.js.map +1 -1
- package/dist/components/Onramp/OnrampWidget.d.ts +7 -6
- package/dist/components/Onramp/OnrampWidget.d.ts.map +1 -1
- package/dist/components/Onramp/OnrampWidget.js +56 -34
- package/dist/components/Onramp/OnrampWidget.js.map +1 -1
- package/dist/components/Onramp/index.d.ts +2 -3
- package/dist/components/Onramp/index.d.ts.map +1 -1
- package/dist/components/Onramp/index.js +2 -3
- package/dist/components/Onramp/index.js.map +1 -1
- package/dist/components/Overlay/ConfirmDialog.d.ts +14 -0
- package/dist/components/Overlay/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/Overlay/ConfirmDialog.js +11 -0
- package/dist/components/Overlay/ConfirmDialog.js.map +1 -0
- package/dist/components/Overlay/Dialog.d.ts +11 -0
- package/dist/components/Overlay/Dialog.d.ts.map +1 -0
- package/dist/components/Overlay/Dialog.js +69 -0
- package/dist/components/Overlay/Dialog.js.map +1 -0
- package/dist/components/Overlay/DropdownMenu.d.ts +17 -0
- package/dist/components/Overlay/DropdownMenu.d.ts.map +1 -0
- package/dist/components/Overlay/DropdownMenu.js +123 -0
- package/dist/components/Overlay/DropdownMenu.js.map +1 -0
- package/dist/components/Overlay/index.d.ts +9 -0
- package/dist/components/Overlay/index.d.ts.map +1 -0
- package/dist/components/Overlay/index.js +9 -0
- package/dist/components/Overlay/index.js.map +1 -0
- package/dist/components/PaymentWidget/PaymentGate.d.ts +30 -0
- package/dist/components/PaymentWidget/PaymentGate.d.ts.map +1 -0
- package/dist/components/PaymentWidget/PaymentGate.js +54 -0
- package/dist/components/PaymentWidget/PaymentGate.js.map +1 -0
- package/dist/components/PaymentWidget/PaymentWidget.d.ts +31 -0
- package/dist/components/PaymentWidget/PaymentWidget.d.ts.map +1 -0
- package/dist/components/PaymentWidget/PaymentWidget.js +163 -0
- package/dist/components/PaymentWidget/PaymentWidget.js.map +1 -0
- package/dist/components/PaymentWidget/index.d.ts +30 -0
- package/dist/components/PaymentWidget/index.d.ts.map +1 -0
- package/dist/components/PaymentWidget/index.js +32 -0
- package/dist/components/PaymentWidget/index.js.map +1 -0
- package/dist/components/PaymentWidget/types.d.ts +200 -0
- package/dist/components/PaymentWidget/types.d.ts.map +1 -0
- package/dist/components/PaymentWidget/types.js +84 -0
- package/dist/components/PaymentWidget/types.js.map +1 -0
- package/dist/components/PaymentWidget/useVarityPayment.d.ts +20 -0
- package/dist/components/PaymentWidget/useVarityPayment.d.ts.map +1 -0
- package/dist/components/PaymentWidget/useVarityPayment.js +164 -0
- package/dist/components/PaymentWidget/useVarityPayment.js.map +1 -0
- package/dist/components/Payments/constants.d.ts +1 -1
- package/dist/components/Payments/constants.d.ts.map +1 -1
- package/dist/components/Payments/constants.js +1 -1
- package/dist/components/Payments/constants.js.map +1 -1
- package/dist/components/Privy/InitTimeoutScreen.d.ts.map +1 -1
- package/dist/components/Privy/InitTimeoutScreen.js +1 -1
- package/dist/components/Privy/InitTimeoutScreen.js.map +1 -1
- package/dist/components/Privy/InitializingScreen.d.ts +3 -3
- package/dist/components/Privy/InitializingScreen.d.ts.map +1 -1
- package/dist/components/Privy/InitializingScreen.js +6 -6
- package/dist/components/Privy/InitializingScreen.js.map +1 -1
- package/dist/components/index.d.ts +5 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +20 -4
- package/dist/components/index.js.map +1 -1
- package/dist/config/chains.d.ts +5 -5
- package/dist/config/chains.d.ts.map +1 -1
- package/dist/config/chains.js +8 -8
- package/dist/config/chains.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -11
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +54 -11
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useAnalytics.d.ts +1 -1
- package/dist/hooks/useAuth.d.ts +1 -1
- package/dist/hooks/useAuth.js +1 -1
- package/dist/hooks/useWalletAuth.js +1 -1
- package/dist/index.d.ts +23 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +179 -42
- package/dist/index.js.map +1 -1
- package/dist/modules/cache/index.d.ts +11 -1
- package/dist/modules/cache/index.d.ts.map +1 -1
- package/dist/modules/cache/index.js +12 -1
- package/dist/modules/cache/index.js.map +1 -1
- package/dist/providers/PrivyProvider.js +1 -1
- package/dist/providers/PrivyProvider.js.map +1 -1
- package/dist/providers/PrivyStack.d.ts +37 -51
- package/dist/providers/PrivyStack.d.ts.map +1 -1
- package/dist/providers/PrivyStack.js +47 -145
- package/dist/providers/PrivyStack.js.map +1 -1
- package/dist/providers/VarityDashboardProvider.d.ts +7 -10
- package/dist/providers/VarityDashboardProvider.d.ts.map +1 -1
- package/dist/providers/VarityDashboardProvider.js +12 -15
- package/dist/providers/VarityDashboardProvider.js.map +1 -1
- package/dist/wallets/SimpleSmartWallet.js +1 -1
- package/dist/wallets/SimpleSmartWallet.js.map +1 -1
- package/dist/wallets/SmartWalletProvider.js +2 -2
- package/dist/wallets/SmartWalletProvider.js.map +1 -1
- package/dist/wallets/config.d.ts +8 -8
- package/dist/wallets/config.js +10 -10
- package/dist/wallets/config.js.map +1 -1
- package/package.json +44 -39
- package/dist/modules/cache/CacheClient.d.ts +0 -48
- package/dist/modules/cache/CacheClient.d.ts.map +0 -1
- package/dist/modules/cache/CacheClient.js +0 -59
- package/dist/modules/cache/CacheClient.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -22,9 +22,9 @@ SOFTWARE.
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
Varity SDK -
|
|
25
|
+
Varity SDK - Open-Source App Platform
|
|
26
26
|
|
|
27
|
-
Build
|
|
27
|
+
Build, deploy, and monetize production apps — 70% cheaper than AWS.
|
|
28
28
|
|
|
29
29
|
For more information, visit https://varity.so
|
|
30
30
|
|
package/README.md
CHANGED
|
@@ -1,248 +1,241 @@
|
|
|
1
|
-
# @varity/ui-kit
|
|
1
|
+
# @varity-labs/ui-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@varity-labs/ui-kit)
|
|
4
|
+
[](https://github.com/varity-labs/varity-sdk/blob/main/LICENSE)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Production-ready React component library for building applications on Varity. 19 components, dashboard layouts, analytics widgets, authentication, and payments — everything you need to build a full SaaS app.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Install
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- ✅ **SmartWalletProvider** - Gasless transactions (ERC-4337) - FULLY IMPLEMENTED
|
|
13
|
-
- ✅ **WalletSyncProvider** - Seamless Privy ↔ thirdweb wallet sync
|
|
14
|
-
- ✅ **OnrampWidget** - Credit card to USDC conversion
|
|
15
|
-
- ✅ **All smart contracts deployed** - Revenue split, App Store, Paymaster, Wallet Factory
|
|
10
|
+
```bash
|
|
11
|
+
npm install @varity-labs/ui-kit @varity-labs/sdk @varity-labs/types
|
|
12
|
+
```
|
|
16
13
|
|
|
17
|
-
##
|
|
14
|
+
## Quick Start
|
|
18
15
|
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
```tsx
|
|
17
|
+
import { PrivyStack } from '@varity-labs/ui-kit'
|
|
18
|
+
|
|
19
|
+
function App() {
|
|
20
|
+
return (
|
|
21
|
+
<PrivyStack>
|
|
22
|
+
<YourApp />
|
|
23
|
+
</PrivyStack>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
That's it — authentication, theming, and providers are all configured automatically with zero setup.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
## Components
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
import { PrivyStack } from '@varity/ui-kit';
|
|
32
|
+
### Form (7)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
| Component | Description |
|
|
35
|
+
|-----------|-------------|
|
|
36
|
+
| `Button` | Primary, secondary, outline, ghost, danger variants |
|
|
37
|
+
| `Input` | Text input with labels and validation |
|
|
38
|
+
| `Textarea` | Multi-line text input |
|
|
39
|
+
| `Select` | Dropdown selector |
|
|
40
|
+
| `Toggle` | On/off switch |
|
|
41
|
+
| `Checkbox` | Multi-select checkbox |
|
|
42
|
+
| `RadioGroup` | Single-select radio buttons |
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
### Overlay (3)
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const client = createThirdwebClient({
|
|
47
|
-
clientId: process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID!
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
<PrivyStack>
|
|
51
|
-
<SmartWalletProvider
|
|
52
|
-
config={{
|
|
53
|
-
client,
|
|
54
|
-
chain: varityL3Testnet,
|
|
55
|
-
gasless: { enabled: true }
|
|
56
|
-
}}
|
|
57
|
-
>
|
|
58
|
-
<YourApp />
|
|
59
|
-
</SmartWalletProvider>
|
|
60
|
-
</PrivyStack>
|
|
61
|
-
```
|
|
46
|
+
| Component | Description |
|
|
47
|
+
|-----------|-------------|
|
|
48
|
+
| `Dialog` | Modal dialog with focus trap |
|
|
49
|
+
| `ConfirmDialog` | Confirmation modal with confirm/cancel |
|
|
50
|
+
| `DropdownMenu` | Context menu with keyboard navigation |
|
|
62
51
|
|
|
63
|
-
|
|
52
|
+
### Feedback (3)
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
thirdwebClientId={process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID}
|
|
71
|
-
>
|
|
72
|
-
<Dashboard />
|
|
73
|
-
</VarityDashboardProvider>
|
|
74
|
-
```
|
|
54
|
+
| Component | Description |
|
|
55
|
+
|-----------|-------------|
|
|
56
|
+
| `ToastProvider` + `useToast` | Notification toasts (success, error, info) |
|
|
57
|
+
| `Skeleton` | Loading skeleton placeholder |
|
|
58
|
+
| `ProgressBar` | Progress indicator |
|
|
75
59
|
|
|
76
|
-
|
|
60
|
+
### Display (3)
|
|
77
61
|
|
|
78
|
-
|
|
62
|
+
| Component | Description |
|
|
63
|
+
|-----------|-------------|
|
|
64
|
+
| `Badge` | Status badges (+ PriorityBadge, ProjectStatusBadge, TaskStatusBadge, RoleBadge) |
|
|
65
|
+
| `Avatar` + `AvatarGroup` | User avatars |
|
|
66
|
+
| `EmptyState` | Empty state placeholder with presets |
|
|
79
67
|
|
|
80
|
-
|
|
81
|
-
import { VarityClient } from '@varity/ui-kit'
|
|
82
|
-
|
|
83
|
-
// Initialize client
|
|
84
|
-
const client = new VarityClient({
|
|
85
|
-
apiEndpoint: 'https://api.varity.io', // or staging/development
|
|
86
|
-
apiKey: 'your-api-key'
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
// Deploy industry-specific dashboard
|
|
90
|
-
const deployment = await client.templates.deployTemplate({
|
|
91
|
-
industry: 'finance',
|
|
92
|
-
templateId: 'finance-basic',
|
|
93
|
-
customization: {
|
|
94
|
-
branding: {
|
|
95
|
-
companyName: 'Acme Finance',
|
|
96
|
-
primaryColor: '#1E40AF',
|
|
97
|
-
darkMode: true
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
storageLayer: 'layer3',
|
|
101
|
-
deploymentType: 'production'
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
// Use any module
|
|
105
|
-
const kpis = await client.analytics.getKPIs({ period: 'current_month' })
|
|
106
|
-
const aiResponse = await client.compute.query('Analyze my financial data')
|
|
107
|
-
```
|
|
68
|
+
### Navigation (2)
|
|
108
69
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
- **PrivyStack** - Auth (email/social/wallet) + thirdweb integration
|
|
115
|
-
- **SmartWalletProvider** - Gasless transactions (ERC-4337)
|
|
116
|
-
- **VarityDashboardProvider** - Full-featured dashboards (Wagmi + React Query)
|
|
117
|
-
- **WalletSyncProvider** - Seamless Privy ↔ thirdweb wallet sync
|
|
118
|
-
|
|
119
|
-
### 🎯 Template Deployment System
|
|
120
|
-
Deploy pre-configured industry-specific dashboards to Varity L3:
|
|
121
|
-
|
|
122
|
-
- **Finance** - Banking, compliance, transactions, risk management
|
|
123
|
-
- **Healthcare** - HIPAA compliance, patient data, medical operations
|
|
124
|
-
- **Retail** - E-commerce, inventory, supply chain
|
|
125
|
-
- **ISO Merchant** - Payment processing, PCI compliance
|
|
126
|
-
|
|
127
|
-
### 🔐 3-Layer Encrypted Storage Architecture
|
|
128
|
-
- **Layer 1** - Varity internal documentation (Varity admins only)
|
|
129
|
-
- **Layer 2** - Industry RAG knowledge base (shared across industry)
|
|
130
|
-
- **Layer 3** - Customer-specific data (private, customer-only access)
|
|
131
|
-
- **ALL layers encrypted with Lit Protocol**
|
|
132
|
-
|
|
133
|
-
### 🔌 13 Module Clients
|
|
134
|
-
All operations via secure REST API:
|
|
135
|
-
|
|
136
|
-
- **auth** - SIWE authentication
|
|
137
|
-
- **storage** - Filecoin/IPFS file storage
|
|
138
|
-
- **compute** - AI/LLM on Akash Network
|
|
139
|
-
- **zk** - Zero-knowledge ML proofs
|
|
140
|
-
- **analytics** - Business analytics
|
|
141
|
-
- **notifications** - Email/SMS/push notifications
|
|
142
|
-
- **export** - CSV/JSON/PDF data export
|
|
143
|
-
- **cache** - Redis caching
|
|
144
|
-
- **monitoring** - System health & metrics
|
|
145
|
-
- **forecasting** - Predictive analytics
|
|
146
|
-
- **webhooks** - Webhook management
|
|
147
|
-
- **oracle** - Oracle data feeds
|
|
148
|
-
- **templates** - Industry dashboard deployment (NEW)
|
|
149
|
-
|
|
150
|
-
### 🎨 React Industry Templates
|
|
151
|
-
- `<FinanceDashboard />` - Financial services dashboard
|
|
152
|
-
- `<HealthcareDashboard />` - Healthcare operations dashboard
|
|
153
|
-
- `<RetailDashboard />` - Retail & e-commerce dashboard
|
|
154
|
-
- `<ISODashboard />` - ISO merchant services dashboard
|
|
155
|
-
|
|
156
|
-
## API Reference
|
|
157
|
-
|
|
158
|
-
### Authentication
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
// Login with SIWE
|
|
162
|
-
const { token } = await client.auth.login(message, signature)
|
|
163
|
-
|
|
164
|
-
// Get user profile
|
|
165
|
-
const user = await client.auth.me()
|
|
166
|
-
```
|
|
70
|
+
| Component | Description |
|
|
71
|
+
|-----------|-------------|
|
|
72
|
+
| `CommandPalette` | Cmd+K command search and navigation |
|
|
73
|
+
| `Breadcrumb` | Navigation breadcrumbs |
|
|
167
74
|
|
|
168
|
-
###
|
|
75
|
+
### Dashboard Layout (4)
|
|
169
76
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
77
|
+
| Component | Description |
|
|
78
|
+
|-----------|-------------|
|
|
79
|
+
| `DashboardLayout` | Full dashboard wrapper |
|
|
80
|
+
| `DashboardHeader` | Top navigation bar |
|
|
81
|
+
| `DashboardSidebar` | Side navigation |
|
|
82
|
+
| `DashboardFooter` | Footer |
|
|
173
83
|
|
|
174
|
-
|
|
175
|
-
await client.storage.pinCID(cid)
|
|
176
|
-
```
|
|
84
|
+
### Analytics (6)
|
|
177
85
|
|
|
178
|
-
|
|
86
|
+
| Component | Description |
|
|
87
|
+
|-----------|-------------|
|
|
88
|
+
| `DataTable` | Sortable, filterable data table |
|
|
89
|
+
| `KPICard` / `EnhancedKPICard` | Key performance indicator cards |
|
|
90
|
+
| `AnalyticsCard` | Analytics data card |
|
|
91
|
+
| `ChartContainer` | Chart wrapper with actions |
|
|
92
|
+
| `MetricDisplay` | Metric value display |
|
|
93
|
+
| `Sparkline` | Mini inline chart |
|
|
179
94
|
|
|
180
|
-
|
|
181
|
-
// Simple query
|
|
182
|
-
const response = await client.compute.query('What are the trends?')
|
|
95
|
+
### Branding (3)
|
|
183
96
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
```
|
|
97
|
+
| Component | Description |
|
|
98
|
+
|-----------|-------------|
|
|
99
|
+
| `ThemeProvider` + `useTheme` | Theme management with presets |
|
|
100
|
+
| `Logo` | Varity logo |
|
|
101
|
+
| `Attribution` | "Powered by Varity" attribution |
|
|
190
102
|
|
|
191
|
-
|
|
103
|
+
## Authentication
|
|
192
104
|
|
|
193
|
-
|
|
194
|
-
// Get KPIs
|
|
195
|
-
const kpis = await client.analytics.getKPIs({
|
|
196
|
-
period: 'current_month'
|
|
197
|
-
})
|
|
105
|
+
Built-in authentication via Privy — email, Google, and wallet login with zero configuration:
|
|
198
106
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
107
|
+
```tsx
|
|
108
|
+
import { PrivyStack } from '@varity-labs/ui-kit'
|
|
109
|
+
import { usePrivy } from '@privy-io/react-auth'
|
|
110
|
+
|
|
111
|
+
function App() {
|
|
112
|
+
return (
|
|
113
|
+
<PrivyStack>
|
|
114
|
+
<Dashboard />
|
|
115
|
+
</PrivyStack>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function Dashboard() {
|
|
120
|
+
const { login, logout, authenticated, user } = usePrivy()
|
|
121
|
+
|
|
122
|
+
if (!authenticated) {
|
|
123
|
+
return <button onClick={login}>Sign In</button>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<div>
|
|
128
|
+
<p>Welcome, {user?.email?.address}</p>
|
|
129
|
+
<button onClick={logout}>Sign Out</button>
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
204
133
|
```
|
|
205
134
|
|
|
206
|
-
|
|
135
|
+
### Auth Components
|
|
207
136
|
|
|
208
|
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
137
|
+
- `PrivyLoginButton` — Drop-in login button
|
|
138
|
+
- `PrivyUserProfile` — User profile display
|
|
139
|
+
- `PrivyProtectedRoute` — Route protection wrapper
|
|
140
|
+
- `PrivyReadyGate` — Loading gate during initialization
|
|
141
|
+
- Re-exports: `usePrivy`, `useWallets`, `useLogin`, `useLogout`
|
|
212
142
|
|
|
213
|
-
|
|
214
|
-
- **[Privy Integration](./docs/PRIVY_INTEGRATION.md)** - Email/social/wallet authentication
|
|
215
|
-
- **[thirdweb Quickstart](./docs/THIRDWEB_QUICKSTART.md)** - Blockchain operations
|
|
216
|
-
- **[Installation Guide](./docs/INSTALLATION_GUIDE.md)** - Setup and configuration
|
|
143
|
+
## Payments
|
|
217
144
|
|
|
218
|
-
|
|
219
|
-
- **[API Reference](./docs/API_REFERENCE.md)** - Complete API documentation
|
|
220
|
-
- **[Web3 Components](./docs/WEB3_COMPONENTS_REPORT.md)** - Wallet, balance, address components
|
|
145
|
+
Built-in payment components for app monetization (90% to developer, 10% platform fee):
|
|
221
146
|
|
|
222
|
-
|
|
147
|
+
```tsx
|
|
148
|
+
import { PaymentWidget, PaymentGate } from '@varity-labs/ui-kit'
|
|
223
149
|
|
|
224
|
-
|
|
150
|
+
// One-time payment button
|
|
151
|
+
<PaymentWidget appId="your-app" price={4.99} />
|
|
225
152
|
|
|
226
|
-
|
|
227
|
-
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
- ❌ NO encryption keys
|
|
232
|
-
- ❌ NO business logic
|
|
153
|
+
// Paywall — hides content until payment
|
|
154
|
+
<PaymentGate appId="your-app" price={9.99}>
|
|
155
|
+
<PremiumContent />
|
|
156
|
+
</PaymentGate>
|
|
157
|
+
```
|
|
233
158
|
|
|
234
|
-
|
|
159
|
+
## Theming
|
|
235
160
|
|
|
236
|
-
|
|
161
|
+
```tsx
|
|
162
|
+
import { ThemeProvider, useTheme } from '@varity-labs/ui-kit'
|
|
163
|
+
|
|
164
|
+
function App() {
|
|
165
|
+
return (
|
|
166
|
+
<ThemeProvider defaultTheme="dark">
|
|
167
|
+
<YourApp />
|
|
168
|
+
</ThemeProvider>
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function ThemeToggle() {
|
|
173
|
+
const { theme, setTheme } = useTheme()
|
|
174
|
+
return (
|
|
175
|
+
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
|
|
176
|
+
Toggle Theme
|
|
177
|
+
</button>
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Full Dashboard Example
|
|
237
183
|
|
|
238
|
-
|
|
184
|
+
```tsx
|
|
185
|
+
import {
|
|
186
|
+
PrivyStack,
|
|
187
|
+
DashboardLayout,
|
|
188
|
+
DashboardHeader,
|
|
189
|
+
DashboardSidebar,
|
|
190
|
+
KPICard,
|
|
191
|
+
DataTable,
|
|
192
|
+
CommandPalette,
|
|
193
|
+
ToastProvider,
|
|
194
|
+
useToast,
|
|
195
|
+
} from '@varity-labs/ui-kit'
|
|
196
|
+
|
|
197
|
+
function App() {
|
|
198
|
+
return (
|
|
199
|
+
<PrivyStack>
|
|
200
|
+
<ToastProvider>
|
|
201
|
+
<DashboardLayout>
|
|
202
|
+
<DashboardSidebar items={sidebarItems} />
|
|
203
|
+
<DashboardHeader title="My Dashboard" />
|
|
204
|
+
<CommandPalette commands={commands} onNavigate={(path) => router.push(path)} />
|
|
205
|
+
<main>
|
|
206
|
+
<KPICard title="Revenue" value="$12,345" trend={8.2} />
|
|
207
|
+
<DataTable columns={columns} data={data} />
|
|
208
|
+
</main>
|
|
209
|
+
</DashboardLayout>
|
|
210
|
+
</ToastProvider>
|
|
211
|
+
</PrivyStack>
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
```
|
|
239
215
|
|
|
240
|
-
##
|
|
216
|
+
## Compatibility
|
|
241
217
|
|
|
242
|
-
-
|
|
243
|
-
-
|
|
244
|
-
-
|
|
218
|
+
- **React** 18+
|
|
219
|
+
- **Next.js** 13+ (App Router compatible)
|
|
220
|
+
- **Static export** safe (`output: 'export'`)
|
|
221
|
+
- All components have `'use client'` directives
|
|
222
|
+
- WCAG 2.1 Level A accessibility
|
|
245
223
|
|
|
246
224
|
---
|
|
247
225
|
|
|
248
|
-
|
|
226
|
+
## Related Packages
|
|
227
|
+
|
|
228
|
+
- **[@varity-labs/sdk](../../core/varity-sdk/)** — Core SDK (database, credentials)
|
|
229
|
+
- **[@varity-labs/types](../../core/varity-types/)** — Shared TypeScript types
|
|
230
|
+
- **[@varity-labs/mcp](../../cli/varity-mcp/)** — MCP server for AI editors (Cursor, Claude Code, VS Code)
|
|
231
|
+
- **[create-varity-app](../../cli/create-varity-app/)** — Project scaffolding
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
**Part of the [Varity SDK](https://github.com/varity-labs/varity-sdk)** — Build, deploy, and monetize apps 70% cheaper than AWS.
|
|
236
|
+
|
|
237
|
+
[Documentation](https://docs.varity.so) · [GitHub](https://github.com/varity-labs/varity-sdk) · [Discord](https://discord.gg/varity)
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT
|
|
@@ -99,7 +99,7 @@ export const DataTable = ({ columns, data, loading = false, pagination = false,
|
|
|
99
99
|
padding: '40px',
|
|
100
100
|
textAlign: 'center',
|
|
101
101
|
color: 'var(--varity-text-secondary, #757575)'
|
|
102
|
-
} }, emptyMessage))) : (paginatedData.map((row, rowIndex) => (React.createElement("tr", { key: rowIndex
|
|
102
|
+
} }, emptyMessage))) : (paginatedData.map((row, rowIndex) => (React.createElement("tr", { key: row.id || `row-${rowIndex}`, style: {
|
|
103
103
|
borderBottom: '1px solid var(--varity-border-color, #e0e0e0)',
|
|
104
104
|
backgroundColor: striped && rowIndex % 2 === 1 ? 'var(--varity-bg-secondary, #f9f9f9)' : 'transparent',
|
|
105
105
|
cursor: onRowClick ? 'pointer' : 'default',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/components/Analytics/DataTable.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/components/Analytics/DataTable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface EnhancedKPICardProps {
|
|
3
|
+
title: string;
|
|
4
|
+
value: string | number;
|
|
5
|
+
change?: {
|
|
6
|
+
value: number;
|
|
7
|
+
period: string;
|
|
8
|
+
};
|
|
9
|
+
icon: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
trend?: 'up' | 'down' | 'neutral';
|
|
12
|
+
color?: 'blue' | 'green' | 'orange' | 'purple' | 'red';
|
|
13
|
+
sparklineData?: number[];
|
|
14
|
+
showSparkline?: boolean;
|
|
15
|
+
lastSynced?: string;
|
|
16
|
+
helpText?: string;
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function EnhancedKPICard({ title, value, change, icon, source, trend, color, sparklineData, showSparkline, lastSynced, helpText, onClick, }: EnhancedKPICardProps): React.JSX.Element;
|
|
20
|
+
export default EnhancedKPICard;
|
|
21
|
+
//# sourceMappingURL=EnhancedKPICard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnhancedKPICard.d.ts","sourceRoot":"","sources":["../../../src/components/Analytics/EnhancedKPICard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,MAAM,EACN,IAAI,EACJ,MAAM,EACN,KAAiB,EACjB,KAAc,EACd,aAAa,EACb,aAAqB,EACrB,UAAU,EACV,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB,qBAqLtB;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React, { useMemo } from 'react';
|
|
3
|
+
import { HelpCircle, Clock, TrendingUp, TrendingDown, Minus } from 'lucide-react';
|
|
4
|
+
import { Sparkline, getSparklineColors } from './Sparkline';
|
|
5
|
+
export function EnhancedKPICard({ title, value, change, icon, source, trend = 'neutral', color = 'blue', sparklineData, showSparkline = false, lastSynced, helpText, onClick, }) {
|
|
6
|
+
const colorClasses = {
|
|
7
|
+
blue: {
|
|
8
|
+
bg: 'bg-blue-50 dark:bg-blue-950',
|
|
9
|
+
icon: 'text-blue-600 dark:text-blue-400',
|
|
10
|
+
border: 'border-blue-100 dark:border-blue-800',
|
|
11
|
+
accent: 'text-blue-600 dark:text-blue-400',
|
|
12
|
+
},
|
|
13
|
+
green: {
|
|
14
|
+
bg: 'bg-green-50 dark:bg-green-950',
|
|
15
|
+
icon: 'text-green-600 dark:text-green-400',
|
|
16
|
+
border: 'border-green-100 dark:border-green-800',
|
|
17
|
+
accent: 'text-green-600 dark:text-green-400',
|
|
18
|
+
},
|
|
19
|
+
orange: {
|
|
20
|
+
bg: 'bg-orange-50 dark:bg-orange-950',
|
|
21
|
+
icon: 'text-orange-600 dark:text-orange-400',
|
|
22
|
+
border: 'border-orange-100 dark:border-orange-800',
|
|
23
|
+
accent: 'text-orange-600 dark:text-orange-400',
|
|
24
|
+
},
|
|
25
|
+
purple: {
|
|
26
|
+
bg: 'bg-purple-50 dark:bg-purple-950',
|
|
27
|
+
icon: 'text-purple-600 dark:text-purple-400',
|
|
28
|
+
border: 'border-purple-100 dark:border-purple-800',
|
|
29
|
+
accent: 'text-purple-600 dark:text-purple-400',
|
|
30
|
+
},
|
|
31
|
+
red: {
|
|
32
|
+
bg: 'bg-red-50 dark:bg-red-950',
|
|
33
|
+
icon: 'text-red-600 dark:text-red-400',
|
|
34
|
+
border: 'border-red-100 dark:border-red-800',
|
|
35
|
+
accent: 'text-red-600 dark:text-red-400',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const trendConfig = {
|
|
39
|
+
up: {
|
|
40
|
+
color: 'text-emerald-600 dark:text-emerald-400',
|
|
41
|
+
bgColor: 'bg-emerald-50 dark:bg-emerald-950',
|
|
42
|
+
icon: TrendingUp,
|
|
43
|
+
label: 'Up',
|
|
44
|
+
},
|
|
45
|
+
down: {
|
|
46
|
+
color: 'text-red-600 dark:text-red-400',
|
|
47
|
+
bgColor: 'bg-red-50 dark:bg-red-950',
|
|
48
|
+
icon: TrendingDown,
|
|
49
|
+
label: 'Down',
|
|
50
|
+
},
|
|
51
|
+
neutral: {
|
|
52
|
+
color: 'text-gray-600 dark:text-gray-400',
|
|
53
|
+
bgColor: 'bg-gray-50 dark:bg-gray-800',
|
|
54
|
+
icon: Minus,
|
|
55
|
+
label: 'No change',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const TrendIcon = trendConfig[trend].icon;
|
|
59
|
+
const sparklineColors = getSparklineColors(trend, color);
|
|
60
|
+
// Format last synced time
|
|
61
|
+
const formattedLastSynced = useMemo(() => {
|
|
62
|
+
if (!lastSynced)
|
|
63
|
+
return null;
|
|
64
|
+
// If it's already a relative string (e.g., "2 min ago"), return as-is
|
|
65
|
+
if (lastSynced.includes('ago') || lastSynced.includes('Just now')) {
|
|
66
|
+
return lastSynced;
|
|
67
|
+
}
|
|
68
|
+
// Otherwise, try to parse as ISO date
|
|
69
|
+
try {
|
|
70
|
+
const syncDate = new Date(lastSynced);
|
|
71
|
+
const now = new Date();
|
|
72
|
+
const diffMs = now.getTime() - syncDate.getTime();
|
|
73
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
74
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
75
|
+
if (diffMins < 1)
|
|
76
|
+
return 'Just now';
|
|
77
|
+
if (diffMins < 60)
|
|
78
|
+
return `${diffMins}m ago`;
|
|
79
|
+
if (diffHours < 24)
|
|
80
|
+
return `${diffHours}h ago`;
|
|
81
|
+
return `${Math.floor(diffHours / 24)}d ago`;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return lastSynced;
|
|
85
|
+
}
|
|
86
|
+
}, [lastSynced]);
|
|
87
|
+
// Generate mock sparkline data if none provided
|
|
88
|
+
const displaySparklineData = useMemo(() => {
|
|
89
|
+
if (sparklineData && sparklineData.length >= 2)
|
|
90
|
+
return sparklineData;
|
|
91
|
+
// Generate plausible trend data based on current value and change
|
|
92
|
+
const baseValue = typeof value === 'number' ? value : parseFloat(value.replace(/[^0-9.-]/g, '')) || 100;
|
|
93
|
+
const changePercent = change?.value || 0;
|
|
94
|
+
const points = 7;
|
|
95
|
+
const data = [];
|
|
96
|
+
for (let i = 0; i < points; i++) {
|
|
97
|
+
const progress = i / (points - 1);
|
|
98
|
+
const trendValue = baseValue * (1 - changePercent / 100 * (1 - progress));
|
|
99
|
+
const noise = trendValue * 0.02 * (Math.random() - 0.5);
|
|
100
|
+
data.push(Math.max(0, trendValue + noise));
|
|
101
|
+
}
|
|
102
|
+
return data;
|
|
103
|
+
}, [sparklineData, value, change]);
|
|
104
|
+
return (React.createElement("div", { onClick: onClick, className: `bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-5 hover:shadow-lg hover:border-blue-300 dark:hover:border-blue-600 hover:-translate-y-0.5 transition-all duration-200 ${onClick ? 'cursor-pointer' : ''}`, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => e.key === 'Enter' && onClick() : undefined },
|
|
105
|
+
React.createElement("div", { className: "flex items-start justify-between mb-3" },
|
|
106
|
+
React.createElement("div", { className: "flex items-center gap-2" },
|
|
107
|
+
React.createElement("div", { className: `w-10 h-10 ${colorClasses[color].bg} rounded-lg flex items-center justify-center text-xl` }, icon),
|
|
108
|
+
React.createElement("div", null,
|
|
109
|
+
React.createElement("div", { className: "flex items-center gap-1" },
|
|
110
|
+
React.createElement("h3", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, title),
|
|
111
|
+
helpText && (React.createElement("div", { className: "relative group" },
|
|
112
|
+
React.createElement(HelpCircle, { className: "w-3.5 h-3.5 text-gray-400 dark:text-gray-500 cursor-help" }),
|
|
113
|
+
React.createElement("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded whitespace-nowrap opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-10" },
|
|
114
|
+
helpText,
|
|
115
|
+
React.createElement("div", { className: "absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-100" }))))),
|
|
116
|
+
source && (React.createElement("span", { className: "text-[10px] text-gray-400 dark:text-gray-500 uppercase tracking-wide" }, source))))),
|
|
117
|
+
React.createElement("div", { className: "mb-3" },
|
|
118
|
+
React.createElement("p", { className: "text-3xl font-bold text-gray-900 dark:text-white tracking-tight" }, value)),
|
|
119
|
+
change && (React.createElement("div", { className: "flex items-center gap-2 mb-3" },
|
|
120
|
+
React.createElement("span", { className: `inline-flex items-center gap-1 text-xs font-semibold px-2 py-1 rounded ${trendConfig[trend].bgColor} ${trendConfig[trend].color}` },
|
|
121
|
+
React.createElement(TrendIcon, { className: "w-3.5 h-3.5" }),
|
|
122
|
+
React.createElement("span", null,
|
|
123
|
+
Math.abs(change.value).toFixed(1),
|
|
124
|
+
"%")),
|
|
125
|
+
React.createElement("span", { className: "text-xs text-gray-500 dark:text-gray-400" }, change.period))),
|
|
126
|
+
showSparkline && (React.createElement("div", { className: "mb-3" },
|
|
127
|
+
React.createElement(Sparkline, { data: displaySparklineData, width: 180, height: 36, strokeColor: sparklineColors.stroke, fillColor: sparklineColors.fill, strokeWidth: 2, showGradient: true, className: "w-full" }))),
|
|
128
|
+
formattedLastSynced && (React.createElement("div", { className: "flex items-center gap-1 text-[10px] text-gray-400 dark:text-gray-500 pt-2 border-t border-gray-100 dark:border-gray-700" },
|
|
129
|
+
React.createElement(Clock, { className: "w-3 h-3" }),
|
|
130
|
+
React.createElement("span", null,
|
|
131
|
+
"Synced ",
|
|
132
|
+
formattedLastSynced)))));
|
|
133
|
+
}
|
|
134
|
+
export default EnhancedKPICard;
|
|
135
|
+
//# sourceMappingURL=EnhancedKPICard.js.map
|