@rovela-ai/sdk 0.1.19 → 0.1.21
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/admin/components/AdminNav.d.ts +10 -3
- package/dist/admin/components/AdminNav.d.ts.map +1 -1
- package/dist/admin/components/AdminNav.js +80 -28
- package/dist/admin/components/AdminNav.js.map +1 -1
- package/dist/admin/components/CategoryForm.d.ts +30 -0
- package/dist/admin/components/CategoryForm.d.ts.map +1 -0
- package/dist/admin/components/CategoryForm.js +153 -0
- package/dist/admin/components/CategoryForm.js.map +1 -0
- package/dist/admin/components/CategorySelect.d.ts +32 -0
- package/dist/admin/components/CategorySelect.d.ts.map +1 -0
- package/dist/admin/components/CategorySelect.js +148 -0
- package/dist/admin/components/CategorySelect.js.map +1 -0
- package/dist/admin/components/LowStockAlert.d.ts +2 -2
- package/dist/admin/components/LowStockAlert.d.ts.map +1 -1
- package/dist/admin/components/LowStockAlert.js +16 -9
- package/dist/admin/components/LowStockAlert.js.map +1 -1
- package/dist/admin/components/OrderStatusChart.d.ts +21 -0
- package/dist/admin/components/OrderStatusChart.d.ts.map +1 -0
- package/dist/admin/components/OrderStatusChart.js +54 -0
- package/dist/admin/components/OrderStatusChart.js.map +1 -0
- package/dist/admin/components/ProductForm.d.ts +2 -2
- package/dist/admin/components/ProductForm.d.ts.map +1 -1
- package/dist/admin/components/ProductForm.js +125 -9
- package/dist/admin/components/ProductForm.js.map +1 -1
- package/dist/admin/components/RecentOrders.d.ts +1 -1
- package/dist/admin/components/RecentOrders.d.ts.map +1 -1
- package/dist/admin/components/RecentOrders.js +11 -10
- package/dist/admin/components/RecentOrders.js.map +1 -1
- package/dist/admin/components/RevenueChart.d.ts +23 -0
- package/dist/admin/components/RevenueChart.d.ts.map +1 -0
- package/dist/admin/components/RevenueChart.js +70 -0
- package/dist/admin/components/RevenueChart.js.map +1 -0
- package/dist/admin/components/SEOPreview.d.ts +32 -0
- package/dist/admin/components/SEOPreview.d.ts.map +1 -0
- package/dist/admin/components/SEOPreview.js +30 -0
- package/dist/admin/components/SEOPreview.js.map +1 -0
- package/dist/admin/components/StatsCards.d.ts +2 -2
- package/dist/admin/components/StatsCards.d.ts.map +1 -1
- package/dist/admin/components/StatsCards.js +18 -20
- package/dist/admin/components/StatsCards.js.map +1 -1
- package/dist/admin/components/TagInput.d.ts +29 -0
- package/dist/admin/components/TagInput.d.ts.map +1 -0
- package/dist/admin/components/TagInput.js +73 -0
- package/dist/admin/components/TagInput.js.map +1 -0
- package/dist/admin/components/VariantManager.d.ts +42 -0
- package/dist/admin/components/VariantManager.d.ts.map +1 -0
- package/dist/admin/components/VariantManager.js +175 -0
- package/dist/admin/components/VariantManager.js.map +1 -0
- package/dist/admin/components/index.d.ts +9 -0
- package/dist/admin/components/index.d.ts.map +1 -1
- package/dist/admin/components/index.js +13 -0
- package/dist/admin/components/index.js.map +1 -1
- package/dist/admin/hooks/index.d.ts +2 -0
- package/dist/admin/hooks/index.d.ts.map +1 -1
- package/dist/admin/hooks/index.js +1 -0
- package/dist/admin/hooks/index.js.map +1 -1
- package/dist/admin/hooks/useAdminCategories.d.ts +36 -0
- package/dist/admin/hooks/useAdminCategories.d.ts.map +1 -0
- package/dist/admin/hooks/useAdminCategories.js +217 -0
- package/dist/admin/hooks/useAdminCategories.js.map +1 -0
- package/dist/admin/index.d.ts +4 -3
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +6 -2
- package/dist/admin/index.js.map +1 -1
- package/dist/core/StoreSettingsProvider.d.ts +104 -0
- package/dist/core/StoreSettingsProvider.d.ts.map +1 -0
- package/dist/core/StoreSettingsProvider.js +195 -0
- package/dist/core/StoreSettingsProvider.js.map +1 -0
- package/dist/core/api/index.d.ts +7 -0
- package/dist/core/api/index.d.ts.map +1 -0
- package/dist/core/api/index.js +7 -0
- package/dist/core/api/index.js.map +1 -0
- package/dist/core/api/settings.d.ts +42 -0
- package/dist/core/api/settings.d.ts.map +1 -0
- package/dist/core/api/settings.js +74 -0
- package/dist/core/api/settings.js.map +1 -0
- package/dist/core/db/queries.d.ts +6 -6
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @rovela/sdk/admin/components/CategorySelect
|
|
5
|
+
*
|
|
6
|
+
* Category dropdown selector with tree structure and search.
|
|
7
|
+
*/
|
|
8
|
+
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
9
|
+
import { ChevronDown, X, FolderOpen, Plus, Search } from 'lucide-react';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Component
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Category selector with hierarchical dropdown.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <CategorySelect
|
|
19
|
+
* value={categoryId}
|
|
20
|
+
* onChange={setCategoryId}
|
|
21
|
+
* placeholder="Select a category"
|
|
22
|
+
* showAddNew
|
|
23
|
+
* onAddNew={() => setShowCategoryModal(true)}
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function CategorySelect({ value, onChange, placeholder = 'Select category', showAddNew = false, onAddNew, disabled = false, className = '', }) {
|
|
28
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
29
|
+
const [search, setSearch] = useState('');
|
|
30
|
+
const [categories, setCategories] = useState([]);
|
|
31
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
32
|
+
const containerRef = useRef(null);
|
|
33
|
+
const searchInputRef = useRef(null);
|
|
34
|
+
// Fetch categories
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const fetchCategories = async () => {
|
|
37
|
+
setIsLoading(true);
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch('/api/admin/categories?flat=true');
|
|
40
|
+
if (response.ok) {
|
|
41
|
+
const data = await response.json();
|
|
42
|
+
setCategories(data.data || []);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('[CategorySelect] Failed to fetch categories:', error);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
setIsLoading(false);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
fetchCategories();
|
|
53
|
+
}, []);
|
|
54
|
+
// Build tree with levels
|
|
55
|
+
const buildTreeWithLevels = useCallback((items) => {
|
|
56
|
+
const map = new Map();
|
|
57
|
+
const roots = [];
|
|
58
|
+
// First pass: create nodes
|
|
59
|
+
for (const cat of items) {
|
|
60
|
+
map.set(cat.id, { ...cat, children: [], level: 0 });
|
|
61
|
+
}
|
|
62
|
+
// Second pass: build tree and assign levels
|
|
63
|
+
for (const cat of items) {
|
|
64
|
+
const node = map.get(cat.id);
|
|
65
|
+
if (cat.parentId && map.has(cat.parentId)) {
|
|
66
|
+
const parent = map.get(cat.parentId);
|
|
67
|
+
node.level = parent.level + 1;
|
|
68
|
+
parent.children.push(node);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
roots.push(node);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Sort by order
|
|
75
|
+
const sortByOrder = (a, b) => a.order - b.order;
|
|
76
|
+
roots.sort(sortByOrder);
|
|
77
|
+
for (const node of map.values()) {
|
|
78
|
+
node.children.sort(sortByOrder);
|
|
79
|
+
}
|
|
80
|
+
return roots;
|
|
81
|
+
}, []);
|
|
82
|
+
// Flatten tree for display
|
|
83
|
+
const flattenTree = useCallback((tree) => {
|
|
84
|
+
const result = [];
|
|
85
|
+
const traverse = (nodes) => {
|
|
86
|
+
for (const node of nodes) {
|
|
87
|
+
result.push(node);
|
|
88
|
+
traverse(node.children);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
traverse(tree);
|
|
92
|
+
return result;
|
|
93
|
+
}, []);
|
|
94
|
+
// Get flat list with levels
|
|
95
|
+
const flatListWithLevels = flattenTree(buildTreeWithLevels(categories));
|
|
96
|
+
// Filter by search
|
|
97
|
+
const filteredCategories = search
|
|
98
|
+
? flatListWithLevels.filter((cat) => cat.name.toLowerCase().includes(search.toLowerCase()))
|
|
99
|
+
: flatListWithLevels;
|
|
100
|
+
// Get selected category
|
|
101
|
+
const selectedCategory = categories.find((cat) => cat.id === value);
|
|
102
|
+
// Close on outside click
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const handleClickOutside = (event) => {
|
|
105
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
106
|
+
setIsOpen(false);
|
|
107
|
+
setSearch('');
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
111
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
112
|
+
}, []);
|
|
113
|
+
// Focus search input when opened
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (isOpen && searchInputRef.current) {
|
|
116
|
+
searchInputRef.current.focus();
|
|
117
|
+
}
|
|
118
|
+
}, [isOpen]);
|
|
119
|
+
// Handle keyboard navigation
|
|
120
|
+
const handleKeyDown = (e) => {
|
|
121
|
+
if (e.key === 'Escape') {
|
|
122
|
+
setIsOpen(false);
|
|
123
|
+
setSearch('');
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
return (_jsxs("div", { ref: containerRef, className: `relative ${className}`, onKeyDown: handleKeyDown, children: [_jsxs("button", { type: "button", onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, className: `
|
|
127
|
+
flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm
|
|
128
|
+
${disabled
|
|
129
|
+
? 'cursor-not-allowed border-input bg-muted text-muted-foreground'
|
|
130
|
+
: 'border-input bg-background text-foreground hover:border-primary focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'}
|
|
131
|
+
`, children: [_jsx("span", { className: selectedCategory ? 'text-foreground' : 'text-muted-foreground', children: isLoading ? ('Loading...') : selectedCategory ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx(FolderOpen, { className: "h-4 w-4 text-muted-foreground" }), selectedCategory.name] })) : (placeholder) }), _jsxs("div", { className: "flex items-center gap-1", children: [selectedCategory && !disabled && (_jsx("button", { type: "button", onClick: (e) => {
|
|
132
|
+
e.stopPropagation();
|
|
133
|
+
onChange(null);
|
|
134
|
+
}, className: "rounded p-0.5 hover:bg-accent", children: _jsx(X, { className: "h-3 w-3 text-muted-foreground" }) })), _jsx(ChevronDown, { className: `h-4 w-4 text-muted-foreground transition-transform ${isOpen ? 'rotate-180' : ''}` })] })] }), isOpen && (_jsxs("div", { className: "absolute z-50 mt-1 w-full rounded-md border border-border bg-popover shadow-lg", children: [_jsx("div", { className: "border-b border-border p-2", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { ref: searchInputRef, type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Search categories...", className: "w-full rounded-md border border-input bg-background py-1.5 pl-8 pr-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary" })] }) }), _jsx("div", { className: "max-h-60 overflow-auto p-1", children: filteredCategories.length === 0 ? (_jsx("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: search ? 'No categories found' : 'No categories yet' })) : (filteredCategories.map((category) => (_jsxs("button", { type: "button", onClick: () => {
|
|
135
|
+
onChange(category.id);
|
|
136
|
+
setIsOpen(false);
|
|
137
|
+
setSearch('');
|
|
138
|
+
}, className: `
|
|
139
|
+
flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm
|
|
140
|
+
${category.id === value
|
|
141
|
+
? 'bg-primary/10 text-primary'
|
|
142
|
+
: 'text-foreground hover:bg-accent'}
|
|
143
|
+
`, style: { paddingLeft: `${12 + category.level * 16}px` }, children: [_jsx(FolderOpen, { className: "h-4 w-4 text-muted-foreground" }), category.name] }, category.id)))) }), showAddNew && onAddNew && (_jsx("div", { className: "border-t border-border p-1", children: _jsxs("button", { type: "button", onClick: () => {
|
|
144
|
+
onAddNew();
|
|
145
|
+
setIsOpen(false);
|
|
146
|
+
}, className: "flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm text-primary hover:bg-accent", children: [_jsx(Plus, { className: "h-4 w-4" }), "Add new category"] }) }))] }))] }));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=CategorySelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategorySelect.js","sourceRoot":"","sources":["../../../src/admin/components/CategorySelect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { LowStockAlertProps } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
* Low stock alert widget for dashboard.
|
|
3
|
+
* Low stock alert widget for dashboard with success state.
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```tsx
|
|
7
7
|
* <LowStockAlert threshold={10} viewAllHref="/admin/products?filter=low-stock" />
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
export declare function LowStockAlert({ threshold, viewAllHref, className, }: LowStockAlertProps): import("react/jsx-runtime").JSX.Element
|
|
10
|
+
export declare function LowStockAlert({ threshold, viewAllHref, className, }: LowStockAlertProps): import("react/jsx-runtime").JSX.Element;
|
|
11
11
|
//# sourceMappingURL=LowStockAlert.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LowStockAlert.d.ts","sourceRoot":"","sources":["../../../src/admin/components/LowStockAlert.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"LowStockAlert.d.ts","sourceRoot":"","sources":["../../../src/admin/components/LowStockAlert.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AA0BlD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAc,EACd,WAA+B,EAC/B,SAAc,GACf,EAAE,kBAAkB,2CAoHpB"}
|
|
@@ -3,14 +3,23 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* @rovela/sdk/admin/components/LowStockAlert
|
|
5
5
|
*
|
|
6
|
-
* Low stock inventory warning widget.
|
|
6
|
+
* Low stock inventory warning widget with theme-aware styling.
|
|
7
7
|
*/
|
|
8
8
|
import { useAdminStats } from '../hooks/useAdminStats';
|
|
9
9
|
// =============================================================================
|
|
10
|
+
// Icons
|
|
11
|
+
// =============================================================================
|
|
12
|
+
function AlertIcon({ className = 'h-5 w-5' }) {
|
|
13
|
+
return (_jsx("svg", { className: className, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }) }));
|
|
14
|
+
}
|
|
15
|
+
function CheckIcon({ className = 'h-5 w-5' }) {
|
|
16
|
+
return (_jsx("svg", { className: className, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }));
|
|
17
|
+
}
|
|
18
|
+
// =============================================================================
|
|
10
19
|
// Component
|
|
11
20
|
// =============================================================================
|
|
12
21
|
/**
|
|
13
|
-
* Low stock alert widget for dashboard.
|
|
22
|
+
* Low stock alert widget for dashboard with success state.
|
|
14
23
|
*
|
|
15
24
|
* @example
|
|
16
25
|
* ```tsx
|
|
@@ -21,12 +30,10 @@ export function LowStockAlert({ threshold = 10, viewAllHref = '/admin/products',
|
|
|
21
30
|
const { lowStock, isLoading } = useAdminStats({
|
|
22
31
|
lowStockThreshold: threshold,
|
|
23
32
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
? 'bg-red-100 text-red-800'
|
|
30
|
-
: 'bg-amber-100 text-amber-800'}`, children: item.inventory === 0 ? 'Out of stock' : `${item.inventory} left` }) })] }, item.variantId)))) }), !isLoading && lowStock.length > 5 && (_jsx("div", { className: "border-t border-border px-6 py-3 text-center", children: _jsxs("a", { href: viewAllHref, className: "text-sm text-primary hover:underline", children: ["+", lowStock.length - 5, " more items"] }) }))] }));
|
|
33
|
+
return (_jsxs("div", { className: `rounded-xl border border-border bg-card ${className}`, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-6 py-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [!isLoading && lowStock.length === 0 ? (_jsx("div", { className: "rounded-full bg-emerald-500/10 p-2", children: _jsx(CheckIcon, { className: "h-5 w-5 text-emerald-600 dark:text-emerald-400" }) })) : (_jsx("div", { className: "rounded-full bg-amber-500/10 p-2", children: _jsx(AlertIcon, { className: "h-5 w-5 text-amber-600 dark:text-amber-400" }) })), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold text-foreground", children: !isLoading && lowStock.length === 0 ? 'Inventory Healthy' : 'Low Stock Alert' }), _jsx("p", { className: "text-sm text-muted-foreground", children: !isLoading && lowStock.length === 0
|
|
34
|
+
? 'All products are well stocked'
|
|
35
|
+
: `${lowStock.length} item${lowStock.length !== 1 ? 's' : ''} need attention` })] })] }), lowStock.length > 0 && (_jsxs("a", { href: viewAllHref, className: "inline-flex items-center gap-1 text-sm font-medium text-primary transition-colors hover:text-primary/80", children: ["View all", _jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })] }))] }), _jsxs("div", { children: [isLoading ? (_jsx("div", { className: "p-6", children: _jsx("div", { className: "space-y-4", children: [...Array(3)].map((_, i) => (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-4 w-32 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-20 animate-pulse rounded bg-muted" })] }), _jsx("div", { className: "h-6 w-16 animate-pulse rounded bg-muted" })] }, i))) }) })) : lowStock.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [_jsx("div", { className: "rounded-full bg-emerald-500/10 p-4", children: _jsx(CheckIcon, { className: "h-8 w-8 text-emerald-600 dark:text-emerald-400" }) }), _jsx("p", { className: "mt-4 text-sm font-medium text-foreground", children: "All stocked up!" }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["No products below ", threshold, " units in stock"] })] })) : (_jsx("div", { className: "divide-y divide-border", children: lowStock.slice(0, 5).map((item) => (_jsxs("div", { className: "flex items-center justify-between px-6 py-4 transition-colors hover:bg-muted/50", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("a", { href: `/admin/products/${item.productId}`, className: "block truncate font-medium text-foreground transition-colors hover:text-primary", children: item.productName }), _jsx("p", { className: "truncate text-sm text-muted-foreground", children: item.variantName })] }), _jsx("div", { className: "ml-4 flex-shrink-0", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${item.inventory === 0
|
|
36
|
+
? 'bg-red-500/10 text-red-600 dark:text-red-400'
|
|
37
|
+
: 'bg-amber-500/10 text-amber-600 dark:text-amber-400'}`, children: item.inventory === 0 ? 'Out of stock' : `${item.inventory} left` }) })] }, item.variantId))) })), !isLoading && lowStock.length > 5 && (_jsx("div", { className: "border-t border-border px-6 py-3 text-center", children: _jsxs("a", { href: viewAllHref, className: "text-sm font-medium text-primary transition-colors hover:text-primary/80", children: ["+", lowStock.length - 5, " more items"] }) }))] })] }));
|
|
31
38
|
}
|
|
32
39
|
//# sourceMappingURL=LowStockAlert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LowStockAlert.js","sourceRoot":"","sources":["../../../src/admin/components/LowStockAlert.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAGtD,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,SAAS,GAAG,EAAE,EACd,WAAW,GAAG,iBAAiB,EAC/B,SAAS,GAAG,EAAE,GACK;IACnB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;QAC5C,iBAAiB,EAAE,SAAS;KAC7B,CAAC,CAAA;IAEF,
|
|
1
|
+
{"version":3,"file":"LowStockAlert.js","sourceRoot":"","sources":["../../../src/admin/components/LowStockAlert.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface OrderStatusChartProps {
|
|
2
|
+
/** Order counts by status */
|
|
3
|
+
data: {
|
|
4
|
+
status: string;
|
|
5
|
+
count: number;
|
|
6
|
+
}[];
|
|
7
|
+
/** Loading state */
|
|
8
|
+
isLoading?: boolean;
|
|
9
|
+
/** Custom className */
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Order status donut chart showing breakdown by status.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <OrderStatusChart data={ordersByStatus} isLoading={isLoading} />
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function OrderStatusChart({ data, isLoading, className, }: OrderStatusChartProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=OrderStatusChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderStatusChart.d.ts","sourceRoot":"","sources":["../../../src/admin/components/OrderStatusChart.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,oBAAoB;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAkDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,SAAiB,EACjB,SAAc,GACf,EAAE,qBAAqB,2CAqGvB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @rovela/sdk/admin/components/OrderStatusChart
|
|
5
|
+
*
|
|
6
|
+
* Order status breakdown donut chart for dashboard.
|
|
7
|
+
*/
|
|
8
|
+
import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from 'recharts';
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Status Configuration
|
|
11
|
+
// =============================================================================
|
|
12
|
+
const statusConfig = {
|
|
13
|
+
pending: { label: 'Pending', color: 'hsl(45 93% 47%)' }, // Amber
|
|
14
|
+
paid: { label: 'Paid', color: 'hsl(142 76% 36%)' }, // Green
|
|
15
|
+
shipped: { label: 'Shipped', color: 'hsl(217 91% 60%)' }, // Blue
|
|
16
|
+
delivered: { label: 'Delivered', color: 'hsl(142 71% 45%)' }, // Emerald
|
|
17
|
+
cancelled: { label: 'Cancelled', color: 'hsl(0 84% 60%)' }, // Red
|
|
18
|
+
refunded: { label: 'Refunded', color: 'hsl(220 9% 46%)' }, // Gray
|
|
19
|
+
};
|
|
20
|
+
function CustomTooltip({ active, payload }) {
|
|
21
|
+
if (!active || !payload || !payload.length)
|
|
22
|
+
return null;
|
|
23
|
+
const data = payload[0].payload;
|
|
24
|
+
const config = statusConfig[data.status] || { label: data.status, color: 'hsl(220 9% 46%)' };
|
|
25
|
+
return (_jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-2 shadow-lg", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "h-3 w-3 rounded-full", style: { backgroundColor: config.color } }), _jsx("span", { className: "text-sm font-medium text-foreground", children: config.label })] }), _jsxs("p", { className: "mt-1 text-lg font-semibold text-foreground", children: [data.count.toLocaleString(), " orders"] })] }));
|
|
26
|
+
}
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Component
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* Order status donut chart showing breakdown by status.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <OrderStatusChart data={ordersByStatus} isLoading={isLoading} />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function OrderStatusChart({ data, isLoading = false, className = '', }) {
|
|
39
|
+
// Process data with colors
|
|
40
|
+
const chartData = data.map((item) => ({
|
|
41
|
+
...item,
|
|
42
|
+
color: statusConfig[item.status]?.color || 'hsl(220 9% 46%)',
|
|
43
|
+
label: statusConfig[item.status]?.label || item.status,
|
|
44
|
+
}));
|
|
45
|
+
// Calculate total
|
|
46
|
+
const totalOrders = data.reduce((sum, item) => sum + item.count, 0);
|
|
47
|
+
return (_jsxs("div", { className: `rounded-xl border border-border bg-card ${className}`, children: [_jsxs("div", { className: "border-b border-border px-6 py-4", children: [_jsx("h3", { className: "text-lg font-semibold text-foreground", children: "Order Status" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Distribution by status" })] }), _jsx("div", { className: "p-6", children: isLoading ? (_jsx("div", { className: "flex h-64 items-center justify-center", children: _jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" }) })) : totalOrders === 0 ? (_jsxs("div", { className: "flex h-64 flex-col items-center justify-center text-center", children: [_jsx("svg", { className: "h-12 w-12 text-muted-foreground/30", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007zM8.625 10.5a.375.375 0 11-.75 0 .375.375 0 01.75 0zm7.5 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" }) }), _jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: "No orders yet" }), _jsx("p", { className: "text-xs text-muted-foreground/70", children: "Order breakdown will appear here" })] })) : (_jsxs("div", { className: "flex items-center gap-6", children: [_jsxs("div", { className: "relative flex-shrink-0", children: [_jsx(ResponsiveContainer, { width: 180, height: 180, children: _jsxs(PieChart, { children: [_jsx(Pie, { data: chartData, cx: "50%", cy: "50%", innerRadius: 55, outerRadius: 80, paddingAngle: 2, dataKey: "count", children: chartData.map((entry, index) => (_jsx(Cell, { fill: entry.color }, `cell-${index}`))) }), _jsx(Tooltip, { content: _jsx(CustomTooltip, {}) })] }) }), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [_jsx("p", { className: "text-2xl font-bold text-foreground", children: totalOrders }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Total" })] })] }), _jsx("div", { className: "flex-1 space-y-2", children: chartData.map((item) => {
|
|
48
|
+
const percentage = totalOrders > 0
|
|
49
|
+
? Math.round((item.count / totalOrders) * 100)
|
|
50
|
+
: 0;
|
|
51
|
+
return (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "h-3 w-3 rounded-full", style: { backgroundColor: item.color } }), _jsx("span", { className: "text-sm text-foreground", children: item.label })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: item.count }), _jsxs("span", { className: "text-xs text-muted-foreground", children: ["(", percentage, "%)"] })] })] }, item.status));
|
|
52
|
+
}) })] })) })] }));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=OrderStatusChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrderStatusChart.js","sourceRoot":"","sources":["../../../src/admin/components/OrderStatusChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ProductFormProps } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Enhanced product form for create and edit.
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```tsx
|
|
7
7
|
* // Create mode
|
|
8
|
-
* <ProductForm onSuccess={(
|
|
8
|
+
* <ProductForm onSuccess={() => router.push('/admin/products')} />
|
|
9
9
|
*
|
|
10
10
|
* // Edit mode
|
|
11
11
|
* <ProductForm
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductForm.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ProductForm.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductForm.d.ts","sourceRoot":"","sources":["../../../src/admin/components/ProductForm.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAoC,MAAM,UAAU,CAAA;AAkBlF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAc,GACf,EAAE,gBAAgB,2CAmvBlB"}
|