@beyondcorp/beyond-ui 1.2.53 → 1.2.57
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/components/Blog/AllBlogsView.d.ts +8 -0
- package/dist/components/Blog/AllBlogsView.js +70 -0
- package/dist/components/Blog/AllBlogsView.js.map +1 -0
- package/dist/components/Blog/BlogCommentSection.d.ts +7 -0
- package/dist/components/Blog/BlogCommentSection.js +66 -0
- package/dist/components/Blog/BlogCommentSection.js.map +1 -0
- package/dist/components/Blog/BlogLayout.d.ts +11 -0
- package/dist/components/Blog/BlogLayout.js +29 -0
- package/dist/components/Blog/BlogLayout.js.map +1 -0
- package/dist/components/Blog/BlogShowcase.d.ts +2 -0
- package/dist/components/Blog/BlogShowcase.js +74 -0
- package/dist/components/Blog/BlogShowcase.js.map +1 -0
- package/dist/components/Blog/BlogSidebar.d.ts +10 -0
- package/dist/components/Blog/BlogSidebar.js +47 -0
- package/dist/components/Blog/BlogSidebar.js.map +1 -0
- package/dist/components/Blog/SingleBlogView.d.ts +8 -0
- package/dist/components/Blog/SingleBlogView.js +78 -0
- package/dist/components/Blog/SingleBlogView.js.map +1 -0
- package/dist/components/Blog/data/sampleData.d.ts +4 -0
- package/dist/components/Blog/data/sampleData.js +388 -0
- package/dist/components/Blog/data/sampleData.js.map +1 -0
- package/dist/components/Blog/hooks/index.d.ts +3 -0
- package/dist/components/Blog/hooks/useBlog.d.ts +22 -0
- package/dist/components/Blog/hooks/useBlog.js +148 -0
- package/dist/components/Blog/hooks/useBlog.js.map +1 -0
- package/dist/components/Blog/hooks/useBlogNavigation.d.ts +12 -0
- package/dist/components/Blog/hooks/useBlogNavigation.js +75 -0
- package/dist/components/Blog/hooks/useBlogNavigation.js.map +1 -0
- package/dist/components/Blog/hooks/useComments.d.ts +20 -0
- package/dist/components/Blog/hooks/useComments.js +108 -0
- package/dist/components/Blog/hooks/useComments.js.map +1 -0
- package/dist/components/Blog/index.d.ts +8 -0
- package/dist/components/Blog/types.d.ts +82 -0
- package/dist/components/CodeHighlight/CodeHighlight.d.ts +7 -0
- package/dist/components/CodeHighlight/CodeHighlight.js +18 -0
- package/dist/components/CodeHighlight/CodeHighlight.js.map +1 -0
- package/dist/components/CodeHighlight/index.d.ts +1 -0
- package/dist/components/Marketplace/AllProductsView.d.ts +3 -0
- package/dist/components/Marketplace/AllProductsView.js +7 -18
- package/dist/components/Marketplace/AllProductsView.js.map +1 -1
- package/dist/components/Marketplace/MarketplaceComponent.js +5 -1
- package/dist/components/Marketplace/MarketplaceComponent.js.map +1 -1
- package/dist/components/Marketplace/MarketplaceSidebar.js +31 -31
- package/dist/components/Marketplace/MarketplaceSidebar.js.map +1 -1
- package/dist/components/Marketplace/SingleProductView.js +3 -0
- package/dist/components/Marketplace/SingleProductView.js.map +1 -1
- package/dist/components/Marketplace/components/MarketplaceControls.d.ts +17 -0
- package/dist/components/Marketplace/components/MarketplaceControls.js +22 -0
- package/dist/components/Marketplace/components/MarketplaceControls.js.map +1 -0
- package/dist/components/Marketplace/components/MarketplaceDashboard.d.ts +3 -0
- package/dist/components/Marketplace/components/MarketplaceDashboard.js +20 -10
- package/dist/components/Marketplace/components/MarketplaceDashboard.js.map +1 -1
- package/dist/components/Marketplace/components/MarketplaceHeader.js +2 -3
- package/dist/components/Marketplace/components/MarketplaceHeader.js.map +1 -1
- package/dist/components/Marketplace/components/ProductCard.js +9 -2
- package/dist/components/Marketplace/components/ProductCard.js.map +1 -1
- package/dist/components/Marketplace/hooks/useScrollToTop.d.ts +10 -0
- package/dist/components/Marketplace/hooks/useScrollToTop.js +22 -0
- package/dist/components/Marketplace/hooks/useScrollToTop.js.map +1 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +10 -4
- package/dist/styles.css +1 -1
- package/package.json +6 -1
- package/dist/components/AllProductsView/AllProductsView.d.ts +0 -14
- package/dist/components/AllProductsView/AllProductsView.js +0 -61
- package/dist/components/AllProductsView/AllProductsView.js.map +0 -1
- package/dist/components/AllProductsView/CardGroup.d.ts +0 -6
- package/dist/components/AllProductsView/CardGroup.js +0 -11
- package/dist/components/AllProductsView/CardGroup.js.map +0 -1
- package/dist/components/AllProductsView/ProductCard.d.ts +0 -11
- package/dist/components/AllProductsView/ProductCard.js +0 -13
- package/dist/components/AllProductsView/ProductCard.js.map +0 -1
- package/dist/components/AllProductsView/index.d.ts +0 -2
- package/dist/components/BlogFeedView/BlogFeedView.d.ts +0 -22
- package/dist/components/BlogFeedView/BlogFeedView.js +0 -29
- package/dist/components/BlogFeedView/BlogFeedView.js.map +0 -1
- package/dist/components/BlogFeedView/index.d.ts +0 -1
- package/dist/components/BlogLayout/BlogLayout.d.ts +0 -13
- package/dist/components/BlogLayout/BlogLayout.js +0 -20
- package/dist/components/BlogLayout/BlogLayout.js.map +0 -1
- package/dist/components/BlogLayout/index.d.ts +0 -1
- package/dist/components/BlogSidebar/BlogSidebar.d.ts +0 -19
- package/dist/components/BlogSidebar/BlogSidebar.js +0 -10
- package/dist/components/BlogSidebar/BlogSidebar.js.map +0 -1
- package/dist/components/BlogSidebar/index.d.ts +0 -1
- package/dist/components/Checkout/CheckoutPage.d.ts +0 -16
- package/dist/components/Checkout/CheckoutPage.js +0 -44
- package/dist/components/Checkout/CheckoutPage.js.map +0 -1
- package/dist/components/Checkout/CheckoutSidebar.d.ts +0 -15
- package/dist/components/Checkout/CheckoutSidebar.js +0 -25
- package/dist/components/Checkout/CheckoutSidebar.js.map +0 -1
- package/dist/components/Checkout/index.d.ts +0 -3
- package/dist/components/Checkout/types.d.ts +0 -21
- package/dist/components/CommerceSidebar/CommerceSidebar.d.ts +0 -20
- package/dist/components/CommerceSidebar/CommerceSidebar.js +0 -14
- package/dist/components/CommerceSidebar/CommerceSidebar.js.map +0 -1
- package/dist/components/CommerceSidebar/index.d.ts +0 -1
- package/dist/components/MarketplaceLayout/MarketplaceLayout.d.ts +0 -17
- package/dist/components/MarketplaceLayout/MarketplaceLayout.js +0 -22
- package/dist/components/MarketplaceLayout/MarketplaceLayout.js.map +0 -1
- package/dist/components/MarketplaceLayout/index.d.ts +0 -1
- package/dist/components/ProfileManagement/ProfileManagementPage.d.ts +0 -16
- package/dist/components/ProfileManagement/ProfileManagementPage.js +0 -65
- package/dist/components/ProfileManagement/ProfileManagementPage.js.map +0 -1
- package/dist/components/SingleBlogView/SingleBlogView.d.ts +0 -26
- package/dist/components/SingleBlogView/SingleBlogView.js +0 -17
- package/dist/components/SingleBlogView/SingleBlogView.js.map +0 -1
- package/dist/components/SingleBlogView/index.d.ts +0 -1
- package/dist/components/SingleProductView/SingleProductView.d.ts +0 -31
- package/dist/components/SingleProductView/SingleProductView.js +0 -34
- package/dist/components/SingleProductView/SingleProductView.js.map +0 -1
- 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,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,18 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Prism } from 'react-syntax-highlighter';
|
|
3
|
+
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
|
4
|
+
|
|
5
|
+
const CodeHighlight = ({ code, language = "javascript", className = "", }) => {
|
|
6
|
+
return (jsx(Prism, { 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,KAAiB,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';
|
|
@@ -3,6 +3,9 @@ import type { Product, FilterOptions } from './types';
|
|
|
3
3
|
interface AllProductsViewProps {
|
|
4
4
|
products?: Product[];
|
|
5
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;
|
|
8
11
|
onFiltersChange: (filters: FilterOptions) => void;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { useState, useMemo } from 'react';
|
|
3
|
-
import { Search,
|
|
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,9 +18,8 @@ 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, onFiltersChange, onClearFilters, }) => {
|
|
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);
|
|
@@ -108,7 +107,6 @@ const AllProductsView = ({ products, filters: filtersProp, onProductClick, onAdd
|
|
|
108
107
|
};
|
|
109
108
|
const handleClearFilters = () => {
|
|
110
109
|
onClearFilters();
|
|
111
|
-
setSearchQuery('');
|
|
112
110
|
setCurrentPage(1);
|
|
113
111
|
};
|
|
114
112
|
const toggleWishlist = (productId) => {
|
|
@@ -129,19 +127,10 @@ const AllProductsView = ({ products, filters: filtersProp, onProductClick, onAdd
|
|
|
129
127
|
onAddToCart?.(product);
|
|
130
128
|
showToast.success(`${product.name} added to cart!`);
|
|
131
129
|
};
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
toggleWishlist(product.id);
|
|
135
|
-
}, 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) => {
|
|
136
|
-
e.stopPropagation();
|
|
137
|
-
setQuickViewProduct(product);
|
|
138
|
-
}, 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) => {
|
|
139
|
-
e.stopPropagation();
|
|
140
|
-
handleAddToCart(product);
|
|
141
|
-
}, disabled: !product.inStock, className: "w-full", children: [jsx(ShoppingCart, { className: "mr-2 h-4 w-4" }), "Add to Cart"] })] })] }));
|
|
142
|
-
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"] })] })] }), 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-6 ${viewMode === 'grid'
|
|
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'
|
|
143
132
|
? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
|
|
144
|
-
: 'grid-cols-1'}`, children: paginatedProducts.map((product) => (jsx(ProductCard, { product: product }, product.id))) }), totalPages > 1 && (jsxs("div", { className: "flex items-center justify-center
|
|
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) => {
|
|
145
134
|
const page = i + 1;
|
|
146
135
|
return (jsx(Button, { variant: currentPage === page ? 'primary' : 'outline', onClick: () => setCurrentPage(page), children: page }, page));
|
|
147
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) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AllProductsView.js","sources":["../../../src/components/Marketplace/AllProductsView.tsx"],"sourcesContent":["import React, { useState, useMemo } from 'react';\nimport { Search, Filter, Grid2x2 as Grid, List, Star, Heart, ShoppingCart, Eye, ChevronDown, X } from 'lucide-react';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\nimport { Card, CardContent } from '../Card';\nimport { Badge } from '../Badge';\nimport { Modal, ModalHeader, ModalTitle, ModalContent, ModalFooter } from '../Modal';\nimport { Checkbox } from '../Checkbox';\nimport { showToast } from '../Toast';\nimport type { Product, FilterOptions, SortOption } from './types';\nimport { sampleProducts } from './data/sampleData';\n\ninterface AllProductsViewProps {\n products?: Product[];\n filters: FilterOptions;\n onProductClick?: (product: Product) => void;\n onAddToCart?: (product: Product) => void;\n onFiltersChange: (filters: FilterOptions) => void;\n onClearFilters: () => void;\n}\n\nconst sortOptions: SortOption[] = [\n { value: 'relevance', label: 'Most Relevant' },\n { value: 'price-low', label: 'Price: Low to High' },\n { value: 'price-high', label: 'Price: High to Low' },\n { value: 'rating', label: 'Highest Rated' },\n { value: 'newest', label: 'Newest First' },\n { value: 'popular', label: 'Most Popular' },\n];\n\nexport const AllProductsView: React.FC<AllProductsViewProps> = ({\n products,\n filters: filtersProp,\n onProductClick,\n onAddToCart,\n onFiltersChange,\n onClearFilters,\n}) => {\n const productsData = products ?? sampleProducts;\n const [searchQuery, setSearchQuery] = useState('');\n const [sortBy, setSortBy] = useState('relevance');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [currentPage, setCurrentPage] = useState(1);\n const [showFilters, setShowFilters] = useState(false);\n const [quickViewProduct, setQuickViewProduct] = useState<Product | null>(null);\n const [wishlist, setWishlist] = useState<Set<string>>(new Set());\n\n // Use filters and handlers from props only\n const filters = filtersProp;\n\n const itemsPerPage = 12;\n\n // Get unique filter options from products\n const filterOptions = useMemo(() => {\n const categories = [...new Set(productsData.map((p: Product) => p.category))];\n const brands = [...new Set(productsData.map((p: Product) => p.brand))];\n const vendors = [...new Set(productsData.map((p: Product) => p.vendor.name))];\n\n return { categories, brands, vendors };\n }, [productsData]);\n\n // Filter and sort products\n const filteredProducts = useMemo(() => {\n let filtered = productsData.filter((product: Product) => {\n // Search query\n if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase()) &&\n !product.description.toLowerCase().includes(searchQuery.toLowerCase())) {\n return false;\n }\n\n // Category filter\n if (filters.categories.length > 0 && !filters.categories.includes(product.category)) {\n return false;\n }\n\n // Brand filter\n if (filters.brands.length > 0 && !filters.brands.includes(product.brand)) {\n return false;\n }\n\n // Price range\n if (product.price < filters.priceRange[0] || product.price > filters.priceRange[1]) {\n return false;\n }\n\n // Rating filter\n if (filters.rating > 0 && product.rating < filters.rating) {\n return false;\n }\n\n // In stock filter\n if (filters.inStock && !product.inStock) {\n return false;\n }\n\n // Vendor filter\n if (filters.vendors.length > 0 && !filters.vendors.includes(product.vendor.name)) {\n return false;\n }\n\n return true;\n });\n\n // Sort products\n switch (sortBy) {\n case 'price-low':\n filtered.sort((a: Product, b: Product) => a.price - b.price);\n break;\n case 'price-high':\n filtered.sort((a: Product, b: Product) => b.price - a.price);\n break;\n case 'rating':\n filtered.sort((a: Product, b: Product) => b.rating - a.rating);\n break;\n case 'newest':\n // Assuming newer products have higher IDs\n filtered.sort((a: Product, b: Product) => parseInt(b.id) - parseInt(a.id));\n break;\n case 'popular':\n filtered.sort((a: Product, b: Product) => b.reviewCount - a.reviewCount);\n break;\n default:\n // Keep original order for relevance\n break;\n }\n\n return filtered;\n }, [productsData, searchQuery, filters, sortBy]);\n\n // Paginate products\n const paginatedProducts = useMemo(() => {\n const startIndex = (currentPage - 1) * itemsPerPage;\n return filteredProducts.slice(startIndex, startIndex + itemsPerPage);\n }, [filteredProducts, currentPage]);\n\n const totalPages = Math.ceil(filteredProducts.length / itemsPerPage);\n\n const handleFilterChange = (filterType: keyof FilterOptions, value: any) => {\n const newFilters = {\n ...filters,\n [filterType]: value,\n };\n onFiltersChange(newFilters);\n setCurrentPage(1); // Reset to first page when filters change\n };\n\n const handleClearFilters = () => {\n onClearFilters();\n setSearchQuery('');\n setCurrentPage(1);\n };\n\n const toggleWishlist = (productId: string) => {\n setWishlist(prev => {\n const newWishlist = new Set(prev);\n if (newWishlist.has(productId)) {\n newWishlist.delete(productId);\n showToast.info('Removed from wishlist');\n } else {\n newWishlist.add(productId);\n showToast.success('Added to wishlist');\n }\n return newWishlist;\n });\n };\n\n const handleAddToCart = (product: Product) => {\n onAddToCart?.(product);\n showToast.success(`${product.name} added to cart!`);\n };\n\n const ProductCard: React.FC<{ product: Product }> = ({ product }) => (\n <Card className=\"group hover:shadow-lg transition-all duration-300\">\n <div className=\"relative aspect-square bg-gray-100 rounded-t-lg overflow-hidden\">\n <img\n src={product.images[0]}\n alt={product.name}\n className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300\"\n />\n {product.discount && (\n <Badge variant=\"danger\" className=\"absolute top-2 left-2\">\n -{product.discount}%\n </Badge>\n )}\n <div className=\"absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n toggleWishlist(product.id);\n }}\n className=\"bg-white/80 hover:bg-white\"\n >\n <Heart className={`h-4 w-4 ${wishlist.has(product.id) ? 'fill-current text-red-500' : ''}`} />\n </Button>\n </div>\n <div className=\"absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n setQuickViewProduct(product);\n }}\n className=\"bg-white/80 hover:bg-white\"\n >\n <Eye className=\"h-4 w-4\" />\n </Button>\n </div>\n {!product.inStock && (\n <div className=\"absolute inset-0 bg-black/50 flex items-center justify-center\">\n <Badge variant=\"secondary\">Out of Stock</Badge>\n </div>\n )}\n </div>\n <CardContent className=\"p-4\">\n <div className=\"mb-2\">\n <h3 \n className=\"font-medium text-gray-900 line-clamp-2 cursor-pointer hover:text-primary-600\"\n onClick={() => onProductClick?.(product)}\n >\n {product.name}\n </h3>\n <p className=\"text-sm text-gray-600\">{product.brand}</p>\n </div>\n <div className=\"flex items-center space-x-1 mb-2\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">\n {product.rating} ({product.reviewCount})\n </span>\n </div>\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"flex items-center space-x-2\">\n <span className=\"text-lg font-bold text-gray-900\">\n ${product.price.toFixed(2)}\n </span>\n {product.originalPrice && (\n <span className=\"text-sm text-gray-500 line-through\">\n ${product.originalPrice.toFixed(2)}\n </span>\n )}\n </div>\n </div>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n handleAddToCart(product);\n }}\n disabled={!product.inStock}\n className=\"w-full\"\n >\n <ShoppingCart className=\"mr-2 h-4 w-4\" />\n Add to Cart\n </Button>\n </CardContent>\n </Card>\n );\n\n return (\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\">\n {/* Header */}\n <div className=\"flex flex-col lg:flex-row lg:items-center lg:justify-between mb-8\">\n <div>\n <h1 className=\"text-3xl font-bold text-gray-900 mb-2\">All Products</h1>\n <p className=\"text-gray-600\">\n Showing {filteredProducts.length} of {productsData.length} products\n </p>\n </div>\n \n {/* Search and Controls */}\n <div className=\"flex items-center space-x-4 mt-4 lg:mt-0\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400\" />\n <Input\n placeholder=\"Search products...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10 w-64\"\n />\n </div>\n \n <select\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value)}\n className=\"border border-gray-300 rounded-lg px-3 py-2 bg-white\"\n >\n {sortOptions.map(option => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n\n <div className=\"flex items-center bg-gray-100 rounded-lg p-1\">\n <Button\n variant={viewMode === 'grid' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('grid')}\n >\n <Grid className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <Button\n variant=\"outline\"\n onClick={() => setShowFilters(true)}\n className=\"lg:hidden\"\n >\n <Filter className=\"mr-2 h-4 w-4\" />\n Filters\n </Button>\n </div>\n </div>\n\n <div className=\"flex gap-8\">\n\n {/* Products Grid */}\n <div className=\"flex-1\">\n {paginatedProducts.length === 0 ? (\n <div className=\"text-center py-12\">\n <div className=\"text-gray-400 mb-4\">\n <Search className=\"h-16 w-16 mx-auto\" />\n </div>\n <h3 className=\"text-lg font-medium text-gray-900 mb-2\">No products found</h3>\n <p className=\"text-gray-600 mb-4\">\n Try adjusting your search or filter criteria\n </p>\n <Button variant=\"outline\" onClick={handleClearFilters}>\n Clear Filters\n </Button>\n </div>\n ) : (\n <>\n <div className={`grid gap-6 ${\n viewMode === 'grid' \n ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4' \n : 'grid-cols-1'\n }`}>\n {paginatedProducts.map((product: Product) => (\n <ProductCard key={product.id} product={product} />\n ))}\n </div>\n\n {/* Pagination */}\n {totalPages > 1 && (\n <div className=\"flex items-center justify-center space-x-2 mt-12\">\n <Button\n variant=\"outline\"\n onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}\n disabled={currentPage === 1}\n >\n Previous\n </Button>\n \n {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {\n const page = i + 1;\n return (\n <Button\n key={page}\n variant={currentPage === page ? 'primary' : 'outline'}\n onClick={() => setCurrentPage(page)}\n >\n {page}\n </Button>\n );\n })}\n \n <Button\n variant=\"outline\"\n onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}\n disabled={currentPage === totalPages}\n >\n Next\n </Button>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n\n {/* Mobile Filters Modal */}\n <Modal open={showFilters} onOpenChange={setShowFilters}>\n <ModalHeader>\n <ModalTitle>Filters</ModalTitle>\n </ModalHeader>\n <ModalContent>\n {/* Same filter content as sidebar but in modal */}\n <div className=\"space-y-6\">\n {/* Categories */}\n <div>\n <h4 className=\"font-medium text-gray-900 mb-3\">Categories</h4>\n <div className=\"space-y-2\">\n {(filterOptions.categories as string[]).map((category, idx) => (\n <label key={category} className=\"flex items-center space-x-2\">\n <Checkbox\n checked={filters.categories.includes(category)}\n onChange={(e) => {\n const alreadyChecked = filters.categories.includes(category);\n const newCategories = e.target.checked\n ? alreadyChecked\n ? filters.categories\n : [...filters.categories, category]\n : filters.categories.filter((c: string) => c !== category);\n handleFilterChange('categories', newCategories);\n }}\n />\n <span className=\"text-sm text-gray-700\">{category}</span>\n </label>\n ))}\n </div>\n </div>\n {/* Brands */}\n <div>\n <h4 className=\"font-medium text-gray-900 mb-3\">Brands</h4>\n <div className=\"space-y-2\">\n {(filterOptions.brands as string[]).map((brand, idx) => (\n <label key={brand} className=\"flex items-center space-x-2\">\n <Checkbox\n checked={filters.brands.includes(brand)}\n onChange={(e) => {\n const alreadyChecked = filters.brands.includes(brand);\n const newBrands = e.target.checked\n ? alreadyChecked\n ? filters.brands\n : [...filters.brands, brand]\n : filters.brands.filter((b: string) => b !== brand);\n handleFilterChange('brands', newBrands);\n }}\n />\n <span className=\"text-sm text-gray-700\">{brand}</span>\n </label>\n ))}\n </div>\n </div>\n {/* Vendors */}\n <div>\n <h4 className=\"font-medium text-gray-900 mb-3\">Vendors</h4>\n <div className=\"space-y-2\">\n {(filterOptions.vendors as string[]).map((vendor, idx) => (\n <label key={vendor} className=\"flex items-center space-x-2\">\n <Checkbox\n checked={filters.vendors.includes(vendor)}\n onChange={(e) => {\n const alreadyChecked = filters.vendors.includes(vendor);\n const newVendors = e.target.checked\n ? alreadyChecked\n ? filters.vendors\n : [...filters.vendors, vendor]\n : filters.vendors.filter((v: string) => v !== vendor);\n handleFilterChange('vendors', newVendors);\n }}\n />\n <span className=\"text-sm text-gray-700\">{vendor}</span>\n </label>\n ))}\n </div>\n </div>\n </div>\n </ModalContent>\n <ModalFooter>\n <Button variant=\"outline\" onClick={handleClearFilters}>\n Clear All\n </Button>\n <Button variant=\"primary\" onClick={() => setShowFilters(false)}>\n Apply Filters\n </Button>\n </ModalFooter>\n </Modal>\n\n {/* Quick View Modal */}\n <Modal open={!!quickViewProduct} onOpenChange={() => setQuickViewProduct(null)} size=\"lg\">\n {quickViewProduct && (\n <>\n <ModalHeader>\n <ModalTitle>{quickViewProduct.name}</ModalTitle>\n </ModalHeader>\n <ModalContent>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div className=\"aspect-square bg-gray-100 rounded-lg overflow-hidden\">\n <img\n src={quickViewProduct.images[0]}\n alt={quickViewProduct.name}\n className=\"w-full h-full object-cover\"\n />\n </div>\n <div>\n <div className=\"flex items-center space-x-1 mb-2\">\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\n <span className=\"text-sm text-gray-600\">\n {quickViewProduct.rating} ({quickViewProduct.reviewCount} reviews)\n </span>\n </div>\n <div className=\"flex items-center space-x-2 mb-4\">\n <span className=\"text-2xl font-bold text-gray-900\">\n ${quickViewProduct.price.toFixed(2)}\n </span>\n {quickViewProduct.originalPrice && (\n <span className=\"text-lg text-gray-500 line-through\">\n ${quickViewProduct.originalPrice.toFixed(2)}\n </span>\n )}\n </div>\n <p className=\"text-gray-600 mb-4\">{quickViewProduct.description}</p>\n <Badge variant={quickViewProduct.inStock ? 'success' : 'danger'} className=\"mb-4\">\n {quickViewProduct.inStock ? 'In Stock' : 'Out of Stock'}\n </Badge>\n </div>\n </div>\n </ModalContent>\n <ModalFooter>\n <Button variant=\"outline\" onClick={() => onProductClick?.(quickViewProduct)}>\n View Details\n </Button>\n <Button \n variant=\"primary\" \n onClick={() => handleAddToCart(quickViewProduct)}\n disabled={!quickViewProduct.inStock}\n >\n <ShoppingCart className=\"mr-2 h-4 w-4\" />\n Add to Cart\n </Button>\n </ModalFooter>\n </>\n )}\n </Modal>\n </div>\n );\n};"],"names":["_jsxs","_jsx","Grid","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AllProductsView.js","sources":["../../../src/components/Marketplace/AllProductsView.tsx"],"sourcesContent":["import React, { useState, useMemo } from 'react';\r\nimport { Search, Filter, Grid2x2 as Grid, List, Star, ShoppingCart } from 'lucide-react';\r\nimport { MarketplaceControls } from './components/MarketplaceControls';\r\nimport { Button } from '../Button';\r\nimport { Badge } from '../Badge';\r\nimport { Modal, ModalHeader, ModalTitle, ModalContent, ModalFooter } from '../Modal';\r\nimport { Checkbox } from '../Checkbox';\r\nimport { showToast } from '../Toast';\r\nimport type { Product, FilterOptions, SortOption } from './types';\r\nimport { sampleProducts } from './data/sampleData';\r\nimport { ProductCard } from './components/ProductCard';\r\n\r\ninterface AllProductsViewProps {\r\n products?: Product[];\r\n filters: FilterOptions;\r\n searchQuery: string;\r\n setSearchQuery?: (query: string) => void;\r\n shouldFocusSearch?: boolean;\r\n onProductClick?: (product: Product) => void;\r\n onAddToCart?: (product: Product) => void;\r\n onFiltersChange: (filters: FilterOptions) => void;\r\n onClearFilters: () => void;\r\n}\r\n\r\nconst sortOptions: SortOption[] = [\r\n { value: 'relevance', label: 'Most Relevant' },\r\n { value: 'price-low', label: 'Price: Low to High' },\r\n { value: 'price-high', label: 'Price: High to Low' },\r\n { value: 'rating', label: 'Highest Rated' },\r\n { value: 'newest', label: 'Newest First' },\r\n { value: 'popular', label: 'Most Popular' },\r\n];\r\n\r\nexport const AllProductsView: React.FC<AllProductsViewProps> = ({\r\n products,\r\n filters: filtersProp,\r\n searchQuery,\r\n setSearchQuery,\r\n shouldFocusSearch,\r\n onProductClick,\r\n onAddToCart,\r\n onFiltersChange,\r\n onClearFilters,\r\n}) => {\r\n const productsData = products ?? sampleProducts;\r\n const [sortBy, setSortBy] = useState('relevance');\r\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [showFilters, setShowFilters] = useState(false);\r\n const [quickViewProduct, setQuickViewProduct] = useState<Product | null>(null);\r\n const [wishlist, setWishlist] = useState<Set<string>>(new Set());\r\n\r\n // Use filters and handlers from props only\r\n const filters = filtersProp;\r\n\r\n const itemsPerPage = 12;\r\n\r\n // Get unique filter options from products\r\n const filterOptions = useMemo(() => {\r\n const categories = [...new Set(productsData.map((p: Product) => p.category))];\r\n const brands = [...new Set(productsData.map((p: Product) => p.brand))];\r\n const vendors = [...new Set(productsData.map((p: Product) => p.vendor.name))];\r\n\r\n return { categories, brands, vendors };\r\n }, [productsData]);\r\n\r\n // Filter and sort products\r\n const filteredProducts = useMemo(() => {\r\n let filtered = productsData.filter((product: Product) => {\r\n // Search query\r\n if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase()) &&\r\n !product.description.toLowerCase().includes(searchQuery.toLowerCase())) {\r\n return false;\r\n }\r\n\r\n // Category filter\r\n if (filters.categories.length > 0 && !filters.categories.includes(product.category)) {\r\n return false;\r\n }\r\n\r\n // Brand filter\r\n if (filters.brands.length > 0 && !filters.brands.includes(product.brand)) {\r\n return false;\r\n }\r\n\r\n // Price range\r\n if (product.price < filters.priceRange[0] || product.price > filters.priceRange[1]) {\r\n return false;\r\n }\r\n\r\n // Rating filter\r\n if (filters.rating > 0 && product.rating < filters.rating) {\r\n return false;\r\n }\r\n\r\n // In stock filter\r\n if (filters.inStock && !product.inStock) {\r\n return false;\r\n }\r\n\r\n // Vendor filter\r\n if (filters.vendors.length > 0 && !filters.vendors.includes(product.vendor.name)) {\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n\r\n // Sort products\r\n switch (sortBy) {\r\n case 'price-low':\r\n filtered.sort((a: Product, b: Product) => a.price - b.price);\r\n break;\r\n case 'price-high':\r\n filtered.sort((a: Product, b: Product) => b.price - a.price);\r\n break;\r\n case 'rating':\r\n filtered.sort((a: Product, b: Product) => b.rating - a.rating);\r\n break;\r\n case 'newest':\r\n // Assuming newer products have higher IDs\r\n filtered.sort((a: Product, b: Product) => parseInt(b.id) - parseInt(a.id));\r\n break;\r\n case 'popular':\r\n filtered.sort((a: Product, b: Product) => b.reviewCount - a.reviewCount);\r\n break;\r\n default:\r\n // Keep original order for relevance\r\n break;\r\n }\r\n\r\n return filtered;\r\n }, [productsData, searchQuery, filters, sortBy]);\r\n\r\n // Paginate products\r\n const paginatedProducts = useMemo(() => {\r\n const startIndex = (currentPage - 1) * itemsPerPage;\r\n return filteredProducts.slice(startIndex, startIndex + itemsPerPage);\r\n }, [filteredProducts, currentPage]);\r\n\r\n const totalPages = Math.ceil(filteredProducts.length / itemsPerPage);\r\n\r\n const handleFilterChange = (filterType: keyof FilterOptions, value: any) => {\r\n const newFilters = {\r\n ...filters,\r\n [filterType]: value,\r\n };\r\n onFiltersChange(newFilters);\r\n setCurrentPage(1); // Reset to first page when filters change\r\n };\r\n\r\n const handleClearFilters = () => {\r\n onClearFilters();\r\n setCurrentPage(1);\r\n };\r\n\r\n const toggleWishlist = (productId: string) => {\r\n setWishlist(prev => {\r\n const newWishlist = new Set(prev);\r\n if (newWishlist.has(productId)) {\r\n newWishlist.delete(productId);\r\n showToast.info('Removed from wishlist');\r\n } else {\r\n newWishlist.add(productId);\r\n showToast.success('Added to wishlist');\r\n }\r\n return newWishlist;\r\n });\r\n };\r\n\r\n const handleAddToCart = (product: Product) => {\r\n onAddToCart?.(product);\r\n showToast.success(`${product.name} added to cart!`);\r\n };\r\n\r\n // Remove local ProductCard in favor of reusable ProductCard\r\n\r\n return (\r\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\">\r\n {/* Header */}\r\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between mb-8\">\r\n <div>\r\n <h1 className=\"text-3xl font-bold text-gray-900 mb-2\">All Products</h1>\r\n <p className=\"text-gray-600\">\r\n Showing {filteredProducts.length} of {productsData.length} products\r\n </p>\r\n </div>\r\n \r\n {/* Search and Controls */}\r\n <MarketplaceControls\r\n searchQuery={searchQuery}\r\n onSearchChange={setSearchQuery ? setSearchQuery : () => {}}\r\n shouldFocusSearch={shouldFocusSearch}\r\n sortBy={sortBy}\r\n onSortChange={setSortBy}\r\n viewMode={viewMode}\r\n onViewModeChange={setViewMode}\r\n onShowFilters={() => setShowFilters(true)}\r\n sortOptions={sortOptions}\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-8\">\r\n\r\n {/* Products Grid */}\r\n <div className=\"flex-1\">\r\n {paginatedProducts.length === 0 ? (\r\n <div className=\"text-center py-12\">\r\n <div className=\"text-gray-400 mb-4\">\r\n <Search className=\"h-16 w-16 mx-auto\" />\r\n </div>\r\n <h3 className=\"text-lg font-medium text-gray-900 mb-2\">No products found</h3>\r\n <p className=\"text-gray-600 mb-4\">\r\n Try adjusting your search or filter criteria\r\n </p>\r\n <Button variant=\"outline\" onClick={handleClearFilters}>\r\n Clear Filters\r\n </Button>\r\n </div>\r\n ) : (\r\n <>\r\n <div className={`grid gap-3 sm:gap-6 ${\r\n viewMode === 'grid'\r\n ? 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'\r\n : 'grid-cols-1'\r\n }`}>\r\n {paginatedProducts.map((product: Product) => (\r\n <div className=\"w-full max-w-xs mx-auto sm:max-w-none\" key={product.id}>\r\n <ProductCard\r\n product={product}\r\n onProductClick={onProductClick}\r\n onAddToCart={handleAddToCart}\r\n onQuickView={() => setQuickViewProduct(product)}\r\n onToggleWishlist={toggleWishlist}\r\n isWishlisted={wishlist.has(product.id)}\r\n showQuickActions={true}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex flex-wrap items-center justify-center gap-2 mt-8 sm:mt-12\">\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}\r\n disabled={currentPage === 1}\r\n >\r\n Previous\r\n </Button>\r\n \r\n {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {\r\n const page = i + 1;\r\n return (\r\n <Button\r\n key={page}\r\n variant={currentPage === page ? 'primary' : 'outline'}\r\n onClick={() => setCurrentPage(page)}\r\n >\r\n {page}\r\n </Button>\r\n );\r\n })}\r\n \r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}\r\n disabled={currentPage === totalPages}\r\n >\r\n Next\r\n </Button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Mobile Filters Modal */}\r\n <Modal open={showFilters} onOpenChange={setShowFilters}>\r\n <ModalHeader>\r\n <ModalTitle>Filters</ModalTitle>\r\n </ModalHeader>\r\n <ModalContent>\r\n {/* Same filter content as sidebar but in modal */}\r\n <div className=\"space-y-6\">\r\n {/* Categories */}\r\n <div>\r\n <h4 className=\"font-medium text-gray-900 mb-3\">Categories</h4>\r\n <div className=\"space-y-2\">\r\n {(filterOptions.categories as string[]).map((category, idx) => (\r\n <label key={category} className=\"flex items-center space-x-2\">\r\n <Checkbox\r\n checked={filters.categories.includes(category)}\r\n onChange={(e) => {\r\n const alreadyChecked = filters.categories.includes(category);\r\n const newCategories = e.target.checked\r\n ? alreadyChecked\r\n ? filters.categories\r\n : [...filters.categories, category]\r\n : filters.categories.filter((c: string) => c !== category);\r\n handleFilterChange('categories', newCategories);\r\n }}\r\n />\r\n <span className=\"text-sm text-gray-700\">{category}</span>\r\n </label>\r\n ))}\r\n </div>\r\n </div>\r\n {/* Brands */}\r\n <div>\r\n <h4 className=\"font-medium text-gray-900 mb-3\">Brands</h4>\r\n <div className=\"space-y-2\">\r\n {(filterOptions.brands as string[]).map((brand, idx) => (\r\n <label key={brand} className=\"flex items-center space-x-2\">\r\n <Checkbox\r\n checked={filters.brands.includes(brand)}\r\n onChange={(e) => {\r\n const alreadyChecked = filters.brands.includes(brand);\r\n const newBrands = e.target.checked\r\n ? alreadyChecked\r\n ? filters.brands\r\n : [...filters.brands, brand]\r\n : filters.brands.filter((b: string) => b !== brand);\r\n handleFilterChange('brands', newBrands);\r\n }}\r\n />\r\n <span className=\"text-sm text-gray-700\">{brand}</span>\r\n </label>\r\n ))}\r\n </div>\r\n </div>\r\n {/* Vendors */}\r\n <div>\r\n <h4 className=\"font-medium text-gray-900 mb-3\">Vendors</h4>\r\n <div className=\"space-y-2\">\r\n {(filterOptions.vendors as string[]).map((vendor, idx) => (\r\n <label key={vendor} className=\"flex items-center space-x-2\">\r\n <Checkbox\r\n checked={filters.vendors.includes(vendor)}\r\n onChange={(e) => {\r\n const alreadyChecked = filters.vendors.includes(vendor);\r\n const newVendors = e.target.checked\r\n ? alreadyChecked\r\n ? filters.vendors\r\n : [...filters.vendors, vendor]\r\n : filters.vendors.filter((v: string) => v !== vendor);\r\n handleFilterChange('vendors', newVendors);\r\n }}\r\n />\r\n <span className=\"text-sm text-gray-700\">{vendor}</span>\r\n </label>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </ModalContent>\r\n <ModalFooter>\r\n <Button variant=\"outline\" onClick={handleClearFilters}>\r\n Clear All\r\n </Button>\r\n <Button variant=\"primary\" onClick={() => setShowFilters(false)}>\r\n Apply Filters\r\n </Button>\r\n </ModalFooter>\r\n </Modal>\r\n\r\n {/* Quick View Modal */}\r\n <Modal open={!!quickViewProduct} onOpenChange={() => setQuickViewProduct(null)} size=\"lg\">\r\n {quickViewProduct && (\r\n <>\r\n <ModalHeader>\r\n <ModalTitle>{quickViewProduct.name}</ModalTitle>\r\n </ModalHeader>\r\n <ModalContent>\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <div className=\"aspect-square bg-gray-100 rounded-lg overflow-hidden\">\r\n <img\r\n src={quickViewProduct.images[0]}\r\n alt={quickViewProduct.name}\r\n className=\"w-full h-full object-cover\"\r\n />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center space-x-1 mb-2\">\r\n <Star className=\"h-4 w-4 text-yellow-400 fill-current\" />\r\n <span className=\"text-sm text-gray-600\">\r\n {quickViewProduct.rating} ({quickViewProduct.reviewCount} reviews)\r\n </span>\r\n </div>\r\n <div className=\"flex items-center space-x-2 mb-4\">\r\n <span className=\"text-2xl font-bold text-gray-900\">\r\n ${quickViewProduct.price.toFixed(2)}\r\n </span>\r\n {quickViewProduct.originalPrice && (\r\n <span className=\"text-lg text-gray-500 line-through\">\r\n ${quickViewProduct.originalPrice.toFixed(2)}\r\n </span>\r\n )}\r\n </div>\r\n <p className=\"text-gray-600 mb-4\">{quickViewProduct.description}</p>\r\n <Badge variant={quickViewProduct.inStock ? 'success' : 'danger'} className=\"mb-4\">\r\n {quickViewProduct.inStock ? 'In Stock' : 'Out of Stock'}\r\n </Badge>\r\n </div>\r\n </div>\r\n </ModalContent>\r\n <ModalFooter>\r\n <Button variant=\"outline\" onClick={() => onProductClick?.(quickViewProduct)}>\r\n View Details\r\n </Button>\r\n <Button \r\n variant=\"primary\" \r\n onClick={() => handleAddToCart(quickViewProduct)}\r\n disabled={!quickViewProduct.inStock}\r\n >\r\n <ShoppingCart className=\"mr-2 h-4 w-4\" />\r\n Add to Cart\r\n </Button>\r\n </ModalFooter>\r\n </>\r\n )}\r\n </Modal>\r\n </div>\r\n );\r\n};"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
|