@rovela-ai/sdk 0.4.0 → 0.4.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.
Files changed (57) hide show
  1. package/dist/checkout/server/create-checkout-session.d.ts +10 -1
  2. package/dist/checkout/server/create-checkout-session.d.ts.map +1 -1
  3. package/dist/checkout/server/create-checkout-session.js +28 -17
  4. package/dist/checkout/server/create-checkout-session.js.map +1 -1
  5. package/dist/checkout/server/handle-webhook.js +22 -2
  6. package/dist/checkout/server/handle-webhook.js.map +1 -1
  7. package/dist/checkout/server/order-service.d.ts +7 -1
  8. package/dist/checkout/server/order-service.d.ts.map +1 -1
  9. package/dist/checkout/server/order-service.js +59 -12
  10. package/dist/checkout/server/order-service.js.map +1 -1
  11. package/dist/core/db/queries.d.ts +6 -6
  12. package/dist/core/db/schema.d.ts +4 -4
  13. package/package.json +2 -2
  14. package/dist/admin/api/auth.d.ts +0 -32
  15. package/dist/admin/api/auth.d.ts.map +0 -1
  16. package/dist/admin/api/auth.js +0 -37
  17. package/dist/admin/api/auth.js.map +0 -1
  18. package/dist/admin/components/AdminSetupForm.d.ts +0 -28
  19. package/dist/admin/components/AdminSetupForm.d.ts.map +0 -1
  20. package/dist/admin/components/AdminSetupForm.js +0 -85
  21. package/dist/admin/components/AdminSetupForm.js.map +0 -1
  22. package/dist/auth/api/auth.d.ts +0 -9
  23. package/dist/auth/api/auth.d.ts.map +0 -1
  24. package/dist/auth/api/auth.js +0 -9
  25. package/dist/auth/api/auth.js.map +0 -1
  26. package/dist/auth/server/email-sender.d.ts +0 -64
  27. package/dist/auth/server/email-sender.d.ts.map +0 -1
  28. package/dist/auth/server/email-sender.js +0 -106
  29. package/dist/auth/server/email-sender.js.map +0 -1
  30. package/dist/products/components/CategoryNav.d.ts +0 -51
  31. package/dist/products/components/CategoryNav.d.ts.map +0 -1
  32. package/dist/products/components/CategoryNav.js +0 -110
  33. package/dist/products/components/CategoryNav.js.map +0 -1
  34. package/dist/products/components/ProductBreadcrumb.d.ts +0 -52
  35. package/dist/products/components/ProductBreadcrumb.d.ts.map +0 -1
  36. package/dist/products/components/ProductBreadcrumb.js +0 -73
  37. package/dist/products/components/ProductBreadcrumb.js.map +0 -1
  38. package/dist/products/components/ProductFilters.d.ts +0 -70
  39. package/dist/products/components/ProductFilters.d.ts.map +0 -1
  40. package/dist/products/components/ProductFilters.js +0 -125
  41. package/dist/products/components/ProductFilters.js.map +0 -1
  42. package/dist/products/hooks/useCategories.d.ts +0 -56
  43. package/dist/products/hooks/useCategories.d.ts.map +0 -1
  44. package/dist/products/hooks/useCategories.js +0 -126
  45. package/dist/products/hooks/useCategories.js.map +0 -1
  46. package/dist/products/hooks/useProductAttributes.d.ts +0 -59
  47. package/dist/products/hooks/useProductAttributes.d.ts.map +0 -1
  48. package/dist/products/hooks/useProductAttributes.js +0 -125
  49. package/dist/products/hooks/useProductAttributes.js.map +0 -1
  50. package/dist/theme/ThemeProvider.d.ts +0 -70
  51. package/dist/theme/ThemeProvider.d.ts.map +0 -1
  52. package/dist/theme/ThemeProvider.js +0 -75
  53. package/dist/theme/ThemeProvider.js.map +0 -1
  54. package/dist/theme/hooks.d.ts +0 -110
  55. package/dist/theme/hooks.d.ts.map +0 -1
  56. package/dist/theme/hooks.js +0 -101
  57. package/dist/theme/hooks.js.map +0 -1
@@ -1,73 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- /**
4
- * @rovela/sdk/products/components/ProductBreadcrumb
5
- *
6
- * Breadcrumb navigation for product and category pages.
7
- */
8
- import Link from 'next/link';
9
- import { ChevronRight } from 'lucide-react';
10
- import { cn } from '../../core/utils';
11
- // =============================================================================
12
- // Component
13
- // =============================================================================
14
- /**
15
- * ProductBreadcrumb component for navigation context.
16
- *
17
- * @example
18
- * ```tsx
19
- * import { ProductBreadcrumb, useCategories } from '@rovela/sdk/products'
20
- *
21
- * function ProductPage({ product, categorySlug }) {
22
- * const { getBreadcrumb, getCategoryBySlug } = useCategories()
23
- * const category = getCategoryBySlug(categorySlug)
24
- * const categoryPath = category ? getBreadcrumb(category.id) : []
25
- *
26
- * return (
27
- * <div>
28
- * <ProductBreadcrumb
29
- * categories={categoryPath}
30
- * product={product}
31
- * showHome
32
- * />
33
- * {// ... product content}
34
- * </div>
35
- * )
36
- * }
37
- * ```
38
- */
39
- export function ProductBreadcrumb({ categories = [], product, className, showHome = true, homeLabel = 'Home', homeHref = '/', categoryHrefPattern = '/categories/[slug]', separator, items: customItems, }) {
40
- // Build breadcrumb items
41
- const items = [];
42
- if (customItems) {
43
- // Use custom items if provided
44
- items.push(...customItems);
45
- }
46
- else {
47
- // Build from categories and product
48
- if (showHome) {
49
- items.push({ label: homeLabel, href: homeHref });
50
- }
51
- // Add "Shop" or "Products" link
52
- items.push({ label: 'Products', href: '/products' });
53
- // Add category path
54
- categories.forEach((category) => {
55
- items.push({
56
- label: category.name,
57
- href: categoryHrefPattern.replace('[slug]', category.slug),
58
- });
59
- });
60
- // Add product (no link, it's the current page)
61
- if (product) {
62
- items.push({ label: product.name });
63
- }
64
- }
65
- const defaultSeparator = (_jsx(ChevronRight, { className: "h-4 w-4 flex-shrink-0 text-muted-foreground" }));
66
- return (_jsx("nav", { className: cn('flex items-center text-sm', className), "aria-label": "Breadcrumb", children: _jsx("ol", { className: "flex flex-wrap items-center gap-1.5", children: items.map((item, index) => {
67
- const isLast = index === items.length - 1;
68
- return (_jsxs("li", { className: "flex items-center gap-1.5", children: [index > 0 && (_jsx("span", { className: "flex-shrink-0", "aria-hidden": "true", children: separator || defaultSeparator })), item.href && !isLast ? (_jsx(Link, { href: item.href, className: "text-muted-foreground transition-colors hover:text-foreground", children: item.label })) : (_jsx("span", { className: cn(isLast
69
- ? 'font-medium text-foreground'
70
- : 'text-muted-foreground'), "aria-current": isLast ? 'page' : undefined, children: item.label }))] }, index));
71
- }) }) }));
72
- }
73
- //# sourceMappingURL=ProductBreadcrumb.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductBreadcrumb.js","sourceRoot":"","sources":["../../../src/products/components/ProductBreadcrumb.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAiCrC,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,UAAU,GAAG,EAAE,EACf,OAAO,EACP,SAAS,EACT,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,MAAM,EAClB,QAAQ,GAAG,GAAG,EACd,mBAAmB,GAAG,oBAAoB,EAC1C,SAAS,EACT,KAAK,EAAE,WAAW,GACK;IACvB,yBAAyB;IACzB,MAAM,KAAK,GAAqB,EAAE,CAAA;IAElC,IAAI,WAAW,EAAE,CAAC;QAChB,+BAA+B;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAA;IAC5B,CAAC;SAAM,CAAC;QACN,oCAAoC;QACpC,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAClD,CAAC;QAED,gCAAgC;QAChC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAEpD,oBAAoB;QACpB,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC9B,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,QAAQ,CAAC,IAAI;gBACpB,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;aAC3D,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,+CAA+C;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,CACvB,KAAC,YAAY,IAAC,SAAS,EAAC,6CAA6C,GAAG,CACzE,CAAA;IAED,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,2BAA2B,EAAE,SAAS,CAAC,gBAC1C,YAAY,YAEvB,aAAI,SAAS,EAAC,qCAAqC,YAChD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACzB,MAAM,MAAM,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;gBAEzC,OAAO,CACL,cAAgB,SAAS,EAAC,2BAA2B,aAClD,KAAK,GAAG,CAAC,IAAI,CACZ,eAAM,SAAS,EAAC,eAAe,iBAAa,MAAM,YAC/C,SAAS,IAAI,gBAAgB,GACzB,CACR,EAEA,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CACtB,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,SAAS,EAAC,+DAA+D,YAExE,IAAI,CAAC,KAAK,GACN,CACR,CAAC,CAAC,CAAC,CACF,eACE,SAAS,EAAE,EAAE,CACX,MAAM;gCACJ,CAAC,CAAC,6BAA6B;gCAC/B,CAAC,CAAC,uBAAuB,CAC5B,kBACa,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,YAExC,IAAI,CAAC,KAAK,GACN,CACR,KAzBM,KAAK,CA0BT,CACN,CAAA;YACH,CAAC,CAAC,GACC,GACD,CACP,CAAA;AACH,CAAC"}
@@ -1,70 +0,0 @@
1
- import type { ProductAttribute, PriceRange } from '../hooks/useProductAttributes';
2
- import type { Category } from '../../core/types';
3
- export interface ProductFilterValues {
4
- categories: string[];
5
- attributes: Record<string, string[]>;
6
- priceRange: {
7
- min?: number;
8
- max?: number;
9
- };
10
- }
11
- export interface ProductFilterPanelProps {
12
- /** Available attributes for filtering */
13
- attributes?: ProductAttribute[];
14
- /** Price range for price filter */
15
- priceRange?: PriceRange | null;
16
- /** Categories for category filter */
17
- categories?: Category[];
18
- /** Current filter values */
19
- values: ProductFilterValues;
20
- /** Callback when filters change */
21
- onChange: (values: ProductFilterValues) => void;
22
- /** Custom className */
23
- className?: string;
24
- /** Currency for price display */
25
- currency?: string;
26
- /** Locale for price formatting */
27
- locale?: string;
28
- /** Show category filter */
29
- showCategories?: boolean;
30
- /** Show price filter */
31
- showPriceFilter?: boolean;
32
- /** Collapsible sections */
33
- collapsible?: boolean;
34
- /** Initially expanded sections */
35
- defaultExpanded?: string[];
36
- /** Show clear all button */
37
- showClearAll?: boolean;
38
- /** Layout direction */
39
- layout?: 'vertical' | 'horizontal';
40
- }
41
- /**
42
- * ProductFilterPanel component for filtering product listings.
43
- *
44
- * @example
45
- * ```tsx
46
- * import { ProductFilters, useProductAttributes } from '@rovela/sdk/products'
47
- *
48
- * function Sidebar() {
49
- * const { attributes, priceRange } = useProductAttributes()
50
- * const [filters, setFilters] = useState({
51
- * categories: [],
52
- * attributes: {},
53
- * priceRange: {},
54
- * })
55
- *
56
- * return (
57
- * <ProductFilters
58
- * attributes={attributes}
59
- * priceRange={priceRange}
60
- * values={filters}
61
- * onChange={setFilters}
62
- * collapsible
63
- * showClearAll
64
- * />
65
- * )
66
- * }
67
- * ```
68
- */
69
- export declare function ProductFilterPanel({ attributes, priceRange, categories, values, onChange, className, currency, locale, showCategories, showPriceFilter, collapsible, defaultExpanded, showClearAll, layout, }: ProductFilterPanelProps): import("react/jsx-runtime").JSX.Element;
70
- //# sourceMappingURL=ProductFilters.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductFilters.d.ts","sourceRoot":"","sources":["../../../src/products/components/ProductFilters.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAMhD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACpC,UAAU,EAAE;QACV,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC/B,mCAAmC;IACnC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAC9B,qCAAqC;IACrC,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAA;IACvB,4BAA4B;IAC5B,MAAM,EAAE,mBAAmB,CAAA;IAC3B,mCAAmC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC/C,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2BAA2B;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,wBAAwB;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kCAAkC;IAClC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,4BAA4B;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,uBAAuB;IACvB,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;CACnC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,UAAe,EACf,UAAU,EACV,UAAe,EACf,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAgB,EAChB,MAAgB,EAChB,cAAqB,EACrB,eAAsB,EACtB,WAAkB,EAClB,eAAyC,EACzC,YAAmB,EACnB,MAAmB,GACpB,EAAE,uBAAuB,2CAqNzB"}
@@ -1,125 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- /**
4
- * @rovela/sdk/products/components/ProductFilters
5
- *
6
- * Comprehensive filter panel for product listings.
7
- */
8
- import { useState, useCallback, useMemo } from 'react';
9
- import { ChevronDown } from 'lucide-react';
10
- import { cn, formatPrice } from '../../core/utils';
11
- // =============================================================================
12
- // Component
13
- // =============================================================================
14
- /**
15
- * ProductFilterPanel component for filtering product listings.
16
- *
17
- * @example
18
- * ```tsx
19
- * import { ProductFilters, useProductAttributes } from '@rovela/sdk/products'
20
- *
21
- * function Sidebar() {
22
- * const { attributes, priceRange } = useProductAttributes()
23
- * const [filters, setFilters] = useState({
24
- * categories: [],
25
- * attributes: {},
26
- * priceRange: {},
27
- * })
28
- *
29
- * return (
30
- * <ProductFilters
31
- * attributes={attributes}
32
- * priceRange={priceRange}
33
- * values={filters}
34
- * onChange={setFilters}
35
- * collapsible
36
- * showClearAll
37
- * />
38
- * )
39
- * }
40
- * ```
41
- */
42
- export function ProductFilterPanel({ attributes = [], priceRange, categories = [], values, onChange, className, currency = 'USD', locale = 'en-US', showCategories = true, showPriceFilter = true, collapsible = true, defaultExpanded = ['price', 'categories'], showClearAll = true, layout = 'vertical', }) {
43
- const [expandedSections, setExpandedSections] = useState(new Set(defaultExpanded));
44
- // Check if any filters are active
45
- const hasActiveFilters = useMemo(() => {
46
- return (values.categories.length > 0 ||
47
- Object.values(values.attributes).some((v) => v.length > 0) ||
48
- values.priceRange.min !== undefined ||
49
- values.priceRange.max !== undefined);
50
- }, [values]);
51
- // Toggle section expansion
52
- const toggleSection = useCallback((section) => {
53
- setExpandedSections((prev) => {
54
- const next = new Set(prev);
55
- if (next.has(section)) {
56
- next.delete(section);
57
- }
58
- else {
59
- next.add(section);
60
- }
61
- return next;
62
- });
63
- }, []);
64
- // Handle category toggle
65
- const handleCategoryToggle = useCallback((categoryId) => {
66
- const newCategories = values.categories.includes(categoryId)
67
- ? values.categories.filter((id) => id !== categoryId)
68
- : [...values.categories, categoryId];
69
- onChange({ ...values, categories: newCategories });
70
- }, [values, onChange]);
71
- // Handle attribute toggle
72
- const handleAttributeToggle = useCallback((attributeName, attributeValue) => {
73
- const currentValues = values.attributes[attributeName] || [];
74
- const newValues = currentValues.includes(attributeValue)
75
- ? currentValues.filter((v) => v !== attributeValue)
76
- : [...currentValues, attributeValue];
77
- onChange({
78
- ...values,
79
- attributes: {
80
- ...values.attributes,
81
- [attributeName]: newValues,
82
- },
83
- });
84
- }, [values, onChange]);
85
- // Handle price range change
86
- const handlePriceChange = useCallback((type, value) => {
87
- onChange({
88
- ...values,
89
- priceRange: {
90
- ...values.priceRange,
91
- [type]: value,
92
- },
93
- });
94
- }, [values, onChange]);
95
- // Clear all filters
96
- const handleClearAll = useCallback(() => {
97
- onChange({
98
- categories: [],
99
- attributes: {},
100
- priceRange: {},
101
- });
102
- }, [onChange]);
103
- const containerClasses = cn(layout === 'vertical' ? 'space-y-4' : 'flex flex-wrap gap-4', className);
104
- return (_jsxs("div", { className: containerClasses, children: [showClearAll && hasActiveFilters && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-sm font-medium text-foreground", children: "Filters" }), _jsx("button", { onClick: handleClearAll, className: "text-sm text-primary hover:underline", children: "Clear all" })] })), showCategories && categories.length > 0 && (_jsx(FilterSection, { title: "Category", sectionId: "categories", isExpanded: expandedSections.has('categories'), onToggle: collapsible ? () => toggleSection('categories') : undefined, layout: layout, children: _jsx("div", { className: "space-y-2", children: categories.map((category) => (_jsxs("label", { className: "flex cursor-pointer items-center gap-2", children: [_jsx("input", { type: "checkbox", checked: values.categories.includes(category.id), onChange: () => handleCategoryToggle(category.id), className: "h-4 w-4 rounded border-border text-primary focus:ring-primary" }), _jsx("span", { className: "text-sm text-foreground", children: category.name })] }, category.id))) }) })), showPriceFilter && priceRange && (_jsx(FilterSection, { title: "Price", sectionId: "price", isExpanded: expandedSections.has('price'), onToggle: collapsible ? () => toggleSection('price') : undefined, layout: layout, children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "sr-only", children: "Min price" }), _jsx("input", { type: "number", placeholder: formatPrice(priceRange.min, { currency, locale }), value: values.priceRange.min ?? '', onChange: (e) => handlePriceChange('min', e.target.value ? parseFloat(e.target.value) : undefined), min: 0, className: "w-full rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary" })] }), _jsx("span", { className: "text-muted-foreground", children: "to" }), _jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "sr-only", children: "Max price" }), _jsx("input", { type: "number", placeholder: formatPrice(priceRange.max, { currency, locale }), value: values.priceRange.max ?? '', onChange: (e) => handlePriceChange('max', e.target.value ? parseFloat(e.target.value) : undefined), min: 0, className: "w-full rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary" })] })] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Range: ", formatPrice(priceRange.min, { currency, locale }), " -", ' ', formatPrice(priceRange.max, { currency, locale })] })] }) })), attributes.map((attribute) => (_jsx(FilterSection, { title: formatAttributeName(attribute.name), sectionId: attribute.name, isExpanded: expandedSections.has(attribute.name), onToggle: collapsible ? () => toggleSection(attribute.name) : undefined, layout: layout, children: _jsx("div", { className: "space-y-2", children: attribute.values.map((value) => (_jsxs("label", { className: "flex cursor-pointer items-center gap-2", children: [_jsx("input", { type: "checkbox", checked: (values.attributes[attribute.name] || []).includes(value), onChange: () => handleAttributeToggle(attribute.name, value), className: "h-4 w-4 rounded border-border text-primary focus:ring-primary" }), _jsx("span", { className: "text-sm text-foreground", children: value })] }, value))) }) }, attribute.name)))] }));
105
- }
106
- function FilterSection({ title, sectionId, isExpanded, onToggle, children, layout = 'vertical', }) {
107
- const isCollapsible = !!onToggle;
108
- if (layout === 'horizontal') {
109
- return (_jsxs("div", { className: "rounded-md border border-border p-3", children: [_jsx("span", { className: "mb-2 block text-sm font-medium text-foreground", children: title }), children] }));
110
- }
111
- return (_jsxs("div", { className: "border-b border-border pb-4", children: [isCollapsible ? (_jsxs("button", { onClick: onToggle, className: "flex w-full items-center justify-between py-2 text-sm font-medium text-foreground", "aria-expanded": isExpanded, "aria-controls": `filter-section-${sectionId}`, children: [_jsx("span", { children: title }), _jsx(ChevronDown, { className: cn('h-4 w-4 text-muted-foreground transition-transform', isExpanded && 'rotate-180') })] })) : (_jsx("span", { className: "block py-2 text-sm font-medium text-foreground", children: title })), (!isCollapsible || isExpanded) && (_jsx("div", { id: `filter-section-${sectionId}`, children: children }))] }));
112
- }
113
- // =============================================================================
114
- // Helpers
115
- // =============================================================================
116
- function formatAttributeName(name) {
117
- return name
118
- .replace(/_/g, ' ')
119
- .replace(/([A-Z])/g, ' $1')
120
- .trim()
121
- .split(' ')
122
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
123
- .join(' ');
124
- }
125
- //# sourceMappingURL=ProductFilters.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductFilters.js","sourceRoot":"","sources":["../../../src/products/components/ProductFilters.tsx"],"names":[],"mappings":"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"}
@@ -1,56 +0,0 @@
1
- import type { Category } from '../../core/types';
2
- export interface CategoryWithChildren extends Category {
3
- children: CategoryWithChildren[];
4
- }
5
- export interface UseCategoriesOptions {
6
- /** API endpoint (default /api/categories) */
7
- endpoint?: string;
8
- /** Skip fetching */
9
- skip?: boolean;
10
- /** Initial data (for SSR hydration) */
11
- initialData?: Category[];
12
- }
13
- export interface UseCategoriesReturn {
14
- /** Flat list of all categories */
15
- categories: Category[];
16
- /** Hierarchical category tree (root categories with nested children) */
17
- tree: CategoryWithChildren[];
18
- /** Whether data is currently loading */
19
- isLoading: boolean;
20
- /** Error if request failed */
21
- error: Error | null;
22
- /** Refresh the categories */
23
- refresh: () => void;
24
- /** Get a category by ID */
25
- getCategoryById: (id: string) => Category | undefined;
26
- /** Get a category by slug */
27
- getCategoryBySlug: (slug: string) => Category | undefined;
28
- /** Get child categories of a parent */
29
- getChildren: (parentId: string | null) => Category[];
30
- /** Get breadcrumb path for a category */
31
- getBreadcrumb: (categoryId: string) => Category[];
32
- }
33
- /**
34
- * Hook for fetching and managing categories.
35
- *
36
- * @example
37
- * ```tsx
38
- * import { useCategories } from '@rovela/sdk/products'
39
- *
40
- * function CategoryNav() {
41
- * const { tree, isLoading } = useCategories()
42
- *
43
- * if (isLoading) return <div>Loading...</div>
44
- *
45
- * return (
46
- * <nav>
47
- * {tree.map(category => (
48
- * <CategoryLink key={category.id} category={category} />
49
- * ))}
50
- * </nav>
51
- * )
52
- * }
53
- * ```
54
- */
55
- export declare function useCategories(options?: UseCategoriesOptions): UseCategoriesReturn;
56
- //# sourceMappingURL=useCategories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["../../../src/products/hooks/useCategories.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAMhD,MAAM,WAAW,oBAAqB,SAAQ,QAAQ;IACpD,QAAQ,EAAE,oBAAoB,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oBAAoB;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uCAAuC;IACvC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,kCAAkC;IAClC,UAAU,EAAE,QAAQ,EAAE,CAAA;IACtB,wEAAwE;IACxE,IAAI,EAAE,oBAAoB,EAAE,CAAA;IAC5B,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAA;IAClB,8BAA8B;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,2BAA2B;IAC3B,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,CAAA;IACrD,6BAA6B;IAC7B,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,CAAA;IACzD,uCAAuC;IACvC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,QAAQ,EAAE,CAAA;IACpD,yCAAyC;IACzC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAA;CAClD;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CA+HrB"}
@@ -1,126 +0,0 @@
1
- 'use client';
2
- /**
3
- * @rovela/sdk/products/hooks/useCategories
4
- *
5
- * Hook for fetching category tree.
6
- */
7
- import { useState, useEffect, useCallback, useMemo } from 'react';
8
- // =============================================================================
9
- // Hook
10
- // =============================================================================
11
- /**
12
- * Hook for fetching and managing categories.
13
- *
14
- * @example
15
- * ```tsx
16
- * import { useCategories } from '@rovela/sdk/products'
17
- *
18
- * function CategoryNav() {
19
- * const { tree, isLoading } = useCategories()
20
- *
21
- * if (isLoading) return <div>Loading...</div>
22
- *
23
- * return (
24
- * <nav>
25
- * {tree.map(category => (
26
- * <CategoryLink key={category.id} category={category} />
27
- * ))}
28
- * </nav>
29
- * )
30
- * }
31
- * ```
32
- */
33
- export function useCategories(options = {}) {
34
- const { endpoint = '/api/categories', skip = false, initialData, } = options;
35
- const [categories, setCategories] = useState(initialData || []);
36
- const [isLoading, setIsLoading] = useState(!initialData && !skip);
37
- const [error, setError] = useState(null);
38
- // Fetch categories
39
- const fetchCategories = useCallback(async () => {
40
- if (skip)
41
- return;
42
- setIsLoading(true);
43
- setError(null);
44
- try {
45
- const response = await fetch(endpoint);
46
- if (!response.ok) {
47
- const errorData = await response.json().catch(() => ({}));
48
- throw new Error(errorData.error || `HTTP ${response.status}`);
49
- }
50
- const data = await response.json();
51
- setCategories(data.data || []);
52
- }
53
- catch (err) {
54
- setError(err instanceof Error ? err : new Error('Failed to fetch categories'));
55
- }
56
- finally {
57
- setIsLoading(false);
58
- }
59
- }, [endpoint, skip]);
60
- // Fetch on mount and when fetchCategories' captured endpoint changes.
61
- // initialData is read once on mount as a hydration shortcut — listing it
62
- // would re-fetch every time a parent passes a new SSR snapshot.
63
- useEffect(() => {
64
- if (!initialData) {
65
- fetchCategories();
66
- }
67
- // eslint-disable-next-line react-hooks/exhaustive-deps
68
- }, [fetchCategories]);
69
- // Build category tree
70
- const tree = useMemo(() => {
71
- const categoryMap = new Map();
72
- // First pass: create all nodes with empty children
73
- categories.forEach((cat) => {
74
- categoryMap.set(cat.id, { ...cat, children: [] });
75
- });
76
- // Second pass: build tree structure
77
- const roots = [];
78
- categories.forEach((cat) => {
79
- const node = categoryMap.get(cat.id);
80
- if (cat.parentId && categoryMap.has(cat.parentId)) {
81
- const parent = categoryMap.get(cat.parentId);
82
- parent.children.push(node);
83
- }
84
- else {
85
- roots.push(node);
86
- }
87
- });
88
- // Sort children by order
89
- const sortChildren = (nodes) => {
90
- nodes.sort((a, b) => a.order - b.order);
91
- nodes.forEach((node) => sortChildren(node.children));
92
- };
93
- sortChildren(roots);
94
- return roots;
95
- }, [categories]);
96
- // Helper: get category by ID
97
- const getCategoryById = useCallback((id) => categories.find((c) => c.id === id), [categories]);
98
- // Helper: get category by slug
99
- const getCategoryBySlug = useCallback((slug) => categories.find((c) => c.slug === slug), [categories]);
100
- // Helper: get children of a parent
101
- const getChildren = useCallback((parentId) => categories
102
- .filter((c) => c.parentId === parentId)
103
- .sort((a, b) => a.order - b.order), [categories]);
104
- // Helper: get breadcrumb path
105
- const getBreadcrumb = useCallback((categoryId) => {
106
- const path = [];
107
- let current = getCategoryById(categoryId);
108
- while (current) {
109
- path.unshift(current);
110
- current = current.parentId ? getCategoryById(current.parentId) : undefined;
111
- }
112
- return path;
113
- }, [getCategoryById]);
114
- return {
115
- categories,
116
- tree,
117
- isLoading,
118
- error,
119
- refresh: fetchCategories,
120
- getCategoryById,
121
- getCategoryBySlug,
122
- getChildren,
123
- getBreadcrumb,
124
- };
125
- }
126
- //# sourceMappingURL=useCategories.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCategories.js","sourceRoot":"","sources":["../../../src/products/hooks/useCategories.ts"],"names":[],"mappings":"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"}
@@ -1,59 +0,0 @@
1
- export interface ProductAttribute {
2
- /** Attribute name (e.g., "color", "size") */
3
- name: string;
4
- /** All unique values for this attribute */
5
- values: string[];
6
- }
7
- export interface PriceRange {
8
- min: number;
9
- max: number;
10
- }
11
- export interface UseProductAttributesOptions {
12
- /** Category to filter by (fetches products from this category) */
13
- categoryId?: string;
14
- /** API endpoint for products */
15
- endpoint?: string;
16
- /** Skip fetching */
17
- skip?: boolean;
18
- }
19
- export interface UseProductAttributesReturn {
20
- /** Available filter attributes with their values */
21
- attributes: ProductAttribute[];
22
- /** Price range across all products */
23
- priceRange: PriceRange | null;
24
- /** Whether data is currently loading */
25
- isLoading: boolean;
26
- /** Error if request failed */
27
- error: Error | null;
28
- /** Refresh the attributes */
29
- refresh: () => void;
30
- }
31
- /**
32
- * Hook for extracting available product attributes for filtering.
33
- *
34
- * @example
35
- * ```tsx
36
- * import { useProductAttributes } from '@rovela/sdk/products'
37
- *
38
- * function ProductFilters({ categoryId }: { categoryId?: string }) {
39
- * const { attributes, priceRange, isLoading } = useProductAttributes({
40
- * categoryId,
41
- * })
42
- *
43
- * if (isLoading) return <div>Loading filters...</div>
44
- *
45
- * return (
46
- * <div>
47
- * {attributes.map(attr => (
48
- * <FilterGroup key={attr.name} name={attr.name} values={attr.values} />
49
- * ))}
50
- * {priceRange && (
51
- * <PriceSlider min={priceRange.min} max={priceRange.max} />
52
- * )}
53
- * </div>
54
- * )
55
- * }
56
- * ```
57
- */
58
- export declare function useProductAttributes(options?: UseProductAttributesOptions): UseProductAttributesReturn;
59
- //# sourceMappingURL=useProductAttributes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useProductAttributes.d.ts","sourceRoot":"","sources":["../../../src/products/hooks/useProductAttributes.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,2BAA2B;IAC1C,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oBAAoB;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,oDAAoD;IACpD,UAAU,EAAE,gBAAgB,EAAE,CAAA;IAC9B,sCAAsC;IACtC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;IAC7B,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAA;IAClB,8BAA8B;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,0BAA0B,CAmG5B"}