@beyondcorp/beyond-ui 1.2.51 → 1.2.55

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 (117) hide show
  1. package/dist/components/Blog/AllBlogsView.d.ts +8 -0
  2. package/dist/components/Blog/AllBlogsView.js +70 -0
  3. package/dist/components/Blog/AllBlogsView.js.map +1 -0
  4. package/dist/components/Blog/BlogCommentSection.d.ts +7 -0
  5. package/dist/components/Blog/BlogCommentSection.js +66 -0
  6. package/dist/components/Blog/BlogCommentSection.js.map +1 -0
  7. package/dist/components/Blog/BlogLayout.d.ts +11 -0
  8. package/dist/components/Blog/BlogLayout.js +29 -0
  9. package/dist/components/Blog/BlogLayout.js.map +1 -0
  10. package/dist/components/Blog/BlogShowcase.d.ts +2 -0
  11. package/dist/components/Blog/BlogShowcase.js +74 -0
  12. package/dist/components/Blog/BlogShowcase.js.map +1 -0
  13. package/dist/components/Blog/BlogSidebar.d.ts +10 -0
  14. package/dist/components/Blog/BlogSidebar.js +47 -0
  15. package/dist/components/Blog/BlogSidebar.js.map +1 -0
  16. package/dist/components/Blog/SingleBlogView.d.ts +8 -0
  17. package/dist/components/Blog/SingleBlogView.js +78 -0
  18. package/dist/components/Blog/SingleBlogView.js.map +1 -0
  19. package/dist/components/Blog/data/sampleData.d.ts +4 -0
  20. package/dist/components/Blog/data/sampleData.js +388 -0
  21. package/dist/components/Blog/data/sampleData.js.map +1 -0
  22. package/dist/components/Blog/hooks/index.d.ts +3 -0
  23. package/dist/components/Blog/hooks/useBlog.d.ts +22 -0
  24. package/dist/components/Blog/hooks/useBlog.js +148 -0
  25. package/dist/components/Blog/hooks/useBlog.js.map +1 -0
  26. package/dist/components/Blog/hooks/useBlogNavigation.d.ts +12 -0
  27. package/dist/components/Blog/hooks/useBlogNavigation.js +75 -0
  28. package/dist/components/Blog/hooks/useBlogNavigation.js.map +1 -0
  29. package/dist/components/Blog/hooks/useComments.d.ts +20 -0
  30. package/dist/components/Blog/hooks/useComments.js +108 -0
  31. package/dist/components/Blog/hooks/useComments.js.map +1 -0
  32. package/dist/components/Blog/index.d.ts +8 -0
  33. package/dist/components/Blog/types.d.ts +82 -0
  34. package/dist/components/CodeHighlight/CodeHighlight.d.ts +7 -0
  35. package/dist/components/CodeHighlight/CodeHighlight.js +18 -0
  36. package/dist/components/CodeHighlight/CodeHighlight.js.map +1 -0
  37. package/dist/components/CodeHighlight/index.d.ts +1 -0
  38. package/dist/components/Marketplace/AllProductsView.d.ts +6 -1
  39. package/dist/components/Marketplace/AllProductsView.js +42 -65
  40. package/dist/components/Marketplace/AllProductsView.js.map +1 -1
  41. package/dist/components/Marketplace/CheckoutCompact.d.ts +1 -0
  42. package/dist/components/Marketplace/CheckoutCompact.js +3 -3
  43. package/dist/components/Marketplace/CheckoutCompact.js.map +1 -1
  44. package/dist/components/Marketplace/CheckoutComponent.js +1 -1
  45. package/dist/components/Marketplace/CheckoutComponent.js.map +1 -1
  46. package/dist/components/Marketplace/MarketplaceComponent.js +31 -2
  47. package/dist/components/Marketplace/MarketplaceComponent.js.map +1 -1
  48. package/dist/components/Marketplace/MarketplaceSidebar.js +32 -32
  49. package/dist/components/Marketplace/MarketplaceSidebar.js.map +1 -1
  50. package/dist/components/Marketplace/SingleProductView.js +3 -0
  51. package/dist/components/Marketplace/SingleProductView.js.map +1 -1
  52. package/dist/components/Marketplace/components/MarketplaceControls.d.ts +17 -0
  53. package/dist/components/Marketplace/components/MarketplaceControls.js +22 -0
  54. package/dist/components/Marketplace/components/MarketplaceControls.js.map +1 -0
  55. package/dist/components/Marketplace/components/MarketplaceDashboard.d.ts +3 -0
  56. package/dist/components/Marketplace/components/MarketplaceDashboard.js +20 -10
  57. package/dist/components/Marketplace/components/MarketplaceDashboard.js.map +1 -1
  58. package/dist/components/Marketplace/components/MarketplaceHeader.js +2 -3
  59. package/dist/components/Marketplace/components/MarketplaceHeader.js.map +1 -1
  60. package/dist/components/Marketplace/components/ProductCard.js +9 -2
  61. package/dist/components/Marketplace/components/ProductCard.js.map +1 -1
  62. package/dist/components/Marketplace/hooks/useScrollToTop.d.ts +10 -0
  63. package/dist/components/Marketplace/hooks/useScrollToTop.js +22 -0
  64. package/dist/components/Marketplace/hooks/useScrollToTop.js.map +1 -0
  65. package/dist/index.d.ts +2 -4
  66. package/dist/index.js +10 -4
  67. package/dist/styles.css +1 -1
  68. package/package.json +6 -1
  69. package/dist/components/AllProductsView/AllProductsView.d.ts +0 -14
  70. package/dist/components/AllProductsView/AllProductsView.js +0 -61
  71. package/dist/components/AllProductsView/AllProductsView.js.map +0 -1
  72. package/dist/components/AllProductsView/CardGroup.d.ts +0 -6
  73. package/dist/components/AllProductsView/CardGroup.js +0 -11
  74. package/dist/components/AllProductsView/CardGroup.js.map +0 -1
  75. package/dist/components/AllProductsView/ProductCard.d.ts +0 -11
  76. package/dist/components/AllProductsView/ProductCard.js +0 -13
  77. package/dist/components/AllProductsView/ProductCard.js.map +0 -1
  78. package/dist/components/AllProductsView/index.d.ts +0 -2
  79. package/dist/components/BlogFeedView/BlogFeedView.d.ts +0 -22
  80. package/dist/components/BlogFeedView/BlogFeedView.js +0 -29
  81. package/dist/components/BlogFeedView/BlogFeedView.js.map +0 -1
  82. package/dist/components/BlogFeedView/index.d.ts +0 -1
  83. package/dist/components/BlogLayout/BlogLayout.d.ts +0 -13
  84. package/dist/components/BlogLayout/BlogLayout.js +0 -20
  85. package/dist/components/BlogLayout/BlogLayout.js.map +0 -1
  86. package/dist/components/BlogLayout/index.d.ts +0 -1
  87. package/dist/components/BlogSidebar/BlogSidebar.d.ts +0 -19
  88. package/dist/components/BlogSidebar/BlogSidebar.js +0 -10
  89. package/dist/components/BlogSidebar/BlogSidebar.js.map +0 -1
  90. package/dist/components/BlogSidebar/index.d.ts +0 -1
  91. package/dist/components/Checkout/CheckoutPage.d.ts +0 -16
  92. package/dist/components/Checkout/CheckoutPage.js +0 -44
  93. package/dist/components/Checkout/CheckoutPage.js.map +0 -1
  94. package/dist/components/Checkout/CheckoutSidebar.d.ts +0 -15
  95. package/dist/components/Checkout/CheckoutSidebar.js +0 -25
  96. package/dist/components/Checkout/CheckoutSidebar.js.map +0 -1
  97. package/dist/components/Checkout/index.d.ts +0 -3
  98. package/dist/components/Checkout/types.d.ts +0 -21
  99. package/dist/components/CommerceSidebar/CommerceSidebar.d.ts +0 -20
  100. package/dist/components/CommerceSidebar/CommerceSidebar.js +0 -14
  101. package/dist/components/CommerceSidebar/CommerceSidebar.js.map +0 -1
  102. package/dist/components/CommerceSidebar/index.d.ts +0 -1
  103. package/dist/components/MarketplaceLayout/MarketplaceLayout.d.ts +0 -17
  104. package/dist/components/MarketplaceLayout/MarketplaceLayout.js +0 -22
  105. package/dist/components/MarketplaceLayout/MarketplaceLayout.js.map +0 -1
  106. package/dist/components/MarketplaceLayout/index.d.ts +0 -1
  107. package/dist/components/ProfileManagement/ProfileManagementPage.d.ts +0 -16
  108. package/dist/components/ProfileManagement/ProfileManagementPage.js +0 -65
  109. package/dist/components/ProfileManagement/ProfileManagementPage.js.map +0 -1
  110. package/dist/components/SingleBlogView/SingleBlogView.d.ts +0 -26
  111. package/dist/components/SingleBlogView/SingleBlogView.js +0 -17
  112. package/dist/components/SingleBlogView/SingleBlogView.js.map +0 -1
  113. package/dist/components/SingleBlogView/index.d.ts +0 -1
  114. package/dist/components/SingleProductView/SingleProductView.d.ts +0 -31
  115. package/dist/components/SingleProductView/SingleProductView.js +0 -34
  116. package/dist/components/SingleProductView/SingleProductView.js.map +0 -1
  117. package/dist/components/SingleProductView/index.d.ts +0 -1
@@ -0,0 +1,75 @@
1
+ import { useState, useCallback, useEffect } from 'react';
2
+
3
+ /**
4
+ * Custom hook for blog navigation and table of contents
5
+ * Handles smooth scrolling and active section tracking
6
+ */
7
+ const useBlogNavigation = () => {
8
+ const [tableOfContents, setTableOfContents] = useState([]);
9
+ const [activeSection, setActiveSection] = useState('');
10
+ // Generate table of contents from markdown content
11
+ const generateTableOfContents = useCallback((content) => {
12
+ const headingRegex = /^(#{1,6})\s+(.+)$/gm;
13
+ const toc = [];
14
+ let match;
15
+ while ((match = headingRegex.exec(content)) !== null) {
16
+ const level = match[1].length;
17
+ const title = match[2].trim();
18
+ const anchor = title
19
+ .toLowerCase()
20
+ .replace(/[^a-z0-9\s-]/g, '')
21
+ .replace(/\s+/g, '-');
22
+ toc.push({
23
+ id: `toc-${toc.length}`,
24
+ title,
25
+ level,
26
+ anchor,
27
+ });
28
+ }
29
+ setTableOfContents(toc);
30
+ }, []);
31
+ // Smooth scroll to section
32
+ const scrollToSection = useCallback((anchor) => {
33
+ const element = document.getElementById(anchor);
34
+ if (element) {
35
+ element.scrollIntoView({
36
+ behavior: 'smooth',
37
+ block: 'start',
38
+ });
39
+ setActiveSection(anchor);
40
+ }
41
+ }, []);
42
+ // Track active section on scroll
43
+ useEffect(() => {
44
+ const handleScroll = () => {
45
+ const headings = tableOfContents.map(item => ({
46
+ anchor: item.anchor,
47
+ element: document.getElementById(item.anchor),
48
+ })).filter(item => item.element);
49
+ let currentActive = '';
50
+ for (const heading of headings) {
51
+ const rect = heading.element.getBoundingClientRect();
52
+ if (rect.top <= 100) {
53
+ currentActive = heading.anchor;
54
+ }
55
+ else {
56
+ break;
57
+ }
58
+ }
59
+ if (currentActive !== activeSection) {
60
+ setActiveSection(currentActive);
61
+ }
62
+ };
63
+ window.addEventListener('scroll', handleScroll, { passive: true });
64
+ return () => window.removeEventListener('scroll', handleScroll);
65
+ }, [tableOfContents, activeSection]);
66
+ return {
67
+ tableOfContents,
68
+ activeSection,
69
+ scrollToSection,
70
+ generateTableOfContents,
71
+ };
72
+ };
73
+
74
+ export { useBlogNavigation };
75
+ //# sourceMappingURL=useBlogNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBlogNavigation.js","sources":["../../../../src/components/Blog/hooks/useBlogNavigation.ts"],"sourcesContent":["import { useState, useCallback, useEffect } from 'react';\nimport type { TableOfContentsItem } from '../types';\n\nexport interface UseBlogNavigationReturn {\n tableOfContents: TableOfContentsItem[];\n activeSection: string;\n scrollToSection: (anchor: string) => void;\n generateTableOfContents: (content: string) => void;\n}\n\n/**\n * Custom hook for blog navigation and table of contents\n * Handles smooth scrolling and active section tracking\n */\nexport const useBlogNavigation = (): UseBlogNavigationReturn => {\n const [tableOfContents, setTableOfContents] = useState<TableOfContentsItem[]>([]);\n const [activeSection, setActiveSection] = useState('');\n\n // Generate table of contents from markdown content\n const generateTableOfContents = useCallback((content: string) => {\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n const toc: TableOfContentsItem[] = [];\n let match;\n\n while ((match = headingRegex.exec(content)) !== null) {\n const level = match[1].length;\n const title = match[2].trim();\n const anchor = title\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-');\n\n toc.push({\n id: `toc-${toc.length}`,\n title,\n level,\n anchor,\n });\n }\n\n setTableOfContents(toc);\n }, []);\n\n // Smooth scroll to section\n const scrollToSection = useCallback((anchor: string) => {\n const element = document.getElementById(anchor);\n if (element) {\n element.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n });\n setActiveSection(anchor);\n }\n }, []);\n\n // Track active section on scroll\n useEffect(() => {\n const handleScroll = () => {\n const headings = tableOfContents.map(item => ({\n anchor: item.anchor,\n element: document.getElementById(item.anchor),\n })).filter(item => item.element);\n\n let currentActive = '';\n \n for (const heading of headings) {\n const rect = heading.element!.getBoundingClientRect();\n if (rect.top <= 100) {\n currentActive = heading.anchor;\n } else {\n break;\n }\n }\n\n if (currentActive !== activeSection) {\n setActiveSection(currentActive);\n }\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, [tableOfContents, activeSection]);\n\n return {\n tableOfContents,\n activeSection,\n scrollToSection,\n generateTableOfContents,\n };\n};"],"names":[],"mappings":";;AAUA;;;AAGG;AACI,MAAM,iBAAiB,GAAG,MAA8B;IAC7D,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAwB,EAAE,CAAC;IACjF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;;AAGtD,IAAA,MAAM,uBAAuB,GAAG,WAAW,CAAC,CAAC,OAAe,KAAI;QAC9D,MAAM,YAAY,GAAG,qBAAqB;QAC1C,MAAM,GAAG,GAA0B,EAAE;AACrC,QAAA,IAAI,KAAK;AAET,QAAA,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE;YACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;YAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAC7B,MAAM,MAAM,GAAG;AACZ,iBAAA,WAAW;AACX,iBAAA,OAAO,CAAC,eAAe,EAAE,EAAE;AAC3B,iBAAA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;YAEvB,GAAG,CAAC,IAAI,CAAC;AACP,gBAAA,EAAE,EAAE,CAAA,IAAA,EAAO,GAAG,CAAC,MAAM,CAAA,CAAE;gBACvB,KAAK;gBACL,KAAK;gBACL,MAAM;AACP,aAAA,CAAC;QACJ;QAEA,kBAAkB,CAAC,GAAG,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAA,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,MAAc,KAAI;QACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC;QAC/C,IAAI,OAAO,EAAE;YACX,OAAO,CAAC,cAAc,CAAC;AACrB,gBAAA,QAAQ,EAAE,QAAQ;AAClB,gBAAA,KAAK,EAAE,OAAO;AACf,aAAA,CAAC;YACF,gBAAgB,CAAC,MAAM,CAAC;QAC1B;IACF,CAAC,EAAE,EAAE,CAAC;;IAGN,SAAS,CAAC,MAAK;QACb,MAAM,YAAY,GAAG,MAAK;YACxB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,KAAK;gBAC5C,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;AAC9C,aAAA,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC;YAEhC,IAAI,aAAa,GAAG,EAAE;AAEtB,YAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAQ,CAAC,qBAAqB,EAAE;AACrD,gBAAA,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG,EAAE;AACnB,oBAAA,aAAa,GAAG,OAAO,CAAC,MAAM;gBAChC;qBAAO;oBACL;gBACF;YACF;AAEA,YAAA,IAAI,aAAa,KAAK,aAAa,EAAE;gBACnC,gBAAgB,CAAC,aAAa,CAAC;YACjC;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClE,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;AACjE,IAAA,CAAC,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAEpC,OAAO;QACL,eAAe;QACf,aAAa;QACb,eAAe;QACf,uBAAuB;KACxB;AACH;;;;"}
@@ -0,0 +1,20 @@
1
+ import type { BlogComment } from '../types';
2
+ export interface UseCommentsProps {
3
+ postId: string;
4
+ }
5
+ export interface UseCommentsReturn {
6
+ comments: BlogComment[];
7
+ loading: boolean;
8
+ error: string | null;
9
+ addComment: (content: string, parentId?: string) => Promise<void>;
10
+ likeComment: (commentId: string) => void;
11
+ dislikeComment: (commentId: string) => void;
12
+ reportComment: (commentId: string) => void;
13
+ deleteComment: (commentId: string) => void;
14
+ getCommentCount: () => number;
15
+ }
16
+ /**
17
+ * Custom hook for managing blog comments
18
+ * Handles comment CRUD operations, moderation, and nested replies
19
+ */
20
+ export declare const useComments: ({ postId }: UseCommentsProps) => UseCommentsReturn;
@@ -0,0 +1,108 @@
1
+ import { useState, useMemo, useCallback } from 'react';
2
+ import { sampleBlogComments } from '../data/sampleData.js';
3
+ import { showToast } from '../../Toast/Toast.js';
4
+
5
+ /**
6
+ * Custom hook for managing blog comments
7
+ * Handles comment CRUD operations, moderation, and nested replies
8
+ */
9
+ const useComments = ({ postId }) => {
10
+ const [comments, setComments] = useState(sampleBlogComments.filter(comment => comment.postId === postId));
11
+ const [loading, setLoading] = useState(false);
12
+ const [error, setError] = useState(null);
13
+ // Organize comments into tree structure
14
+ const organizedComments = useMemo(() => {
15
+ const commentMap = new Map();
16
+ const rootComments = [];
17
+ // First pass: create map of all comments
18
+ comments.forEach(comment => {
19
+ commentMap.set(comment.id, { ...comment, replies: [] });
20
+ });
21
+ // Second pass: organize into tree structure
22
+ comments.forEach(comment => {
23
+ const commentWithReplies = commentMap.get(comment.id);
24
+ if (comment.parentId) {
25
+ const parent = commentMap.get(comment.parentId);
26
+ if (parent) {
27
+ parent.replies = parent.replies || [];
28
+ parent.replies.push(commentWithReplies);
29
+ }
30
+ }
31
+ else {
32
+ rootComments.push(commentWithReplies);
33
+ }
34
+ });
35
+ return rootComments;
36
+ }, [comments]);
37
+ const addComment = useCallback(async (content, parentId) => {
38
+ setLoading(true);
39
+ setError(null);
40
+ try {
41
+ // Simulate API call
42
+ await new Promise(resolve => setTimeout(resolve, 1000));
43
+ const newComment = {
44
+ id: `c${Date.now()}`,
45
+ postId,
46
+ parentId,
47
+ author: {
48
+ id: 'current-user',
49
+ name: 'Current User',
50
+ avatar: 'https://images.pexels.com/photos/774909/pexels-photo-774909.jpeg?auto=compress&cs=tinysrgb&w=64',
51
+ },
52
+ content,
53
+ createdAt: new Date().toISOString(),
54
+ likes: 0,
55
+ dislikes: 0,
56
+ isModerated: false,
57
+ isReported: false,
58
+ };
59
+ setComments(prev => [...prev, newComment]);
60
+ showToast.success('Comment added successfully!');
61
+ }
62
+ catch (err) {
63
+ setError('Failed to add comment');
64
+ showToast.error('Failed to add comment');
65
+ }
66
+ finally {
67
+ setLoading(false);
68
+ }
69
+ }, [postId]);
70
+ const likeComment = useCallback((commentId) => {
71
+ setComments(prev => prev.map(comment => comment.id === commentId
72
+ ? { ...comment, likes: comment.likes + 1 }
73
+ : comment));
74
+ showToast.success('Comment liked!');
75
+ }, []);
76
+ const dislikeComment = useCallback((commentId) => {
77
+ setComments(prev => prev.map(comment => comment.id === commentId
78
+ ? { ...comment, dislikes: comment.dislikes + 1 }
79
+ : comment));
80
+ }, []);
81
+ const reportComment = useCallback((commentId) => {
82
+ setComments(prev => prev.map(comment => comment.id === commentId
83
+ ? { ...comment, isReported: true }
84
+ : comment));
85
+ showToast.info('Comment reported for moderation');
86
+ }, []);
87
+ const deleteComment = useCallback((commentId) => {
88
+ setComments(prev => prev.filter(comment => comment.id !== commentId));
89
+ showToast.info('Comment deleted');
90
+ }, []);
91
+ const getCommentCount = useCallback(() => {
92
+ return comments.length;
93
+ }, [comments.length]);
94
+ return {
95
+ comments: organizedComments,
96
+ loading,
97
+ error,
98
+ addComment,
99
+ likeComment,
100
+ dislikeComment,
101
+ reportComment,
102
+ deleteComment,
103
+ getCommentCount,
104
+ };
105
+ };
106
+
107
+ export { useComments };
108
+ //# sourceMappingURL=useComments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useComments.js","sources":["../../../../src/components/Blog/hooks/useComments.ts"],"sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport type { BlogComment } from '../types';\nimport { sampleBlogComments } from '../data/sampleData';\nimport { showToast } from '../../Toast';\n\nexport interface UseCommentsProps {\n postId: string;\n}\n\nexport interface UseCommentsReturn {\n comments: BlogComment[];\n loading: boolean;\n error: string | null;\n addComment: (content: string, parentId?: string) => Promise<void>;\n likeComment: (commentId: string) => void;\n dislikeComment: (commentId: string) => void;\n reportComment: (commentId: string) => void;\n deleteComment: (commentId: string) => void;\n getCommentCount: () => number;\n}\n\n/**\n * Custom hook for managing blog comments\n * Handles comment CRUD operations, moderation, and nested replies\n */\nexport const useComments = ({ postId }: UseCommentsProps): UseCommentsReturn => {\n const [comments, setComments] = useState<BlogComment[]>(\n sampleBlogComments.filter(comment => comment.postId === postId)\n );\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Organize comments into tree structure\n const organizedComments = useMemo(() => {\n const commentMap = new Map<string, BlogComment>();\n const rootComments: BlogComment[] = [];\n\n // First pass: create map of all comments\n comments.forEach(comment => {\n commentMap.set(comment.id, { ...comment, replies: [] });\n });\n\n // Second pass: organize into tree structure\n comments.forEach(comment => {\n const commentWithReplies = commentMap.get(comment.id)!;\n \n if (comment.parentId) {\n const parent = commentMap.get(comment.parentId);\n if (parent) {\n parent.replies = parent.replies || [];\n parent.replies.push(commentWithReplies);\n }\n } else {\n rootComments.push(commentWithReplies);\n }\n });\n\n return rootComments;\n }, [comments]);\n\n const addComment = useCallback(async (content: string, parentId?: string) => {\n setLoading(true);\n setError(null);\n\n try {\n // Simulate API call\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n const newComment: BlogComment = {\n id: `c${Date.now()}`,\n postId,\n parentId,\n author: {\n id: 'current-user',\n name: 'Current User',\n avatar: 'https://images.pexels.com/photos/774909/pexels-photo-774909.jpeg?auto=compress&cs=tinysrgb&w=64',\n },\n content,\n createdAt: new Date().toISOString(),\n likes: 0,\n dislikes: 0,\n isModerated: false,\n isReported: false,\n };\n\n setComments(prev => [...prev, newComment]);\n showToast.success('Comment added successfully!');\n } catch (err) {\n setError('Failed to add comment');\n showToast.error('Failed to add comment');\n } finally {\n setLoading(false);\n }\n }, [postId]);\n\n const likeComment = useCallback((commentId: string) => {\n setComments(prev =>\n prev.map(comment =>\n comment.id === commentId\n ? { ...comment, likes: comment.likes + 1 }\n : comment\n )\n );\n showToast.success('Comment liked!');\n }, []);\n\n const dislikeComment = useCallback((commentId: string) => {\n setComments(prev =>\n prev.map(comment =>\n comment.id === commentId\n ? { ...comment, dislikes: comment.dislikes + 1 }\n : comment\n )\n );\n }, []);\n\n const reportComment = useCallback((commentId: string) => {\n setComments(prev =>\n prev.map(comment =>\n comment.id === commentId\n ? { ...comment, isReported: true }\n : comment\n )\n );\n showToast.info('Comment reported for moderation');\n }, []);\n\n const deleteComment = useCallback((commentId: string) => {\n setComments(prev => prev.filter(comment => comment.id !== commentId));\n showToast.info('Comment deleted');\n }, []);\n\n const getCommentCount = useCallback(() => {\n return comments.length;\n }, [comments.length]);\n\n return {\n comments: organizedComments,\n loading,\n error,\n addComment,\n likeComment,\n dislikeComment,\n reportComment,\n deleteComment,\n getCommentCount,\n };\n};"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from './types';
2
+ export * from './SingleBlogView';
3
+ export * from './AllBlogsView';
4
+ export * from './BlogSidebar';
5
+ export * from './BlogLayout';
6
+ export * from './BlogCommentSection';
7
+ export * from './BlogShowcase';
8
+ export * from './hooks';
@@ -0,0 +1,82 @@
1
+ export interface BlogPost {
2
+ id: string;
3
+ title: string;
4
+ slug: string;
5
+ content: string;
6
+ excerpt: string;
7
+ author: {
8
+ id: string;
9
+ name: string;
10
+ avatar?: string;
11
+ bio?: string;
12
+ };
13
+ publishedAt: string;
14
+ updatedAt?: string;
15
+ tags: string[];
16
+ category: string;
17
+ readingTime: number;
18
+ featured: boolean;
19
+ status: 'draft' | 'published' | 'archived';
20
+ seoMeta: {
21
+ title?: string;
22
+ description?: string;
23
+ keywords?: string[];
24
+ ogImage?: string;
25
+ };
26
+ stats: {
27
+ views: number;
28
+ likes: number;
29
+ comments: number;
30
+ shares: number;
31
+ };
32
+ }
33
+ export interface BlogComment {
34
+ id: string;
35
+ postId: string;
36
+ author: {
37
+ id: string;
38
+ name: string;
39
+ avatar?: string;
40
+ };
41
+ content: string;
42
+ createdAt: string;
43
+ updatedAt?: string;
44
+ parentId?: string;
45
+ likes: number;
46
+ dislikes: number;
47
+ isModerated: boolean;
48
+ isReported: boolean;
49
+ replies?: BlogComment[];
50
+ }
51
+ export interface BlogCategory {
52
+ id: string;
53
+ name: string;
54
+ slug: string;
55
+ description?: string;
56
+ postCount: number;
57
+ color?: string;
58
+ }
59
+ export interface BlogFilters {
60
+ search: string;
61
+ tags: string[];
62
+ categories: string[];
63
+ authors: string[];
64
+ dateRange: {
65
+ start?: string;
66
+ end?: string;
67
+ };
68
+ sortBy: 'newest' | 'oldest' | 'popular' | 'trending';
69
+ }
70
+ export interface BlogPagination {
71
+ page: number;
72
+ limit: number;
73
+ total: number;
74
+ hasNext: boolean;
75
+ hasPrev: boolean;
76
+ }
77
+ export interface TableOfContentsItem {
78
+ id: string;
79
+ title: string;
80
+ level: number;
81
+ anchor: string;
82
+ }
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface CodeHighlightProps {
3
+ code: string;
4
+ language?: string;
5
+ className?: string;
6
+ }
7
+ export declare const CodeHighlight: React.FC<CodeHighlightProps>;
@@ -0,0 +1,18 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import highlighter from '../../node_modules/react-syntax-highlighter/dist/esm/prism.js';
3
+ import vscDarkPlus from '../../node_modules/react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus.js';
4
+
5
+ const CodeHighlight = ({ code, language = "javascript", className = "", }) => {
6
+ return (jsx(highlighter, { language: language, style: vscDarkPlus, customStyle: {
7
+ borderRadius: "0.5rem",
8
+ padding: "1rem",
9
+ fontFamily: "monospace",
10
+ background: "var(--color-primary-50, #2d2d2d)",
11
+ color: "var(--color-primary-700, #f8f8f2)",
12
+ overflowX: "auto",
13
+ }, className: className, showLineNumbers: false, wrapLongLines: true, children: code }));
14
+ };
15
+ CodeHighlight.displayName = "CodeHighlight";
16
+
17
+ export { CodeHighlight };
18
+ //# sourceMappingURL=CodeHighlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeHighlight.js","sources":["../../../src/components/CodeHighlight/CodeHighlight.tsx"],"sourcesContent":["import React from \"react\";\r\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\r\nimport { vscDarkPlus } from \"react-syntax-highlighter/dist/esm/styles/prism\";\r\n\r\nexport interface CodeHighlightProps {\r\n code: string;\r\n language?: string;\r\n className?: string;\r\n}\r\n\r\nexport const CodeHighlight: React.FC<CodeHighlightProps> = ({\r\n code,\r\n language = \"javascript\",\r\n className = \"\",\r\n}) => {\r\n return (\r\n <SyntaxHighlighter\r\n language={language}\r\n style={vscDarkPlus}\r\n customStyle={{\r\n borderRadius: \"0.5rem\",\r\n padding: \"1rem\",\r\n fontFamily: \"monospace\",\r\n background: \"var(--color-primary-50, #2d2d2d)\",\r\n color: \"var(--color-primary-700, #f8f8f2)\",\r\n overflowX: \"auto\",\r\n }}\r\n className={className}\r\n showLineNumbers={false}\r\n wrapLongLines={true}\r\n >\r\n {code}\r\n </SyntaxHighlighter>\r\n );\r\n};\r\n\r\nCodeHighlight.displayName = \"CodeHighlight\";"],"names":["_jsx","SyntaxHighlighter"],"mappings":";;;;AAUO,MAAM,aAAa,GAAiC,CAAC,EAC1D,IAAI,EACJ,QAAQ,GAAG,YAAY,EACvB,SAAS,GAAG,EAAE,GACf,KAAI;AACH,IAAA,QACEA,GAAA,CAACC,WAAiB,EAAA,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE;AACX,YAAA,YAAY,EAAE,QAAQ;AACtB,YAAA,OAAO,EAAE,MAAM;AACf,YAAA,UAAU,EAAE,WAAW;AACvB,YAAA,UAAU,EAAE,kCAAkC;AAC9C,YAAA,KAAK,EAAE,mCAAmC;AAC1C,YAAA,SAAS,EAAE,MAAM;AAClB,SAAA,EACD,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,KAAK,EACtB,aAAa,EAAE,IAAI,EAAA,QAAA,EAElB,IAAI,EAAA,CACa;AAExB;AAEA,aAAa,CAAC,WAAW,GAAG,eAAe;;;;"}
@@ -0,0 +1 @@
1
+ export * from './CodeHighlight';
@@ -2,9 +2,14 @@ import React from 'react';
2
2
  import type { Product, FilterOptions } from './types';
3
3
  interface AllProductsViewProps {
4
4
  products?: Product[];
5
- filters?: FilterOptions;
5
+ filters: FilterOptions;
6
+ searchQuery: string;
7
+ setSearchQuery?: (query: string) => void;
8
+ shouldFocusSearch?: boolean;
6
9
  onProductClick?: (product: Product) => void;
7
10
  onAddToCart?: (product: Product) => void;
11
+ onFiltersChange: (filters: FilterOptions) => void;
12
+ onClearFilters: () => void;
8
13
  }
9
14
  export declare const AllProductsView: React.FC<AllProductsViewProps>;
10
15
  export {};
@@ -1,14 +1,14 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useState, useMemo } from 'react';
3
- import { Search, Grid2x2, List, Filter, Star, ShoppingCart, Heart, Eye } from 'lucide-react';
3
+ import { Search, Star, ShoppingCart } from 'lucide-react';
4
+ import { MarketplaceControls } from './components/MarketplaceControls.js';
4
5
  import { Button } from '../Button/Button.js';
5
- import { Input } from '../Input/Input.js';
6
- import { Card, CardContent } from '../Card/Card.js';
7
6
  import { Badge } from '../Badge/Badge.js';
8
7
  import { Modal, ModalHeader, ModalTitle, ModalContent, ModalFooter } from '../Modal/Modal.js';
9
8
  import { Checkbox } from '../Checkbox/Checkbox.js';
10
9
  import { showToast } from '../Toast/Toast.js';
11
10
  import { sampleProducts } from './data/sampleData.js';
11
+ import { ProductCard } from './components/ProductCard.js';
12
12
 
13
13
  const sortOptions = [
14
14
  { value: 'relevance', label: 'Most Relevant' },
@@ -18,24 +18,16 @@ const sortOptions = [
18
18
  { value: 'newest', label: 'Newest First' },
19
19
  { value: 'popular', label: 'Most Popular' },
20
20
  ];
21
- const AllProductsView = ({ products, filters: filtersProp, onProductClick, onAddToCart, }) => {
21
+ const AllProductsView = ({ products, filters: filtersProp, searchQuery, setSearchQuery, shouldFocusSearch, onProductClick, onAddToCart, onFiltersChange, onClearFilters, }) => {
22
22
  const productsData = products ?? sampleProducts;
23
- const [searchQuery, setSearchQuery] = useState('');
24
23
  const [sortBy, setSortBy] = useState('relevance');
25
24
  const [viewMode, setViewMode] = useState('grid');
26
25
  const [currentPage, setCurrentPage] = useState(1);
27
26
  const [showFilters, setShowFilters] = useState(false);
28
27
  const [quickViewProduct, setQuickViewProduct] = useState(null);
29
28
  const [wishlist, setWishlist] = useState(new Set());
30
- // Use prop filters if provided, otherwise fallback to internal state
31
- const [filters, setFilters] = useState(filtersProp ?? {
32
- categories: [],
33
- brands: [],
34
- priceRange: [0, 1000],
35
- rating: 0,
36
- inStock: false,
37
- vendors: [],
38
- });
29
+ // Use filters and handlers from props only
30
+ const filters = filtersProp;
39
31
  const itemsPerPage = 12;
40
32
  // Get unique filter options from products
41
33
  const filterOptions = useMemo(() => {
@@ -106,22 +98,15 @@ const AllProductsView = ({ products, filters: filtersProp, onProductClick, onAdd
106
98
  }, [filteredProducts, currentPage]);
107
99
  const totalPages = Math.ceil(filteredProducts.length / itemsPerPage);
108
100
  const handleFilterChange = (filterType, value) => {
109
- setFilters(prev => ({
110
- ...prev,
101
+ const newFilters = {
102
+ ...filters,
111
103
  [filterType]: value,
112
- }));
104
+ };
105
+ onFiltersChange(newFilters);
113
106
  setCurrentPage(1); // Reset to first page when filters change
114
107
  };
115
108
  const handleClearFilters = () => {
116
- setFilters({
117
- categories: [],
118
- brands: [],
119
- priceRange: [0, 1000],
120
- rating: 0,
121
- inStock: false,
122
- vendors: [],
123
- });
124
- setSearchQuery('');
109
+ onClearFilters();
125
110
  setCurrentPage(1);
126
111
  };
127
112
  const toggleWishlist = (productId) => {
@@ -142,45 +127,37 @@ const AllProductsView = ({ products, filters: filtersProp, onProductClick, onAdd
142
127
  onAddToCart?.(product);
143
128
  showToast.success(`${product.name} added to cart!`);
144
129
  };
145
- const ProductCard = ({ product }) => (jsxs(Card, { className: "group hover:shadow-lg transition-all duration-300", children: [jsxs("div", { className: "relative aspect-square bg-gray-100 rounded-t-lg overflow-hidden", children: [jsx("img", { src: product.images[0], alt: product.name, className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" }), product.discount && (jsxs(Badge, { variant: "danger", className: "absolute top-2 left-2", children: ["-", product.discount, "%"] })), jsx("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity", children: jsx(Button, { variant: "ghost", size: "sm", onClick: (e) => {
146
- e.stopPropagation();
147
- toggleWishlist(product.id);
148
- }, className: "bg-white/80 hover:bg-white", children: jsx(Heart, { className: `h-4 w-4 ${wishlist.has(product.id) ? 'fill-current text-red-500' : ''}` }) }) }), jsx("div", { className: "absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity", children: jsx(Button, { variant: "ghost", size: "sm", onClick: (e) => {
149
- e.stopPropagation();
150
- setQuickViewProduct(product);
151
- }, className: "bg-white/80 hover:bg-white", children: jsx(Eye, { className: "h-4 w-4" }) }) }), !product.inStock && (jsx("div", { className: "absolute inset-0 bg-black/50 flex items-center justify-center", children: jsx(Badge, { variant: "secondary", children: "Out of Stock" }) }))] }), jsxs(CardContent, { className: "p-4", children: [jsxs("div", { className: "mb-2", children: [jsx("h3", { className: "font-medium text-gray-900 line-clamp-2 cursor-pointer hover:text-primary-600", onClick: () => onProductClick?.(product), children: product.name }), jsx("p", { className: "text-sm text-gray-600", children: product.brand })] }), jsxs("div", { className: "flex items-center space-x-1 mb-2", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsxs("span", { className: "text-sm text-gray-600", children: [product.rating, " (", product.reviewCount, ")"] })] }), jsx("div", { className: "flex items-center justify-between mb-3", children: jsxs("div", { className: "flex items-center space-x-2", children: [jsxs("span", { className: "text-lg font-bold text-gray-900", children: ["$", product.price.toFixed(2)] }), product.originalPrice && (jsxs("span", { className: "text-sm text-gray-500 line-through", children: ["$", product.originalPrice.toFixed(2)] }))] }) }), jsxs(Button, { variant: "primary", size: "sm", onClick: (e) => {
152
- e.stopPropagation();
153
- handleAddToCart(product);
154
- }, disabled: !product.inStock, className: "w-full", children: [jsx(ShoppingCart, { className: "mr-2 h-4 w-4" }), "Add to Cart"] })] })] }));
155
- return (jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [jsxs("div", { className: "flex flex-col lg:flex-row lg:items-center lg:justify-between mb-8", children: [jsxs("div", { children: [jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-2", children: "All Products" }), jsxs("p", { className: "text-gray-600", children: ["Showing ", filteredProducts.length, " of ", productsData.length, " products"] })] }), jsxs("div", { className: "flex items-center space-x-4 mt-4 lg:mt-0", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { placeholder: "Search products...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "pl-10 w-64" })] }), jsx("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "border border-gray-300 rounded-lg px-3 py-2 bg-white", children: sortOptions.map(option => (jsx("option", { value: option.value, children: option.label }, option.value))) }), jsxs("div", { className: "flex items-center bg-gray-100 rounded-lg p-1", children: [jsx(Button, { variant: viewMode === 'grid' ? 'primary' : 'ghost', size: "sm", onClick: () => setViewMode('grid'), children: jsx(Grid2x2, { className: "h-4 w-4" }) }), jsx(Button, { variant: viewMode === 'list' ? 'primary' : 'ghost', size: "sm", onClick: () => setViewMode('list'), children: jsx(List, { className: "h-4 w-4" }) })] }), jsxs(Button, { variant: "outline", onClick: () => setShowFilters(true), className: "lg:hidden", children: [jsx(Filter, { className: "mr-2 h-4 w-4" }), "Filters"] })] })] }), jsxs("div", { className: "flex gap-8", children: [jsx("div", { className: "hidden lg:block w-64 flex-shrink-0", children: jsx(Card, { className: "sticky top-4", children: jsxs(CardContent, { className: "p-6", children: [jsxs("div", { className: "flex items-center justify-between mb-4", children: [jsx("h3", { className: "font-semibold text-gray-900", children: "Filters" }), jsx(Button, { variant: "ghost", size: "sm", onClick: handleClearFilters, children: "Clear All" })] }), jsxs("div", { className: "mb-6", children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Categories" }), jsx("div", { className: "space-y-2", children: filterOptions.categories.map((category, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.categories.includes(category), onChange: (e) => {
156
- const newCategories = e.target.checked
157
- ? [...filters.categories, category]
158
- : filters.categories.filter((c) => c !== category);
159
- handleFilterChange('categories', newCategories);
160
- } }), jsx("span", { className: "text-sm text-gray-700", children: category })] }, category))) })] }), jsxs("div", { className: "mb-6", children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Brands" }), jsx("div", { className: "space-y-2", children: filterOptions.brands.map((brand, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.brands.includes(brand), onChange: (e) => {
161
- const newBrands = e.target.checked
162
- ? [...filters.brands, brand]
163
- : filters.brands.filter((b) => b !== brand);
164
- handleFilterChange('brands', newBrands);
165
- } }), jsx("span", { className: "text-sm text-gray-700", children: brand })] }, brand))) })] }), jsxs("div", { className: "mb-6", children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Price Range" }), jsx("div", { className: "space-y-2", children: jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Input, { type: "number", placeholder: "Min", value: filters.priceRange[0], onChange: (e) => handleFilterChange('priceRange', [
166
- parseInt(e.target.value) || 0,
167
- filters.priceRange[1]
168
- ]), className: "w-20" }), jsx("span", { children: "-" }), jsx(Input, { type: "number", placeholder: "Max", value: filters.priceRange[1], onChange: (e) => handleFilterChange('priceRange', [
169
- filters.priceRange[0],
170
- parseInt(e.target.value) || 1000
171
- ]), className: "w-20" })] }) })] }), jsxs("div", { className: "mb-6", children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Minimum Rating" }), jsx("div", { className: "space-y-2", children: [4, 3, 2, 1].map(rating => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.rating === rating, onChange: (e) => {
172
- handleFilterChange('rating', e.target.checked ? rating : 0);
173
- } }), jsxs("div", { className: "flex items-center space-x-1", children: [[1, 2, 3, 4, 5].map(star => (jsx(Star, { className: `h-4 w-4 ${star <= rating ? 'text-yellow-400 fill-current' : 'text-gray-300'}` }, star))), jsx("span", { className: "text-sm text-gray-700", children: "& up" })] })] }, rating))) })] }), jsx("div", { className: "mb-6", children: jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.inStock, onChange: (e) => handleFilterChange('inStock', e.target.checked) }), jsx("span", { className: "text-sm text-gray-700", children: "In Stock Only" })] }) })] }) }) }), jsx("div", { className: "flex-1", children: paginatedProducts.length === 0 ? (jsxs("div", { className: "text-center py-12", children: [jsx("div", { className: "text-gray-400 mb-4", children: jsx(Search, { className: "h-16 w-16 mx-auto" }) }), jsx("h3", { className: "text-lg font-medium text-gray-900 mb-2", children: "No products found" }), jsx("p", { className: "text-gray-600 mb-4", children: "Try adjusting your search or filter criteria" }), jsx(Button, { variant: "outline", onClick: handleClearFilters, children: "Clear Filters" })] })) : (jsxs(Fragment, { children: [jsx("div", { className: `grid gap-6 ${viewMode === 'grid'
174
- ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
175
- : 'grid-cols-1'}`, children: paginatedProducts.map((product) => (jsx(ProductCard, { product: product }, product.id))) }), totalPages > 1 && (jsxs("div", { className: "flex items-center justify-center space-x-2 mt-12", children: [jsx(Button, { variant: "outline", onClick: () => setCurrentPage(prev => Math.max(1, prev - 1)), disabled: currentPage === 1, children: "Previous" }), Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
176
- const page = i + 1;
177
- return (jsx(Button, { variant: currentPage === page ? 'primary' : 'outline', onClick: () => setCurrentPage(page), children: page }, page));
178
- }), jsx(Button, { variant: "outline", onClick: () => setCurrentPage(prev => Math.min(totalPages, prev + 1)), disabled: currentPage === totalPages, children: "Next" })] }))] })) })] }), jsxs(Modal, { open: showFilters, onOpenChange: setShowFilters, children: [jsx(ModalHeader, { children: jsx(ModalTitle, { children: "Filters" }) }), jsx(ModalContent, { children: jsx("div", { className: "space-y-6", children: jsxs("div", { children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Categories" }), jsx("div", { className: "space-y-2", children: filterOptions.categories.map((category, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.categories.includes(category), onChange: (e) => {
179
- const newCategories = e.target.checked
180
- ? [...filters.categories, category]
181
- : filters.categories.filter((c) => c !== category);
182
- handleFilterChange('categories', newCategories);
183
- } }), jsx("span", { className: "text-sm text-gray-700", children: category })] }, category))) })] }) }) }), jsxs(ModalFooter, { children: [jsx(Button, { variant: "outline", onClick: handleClearFilters, children: "Clear All" }), jsx(Button, { variant: "primary", onClick: () => setShowFilters(false), children: "Apply Filters" })] })] }), jsx(Modal, { open: !!quickViewProduct, onOpenChange: () => setQuickViewProduct(null), size: "lg", children: quickViewProduct && (jsxs(Fragment, { children: [jsx(ModalHeader, { children: jsx(ModalTitle, { children: quickViewProduct.name }) }), jsx(ModalContent, { children: jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [jsx("div", { className: "aspect-square bg-gray-100 rounded-lg overflow-hidden", children: jsx("img", { src: quickViewProduct.images[0], alt: quickViewProduct.name, className: "w-full h-full object-cover" }) }), jsxs("div", { children: [jsxs("div", { className: "flex items-center space-x-1 mb-2", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsxs("span", { className: "text-sm text-gray-600", children: [quickViewProduct.rating, " (", quickViewProduct.reviewCount, " reviews)"] })] }), jsxs("div", { className: "flex items-center space-x-2 mb-4", children: [jsxs("span", { className: "text-2xl font-bold text-gray-900", children: ["$", quickViewProduct.price.toFixed(2)] }), quickViewProduct.originalPrice && (jsxs("span", { className: "text-lg text-gray-500 line-through", children: ["$", quickViewProduct.originalPrice.toFixed(2)] }))] }), jsx("p", { className: "text-gray-600 mb-4", children: quickViewProduct.description }), jsx(Badge, { variant: quickViewProduct.inStock ? 'success' : 'danger', className: "mb-4", children: quickViewProduct.inStock ? 'In Stock' : 'Out of Stock' })] })] }) }), jsxs(ModalFooter, { children: [jsx(Button, { variant: "outline", onClick: () => onProductClick?.(quickViewProduct), children: "View Details" }), jsxs(Button, { variant: "primary", onClick: () => handleAddToCart(quickViewProduct), disabled: !quickViewProduct.inStock, children: [jsx(ShoppingCart, { className: "mr-2 h-4 w-4" }), "Add to Cart"] })] })] })) })] }));
130
+ // Remove local ProductCard in favor of reusable ProductCard
131
+ return (jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [jsxs("div", { className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between mb-8", children: [jsxs("div", { children: [jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-2", children: "All Products" }), jsxs("p", { className: "text-gray-600", children: ["Showing ", filteredProducts.length, " of ", productsData.length, " products"] })] }), jsx(MarketplaceControls, { searchQuery: searchQuery, onSearchChange: setSearchQuery ? setSearchQuery : () => { }, shouldFocusSearch: shouldFocusSearch, sortBy: sortBy, onSortChange: setSortBy, viewMode: viewMode, onViewModeChange: setViewMode, onShowFilters: () => setShowFilters(true), sortOptions: sortOptions })] }), jsx("div", { className: "flex gap-8", children: jsx("div", { className: "flex-1", children: paginatedProducts.length === 0 ? (jsxs("div", { className: "text-center py-12", children: [jsx("div", { className: "text-gray-400 mb-4", children: jsx(Search, { className: "h-16 w-16 mx-auto" }) }), jsx("h3", { className: "text-lg font-medium text-gray-900 mb-2", children: "No products found" }), jsx("p", { className: "text-gray-600 mb-4", children: "Try adjusting your search or filter criteria" }), jsx(Button, { variant: "outline", onClick: handleClearFilters, children: "Clear Filters" })] })) : (jsxs(Fragment, { children: [jsx("div", { className: `grid gap-3 sm:gap-6 ${viewMode === 'grid'
132
+ ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
133
+ : 'grid-cols-1'}`, children: paginatedProducts.map((product) => (jsx("div", { className: "w-full max-w-xs mx-auto sm:max-w-none", children: jsx(ProductCard, { product: product, onProductClick: onProductClick, onAddToCart: handleAddToCart, onQuickView: () => setQuickViewProduct(product), onToggleWishlist: toggleWishlist, isWishlisted: wishlist.has(product.id), showQuickActions: true }) }, product.id))) }), totalPages > 1 && (jsxs("div", { className: "flex flex-wrap items-center justify-center gap-2 mt-8 sm:mt-12", children: [jsx(Button, { variant: "outline", onClick: () => setCurrentPage(prev => Math.max(1, prev - 1)), disabled: currentPage === 1, children: "Previous" }), Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
134
+ const page = i + 1;
135
+ return (jsx(Button, { variant: currentPage === page ? 'primary' : 'outline', onClick: () => setCurrentPage(page), children: page }, page));
136
+ }), jsx(Button, { variant: "outline", onClick: () => setCurrentPage(prev => Math.min(totalPages, prev + 1)), disabled: currentPage === totalPages, children: "Next" })] }))] })) }) }), jsxs(Modal, { open: showFilters, onOpenChange: setShowFilters, children: [jsx(ModalHeader, { children: jsx(ModalTitle, { children: "Filters" }) }), jsx(ModalContent, { children: jsxs("div", { className: "space-y-6", children: [jsxs("div", { children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Categories" }), jsx("div", { className: "space-y-2", children: filterOptions.categories.map((category, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.categories.includes(category), onChange: (e) => {
137
+ const alreadyChecked = filters.categories.includes(category);
138
+ const newCategories = e.target.checked
139
+ ? alreadyChecked
140
+ ? filters.categories
141
+ : [...filters.categories, category]
142
+ : filters.categories.filter((c) => c !== category);
143
+ handleFilterChange('categories', newCategories);
144
+ } }), jsx("span", { className: "text-sm text-gray-700", children: category })] }, category))) })] }), jsxs("div", { children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Brands" }), jsx("div", { className: "space-y-2", children: filterOptions.brands.map((brand, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.brands.includes(brand), onChange: (e) => {
145
+ const alreadyChecked = filters.brands.includes(brand);
146
+ const newBrands = e.target.checked
147
+ ? alreadyChecked
148
+ ? filters.brands
149
+ : [...filters.brands, brand]
150
+ : filters.brands.filter((b) => b !== brand);
151
+ handleFilterChange('brands', newBrands);
152
+ } }), jsx("span", { className: "text-sm text-gray-700", children: brand })] }, brand))) })] }), jsxs("div", { children: [jsx("h4", { className: "font-medium text-gray-900 mb-3", children: "Vendors" }), jsx("div", { className: "space-y-2", children: filterOptions.vendors.map((vendor, idx) => (jsxs("label", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { checked: filters.vendors.includes(vendor), onChange: (e) => {
153
+ const alreadyChecked = filters.vendors.includes(vendor);
154
+ const newVendors = e.target.checked
155
+ ? alreadyChecked
156
+ ? filters.vendors
157
+ : [...filters.vendors, vendor]
158
+ : filters.vendors.filter((v) => v !== vendor);
159
+ handleFilterChange('vendors', newVendors);
160
+ } }), jsx("span", { className: "text-sm text-gray-700", children: vendor })] }, vendor))) })] })] }) }), jsxs(ModalFooter, { children: [jsx(Button, { variant: "outline", onClick: handleClearFilters, children: "Clear All" }), jsx(Button, { variant: "primary", onClick: () => setShowFilters(false), children: "Apply Filters" })] })] }), jsx(Modal, { open: !!quickViewProduct, onOpenChange: () => setQuickViewProduct(null), size: "lg", children: quickViewProduct && (jsxs(Fragment, { children: [jsx(ModalHeader, { children: jsx(ModalTitle, { children: quickViewProduct.name }) }), jsx(ModalContent, { children: jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [jsx("div", { className: "aspect-square bg-gray-100 rounded-lg overflow-hidden", children: jsx("img", { src: quickViewProduct.images[0], alt: quickViewProduct.name, className: "w-full h-full object-cover" }) }), jsxs("div", { children: [jsxs("div", { className: "flex items-center space-x-1 mb-2", children: [jsx(Star, { className: "h-4 w-4 text-yellow-400 fill-current" }), jsxs("span", { className: "text-sm text-gray-600", children: [quickViewProduct.rating, " (", quickViewProduct.reviewCount, " reviews)"] })] }), jsxs("div", { className: "flex items-center space-x-2 mb-4", children: [jsxs("span", { className: "text-2xl font-bold text-gray-900", children: ["$", quickViewProduct.price.toFixed(2)] }), quickViewProduct.originalPrice && (jsxs("span", { className: "text-lg text-gray-500 line-through", children: ["$", quickViewProduct.originalPrice.toFixed(2)] }))] }), jsx("p", { className: "text-gray-600 mb-4", children: quickViewProduct.description }), jsx(Badge, { variant: quickViewProduct.inStock ? 'success' : 'danger', className: "mb-4", children: quickViewProduct.inStock ? 'In Stock' : 'Out of Stock' })] })] }) }), jsxs(ModalFooter, { children: [jsx(Button, { variant: "outline", onClick: () => onProductClick?.(quickViewProduct), children: "View Details" }), jsxs(Button, { variant: "primary", onClick: () => handleAddToCart(quickViewProduct), disabled: !quickViewProduct.inStock, children: [jsx(ShoppingCart, { className: "mr-2 h-4 w-4" }), "Add to Cart"] })] })] })) })] }));
184
161
  };
185
162
 
186
163
  export { AllProductsView };