@riosst100/pwa-marketplace 3.1.1 → 3.1.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@riosst100/pwa-marketplace",
3
3
  "author": "riosst100@gmail.com",
4
- "version": "3.1.1",
4
+ "version": "3.1.3",
5
5
  "main": "src/index.js",
6
6
  "pwa-studio": {
7
7
  "targets": {
@@ -0,0 +1,151 @@
1
+ import React, { useMemo, useCallback, useState } from 'react';
2
+ import { Link, useLocation, useHistory } from 'react-router-dom';
3
+ import useHelpCenter from '@riosst100/pwa-marketplace/src/talons/HelpCenter/useHelpCenter';
4
+ import classes from './helpcenter.module.css';
5
+
6
+ const HelpCenter = () => {
7
+ const { loading, error, data } = useHelpCenter();
8
+ const history = useHistory();
9
+ const location = useLocation();
10
+
11
+ const queryParams = new URLSearchParams(location.search);
12
+ const activeTag = queryParams.get('tag') || '';
13
+
14
+ const tagCounts = useMemo(() => {
15
+ const counts = {};
16
+ (data.questions || []).forEach(q => {
17
+ const tags = Array.isArray(q.tags) ? q.tags : (typeof q.tags === 'string' ? q.tags.split(',') : []);
18
+ tags.map(t => t && t.trim()).filter(Boolean).forEach(t => {
19
+ counts[t] = (counts[t] || 0) + 1;
20
+ });
21
+ });
22
+ return counts;
23
+ }, [data.questions]);
24
+
25
+ const [expandedId, setExpandedId] = useState(null);
26
+ const toggleExpanded = useCallback((id) => {
27
+ setExpandedId(prev => prev === id ? null : id);
28
+ }, []);
29
+
30
+ const getExcerpt = useCallback((html, limit = 420) => {
31
+ if (!html) return { text: '', truncated: false };
32
+ const text = html
33
+ .replace(/<style[\s\S]*?<\/style>/gi, ' ')
34
+ .replace(/<script[\s\S]*?<\/script>/gi, ' ')
35
+ .replace(/<[^>]+>/g, ' ')
36
+ .replace(/&nbsp;/g, ' ')
37
+ .replace(/\s+/g, ' ')
38
+ .trim();
39
+ if (text.length <= limit) return { text, truncated: false };
40
+ const cut = text.slice(0, limit);
41
+ const lastSpace = cut.lastIndexOf(' ');
42
+ const snippet = (lastSpace > 0 ? cut.slice(0, lastSpace) : cut).trim() + '...';
43
+ return { text: snippet, truncated: true };
44
+ }, []);
45
+
46
+ const visibleQuestions = useMemo(() => {
47
+ const qs = data.questions || [];
48
+ if (!activeTag) return qs;
49
+ return qs.filter(q => {
50
+ const tags = Array.isArray(q.tags) ? q.tags : (typeof q.tags === 'string' ? q.tags.split(',') : []);
51
+ return tags.map(t => t && t.trim()).includes(activeTag);
52
+ });
53
+ }, [data.questions, activeTag]);
54
+
55
+ const onSelectTag = useCallback(tag => {
56
+ const params = new URLSearchParams(location.search);
57
+ if (tag) {
58
+ params.set('tag', tag);
59
+ } else {
60
+ params.delete('tag');
61
+ }
62
+ history.push({ pathname: location.pathname, search: params.toString() });
63
+ }, [history, location]);
64
+
65
+ if (loading) {
66
+ return <div>Loading Help Center…</div>;
67
+ }
68
+
69
+ if (error) {
70
+ return <div>We\'re sorry, an error has occurred while generating this content.</div>;
71
+ }
72
+
73
+ return (
74
+ <div className={classes.container}>
75
+ <h1 className={classes.title}>User Help Center</h1>
76
+ <div className={classes.grid}>
77
+ <aside className={classes.sidebar}>
78
+ <div className={classes.sidebarHeader}>TAGS</div>
79
+ <div className={classes.tagsWrap}>
80
+ {Object.keys(tagCounts).length === 0 && (
81
+ <span className={classes.emptyState}>No tags</span>
82
+ )}
83
+ {Object.entries(tagCounts).map(([tag, count]) => (
84
+ <button
85
+ key={tag}
86
+ onClick={() => onSelectTag(tag)}
87
+ className={`${classes.tagButton} ${activeTag === tag ? classes.tagButtonActive : ''}`}
88
+ >
89
+ {tag.toUpperCase()} ({count})
90
+ </button>
91
+ ))}
92
+ </div>
93
+ </aside>
94
+ <main className={classes.main}>
95
+ {activeTag && (
96
+ <h2 className={classes.tagTitle}>Tag : {activeTag}</h2>
97
+ )}
98
+ {visibleQuestions.map(q => {
99
+ const isOpen = expandedId === q.question_id;
100
+ return (
101
+ <article key={q.question_id} className={classes.questionCard}>
102
+ <header
103
+ onClick={() => toggleExpanded(q.question_id)}
104
+ className={`${classes.questionHeader} ${isOpen ? classes.questionHeaderOpen : ''}`}
105
+ >
106
+ <span className={classes.plusIcon}>{isOpen ? '−' : '+'}</span>
107
+ {q.title}
108
+ </header>
109
+ {isOpen && (
110
+ <section className={classes.questionBody}>
111
+ {q.answer ? (
112
+ (() => {
113
+ const { text, truncated } = getExcerpt(q.answer);
114
+ return (
115
+ <>
116
+ <p className={classes.excerpt}>{text} {truncated && (
117
+ <Link to={`/help-center/question/${q.question_id}`} className={classes.tagLink}>Read more</Link>
118
+ )}</p>
119
+ </>
120
+ );
121
+ })()
122
+ ) : (
123
+ <div>We\'re sorry, an error has occurred while generating this content.</div>
124
+ )}
125
+ <div className={classes.published}>
126
+ <small>
127
+ {q.update_time ? `on ${new Date(q.update_time).toLocaleDateString()} ` : ''}
128
+ Published in: {Array.isArray(q.tags) ? (
129
+ q.tags.map((t, idx) => (
130
+ <Link key={idx} to={`/help-center?tag=${encodeURIComponent(t)}`} className={classes.tagLink}>{t}{idx < q.tags.length - 1 ? ', ' : ''}</Link>
131
+ ))
132
+ ) : (
133
+ <Link to={`/help-center?tag=${encodeURIComponent(q.tags)}`} className={classes.tagLink}>{q.tags}</Link>
134
+ )}
135
+ </small>
136
+ </div>
137
+ </section>
138
+ )}
139
+ </article>
140
+ );
141
+ })}
142
+ {visibleQuestions.length === 0 && (
143
+ <div className={classes.emptyState}>No questions found.</div>
144
+ )}
145
+ </main>
146
+ </div>
147
+ </div>
148
+ );
149
+ };
150
+
151
+ export default HelpCenter;
@@ -0,0 +1,225 @@
1
+ .container {}
2
+
3
+ .grid {
4
+ display: grid;
5
+ grid-template-columns: 280px 1fr;
6
+ gap: 24px;
7
+ }
8
+
9
+ .title {
10
+ margin-top: 16px;
11
+ font-size: 17px;
12
+ font-weight: 700;
13
+ margin-bottom: 16px;
14
+ }
15
+
16
+ .detailTitle {
17
+ margin-top: 8px;
18
+ margin-bottom: 16px;
19
+ font-size: 32px;
20
+ line-height: 1.25;
21
+ font-weight: 700;
22
+ }
23
+
24
+ .sidebar {
25
+ border: 1px solid #E6E9EA;
26
+ border-radius: 6px;
27
+ max-height: max-content;
28
+ }
29
+
30
+ .sidebarHeader {
31
+ padding: 12px;
32
+ border-bottom: 1px solid #E6E9EA;
33
+ font-weight: 600;
34
+ background-color: #F2F2F2;
35
+ }
36
+
37
+ .tagsWrap {
38
+ padding: 12px;
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ gap: 8px;
42
+ }
43
+
44
+ .tagButton {
45
+ border: 1px solid #E6E9EA;
46
+ padding: 8px 10px;
47
+ background: #F8F8F8;
48
+ color: #f76b1c;
49
+ cursor: pointer;
50
+ }
51
+
52
+ .tagButtonActive {
53
+ background: #fff3e6;
54
+ }
55
+
56
+ .main {}
57
+
58
+ .tagTitle {
59
+ margin: 0;
60
+ margin-bottom: 16px;
61
+ }
62
+
63
+ .questionCard {
64
+ border: 1px solid #E6E9EA;
65
+ border-radius: 6px;
66
+ margin-bottom: 16px;
67
+ }
68
+
69
+ .questionCardDetail {
70
+ border-radius: 6px;
71
+ margin-bottom: 16px;
72
+ }
73
+
74
+ .questionHeader {
75
+ padding: 12px;
76
+ background: #F2F2F2;
77
+ color: #f76b1c;
78
+ font-weight: 700;
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 8px;
82
+ cursor: pointer;
83
+ }
84
+
85
+ .questionHeaderOpen {
86
+ background: #fff3e6;
87
+ }
88
+
89
+ .plusIcon {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ width: 18px;
94
+ height: 18px;
95
+ border-radius: 3px;
96
+ background: #f76b1c;
97
+ color: #fff;
98
+ font-size: 14px;
99
+ line-height: 18px;
100
+ }
101
+
102
+ .questionBody {
103
+ padding: 16px 12px;
104
+ color: #292D32;
105
+ font-size: 16px;
106
+ line-height: 1.7;
107
+ }
108
+ .container{
109
+ margin: 3rem 0px;
110
+ }
111
+ .excerpt {
112
+ color: #292D32;
113
+ }
114
+
115
+ .published {
116
+ margin-top: 8px;
117
+ color: #999999;
118
+ }
119
+
120
+ .tagLink {
121
+ color: #f76b1c;
122
+ }
123
+ .emptyState {
124
+ color: #999999;
125
+ }
126
+
127
+ .tagsLine {
128
+ margin-top: 16px;
129
+ display: flex;
130
+ align-items: center;
131
+ gap: 20px;
132
+ flex-wrap: wrap;
133
+ }
134
+
135
+ .tagPill {
136
+ display: inline-flex;
137
+ align-items: center;
138
+ gap: 8px;
139
+ padding: 4px 10px;
140
+ border-radius: 0px 4px 4px 0px;
141
+ background: #292D32;
142
+ color: #fff;
143
+ font-size: 12px;
144
+ position: relative;
145
+ text-transform: uppercase;
146
+ }
147
+
148
+ .tagPill::before {
149
+ content: '';
150
+ position: absolute;
151
+ left: -13px;
152
+ top: 50%;
153
+ transform: translateY(-53%);
154
+ width: 0;
155
+ height: 0;
156
+ border-top: 13px solid transparent;
157
+ border-bottom: 13px solid transparent;
158
+ border-right: 14px solid #292D32;
159
+ }
160
+
161
+ .tagPill::after {
162
+ content: '';
163
+ position: absolute;
164
+ left: -7px;
165
+ top: 50%;
166
+ transform: translateY(-50%);
167
+ width: 5px;
168
+ height: 5px;
169
+ background: #fff;
170
+ border-radius: 50%;
171
+ }
172
+
173
+ /* Mobile adjustments */
174
+ @media (max-width: 768px) {
175
+ .container {
176
+ margin: 1.5rem 0;
177
+ }
178
+ .grid {
179
+ grid-template-columns: 1fr;
180
+ gap: 16px;
181
+ }
182
+ .sidebar {
183
+ border-radius: 8px;
184
+ }
185
+ .tagsWrap {
186
+ gap: 6px;
187
+ }
188
+ .tagButton {
189
+ padding: 8px 12px;
190
+ border-radius: 6px;
191
+ }
192
+ .title {
193
+ font-size: 18px;
194
+ margin-bottom: 12px;
195
+ }
196
+ .tagTitle {
197
+ font-size: 16px;
198
+ margin-bottom: 12px;
199
+ }
200
+ .questionCard {
201
+ margin-bottom: 12px;
202
+ }
203
+ .questionHeader {
204
+ padding: 12px;
205
+ font-size: 14px;
206
+ }
207
+ .plusIcon {
208
+ width: 16px;
209
+ height: 16px;
210
+ font-size: 12px;
211
+ line-height: 16px;
212
+ }
213
+ .questionBody {
214
+ padding: 12px;
215
+ font-size: 15px;
216
+ line-height: 1.6;
217
+ }
218
+ .tagsLine {
219
+ gap: 18px;
220
+ }
221
+ .tagPill {
222
+ font-size: 11px;
223
+ padding: 4px 8px;
224
+ }
225
+ }
@@ -0,0 +1 @@
1
+ export { default } from './helpCenter';
@@ -0,0 +1,89 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Link, useParams } from 'react-router-dom';
3
+ import useHelpCenter from '@riosst100/pwa-marketplace/src/talons/HelpCenter/useHelpCenter';
4
+ import classes from './helpcenter.module.css';
5
+
6
+ const QuestionDetail = () => {
7
+ const { questionId } = useParams();
8
+ const { loading, error, data } = useHelpCenter();
9
+
10
+ const tagCounts = useMemo(() => {
11
+ const counts = {};
12
+ (data.questions || []).forEach(q => {
13
+ const tags = Array.isArray(q.tags) ? q.tags : (typeof q.tags === 'string' ? q.tags.split(',') : []);
14
+ tags.map(t => t && t.trim()).filter(Boolean).forEach(t => {
15
+ counts[t] = (counts[t] || 0) + 1;
16
+ });
17
+ });
18
+ return counts;
19
+ }, [data.questions]);
20
+
21
+ const question = useMemo(() => {
22
+ const id = Number(questionId);
23
+ return (data.questions || []).find(q => Number(q.question_id) === id) || null;
24
+ }, [data.questions, questionId]);
25
+
26
+ if (loading) return <div>Loading…</div>;
27
+ if (error) return <div>We\'re sorry, an error has occurred while generating this content.</div>;
28
+ if (!question) return <div className={classes.emptyState}>Question not found.</div>;
29
+
30
+ return (
31
+ <div className={classes.container}>
32
+ <div className={classes.grid}>
33
+ <aside className={classes.sidebar}>
34
+ <div className={classes.sidebarHeader}>TAGS</div>
35
+ <div className={classes.tagsWrap}>
36
+ {Object.keys(tagCounts).length === 0 && (
37
+ <span className={classes.emptyState}>No tags</span>
38
+ )}
39
+ {Object.entries(tagCounts).map(([tag, count]) => (
40
+ <Link key={tag} to={`/help-center?tag=${encodeURIComponent(tag)}`} className={`${classes.tagButton}`}>
41
+ {tag.toUpperCase()} ({count})
42
+ </Link>
43
+ ))}
44
+ </div>
45
+ </aside>
46
+ <main>
47
+ <h1 className={classes.detailTitle}>{question.title}</h1>
48
+ <article className={classes.questionCardDetail}>
49
+ <section className={classes.questionBody}>
50
+ {question.answer ? (
51
+ <div dangerouslySetInnerHTML={{ __html: question.answer }} />
52
+ ) : (
53
+ <div>We\'re sorry, an error has occurred while generating this content.</div>
54
+ )}
55
+ <div className={classes.published}>
56
+ <p>
57
+ {question.update_time ? `on ${new Date(question.update_time).toLocaleDateString()} ` : ''}
58
+ Published in: {Array.isArray(question.tags) ? (
59
+ question.tags.map((t, idx) => (
60
+ <Link key={idx} to={`/help-center?tag=${encodeURIComponent(t)}`} className={classes.tagLink}>{t}{idx < question.tags.length - 1 ? ', ' : ''}</Link>
61
+ ))
62
+ ) : (
63
+ <Link to={`/help-center?tag=${encodeURIComponent(question.tags)}`} className={classes.tagLink}>{question.tags}</Link>
64
+ )}
65
+ </p>
66
+ </div>
67
+ <div className={classes.tagsLine}>
68
+ <strong>TAGS:</strong>
69
+ {Array.isArray(question.tags) ? (
70
+ question.tags.map((t, idx) => (
71
+ <span key={idx} className={classes.tagPill}>
72
+ {String(t).toUpperCase()}
73
+ </span>
74
+ ))
75
+ ) : (
76
+ <span className={classes.tagPill}>
77
+ {String(question.tags).toUpperCase()}
78
+ </span>
79
+ )}
80
+ </div>
81
+ </section>
82
+ </article>
83
+ </main>
84
+ </div>
85
+ </div>
86
+ );
87
+ };
88
+
89
+ export default QuestionDetail;
package/src/intercept.js CHANGED
@@ -87,6 +87,20 @@ module.exports = targets => {
87
87
  authed: true,
88
88
  redirectTo: "/sign-in"
89
89
  },
90
+ {
91
+ exact: true,
92
+ name: "HelpCenter",
93
+ pattern: "/help-center",
94
+ path: require.resolve("./components/HelpCenter/index.js"),
95
+ authed: false,
96
+ },
97
+ {
98
+ exact: true,
99
+ name: "HelpCenterQuestionDetail",
100
+ pattern: "/help-center/question/:questionId",
101
+ path: require.resolve("./components/HelpCenter/questionDetail.js"),
102
+ authed: false,
103
+ },
90
104
  {
91
105
  exact: true,
92
106
  name: "VerifyEmailPage",
@@ -10,7 +10,7 @@ const getToKnowUsLinks = new Map()
10
10
  .set('About TCG Collective', null)
11
11
  .set('Career', '/')
12
12
  .set('Contact Us', '/')
13
- .set('Help Center', '/')
13
+ .set('Help Center', '/help-center')
14
14
  .set('Intelectual Property Claims', '/');
15
15
 
16
16
  const aboutLinks = new Map()
@@ -108,7 +108,8 @@ export const useFilterContent = props => {
108
108
 
109
109
  getFilters({
110
110
  variables: {
111
- filters: newFilters
111
+ filters: newFilters,
112
+ category_uid: categoryId
112
113
  }
113
114
  });
114
115
  }
@@ -0,0 +1,93 @@
1
+ import { gql } from '@apollo/client';
2
+
3
+ export const FAQ_CATEGORIES = gql`
4
+ query faqCategories {
5
+ faqCategories {
6
+ body_background
7
+ border_color
8
+ border_radius
9
+ border_width
10
+ category_id
11
+ creation_time
12
+ description
13
+ icon
14
+ is_active
15
+ margin_bottom
16
+ margin_left
17
+ meta_description
18
+ meta_keywords
19
+ page_title
20
+ parent_id
21
+ position
22
+ seller_id
23
+ status
24
+ store_id
25
+ title
26
+ title_background
27
+ title_color
28
+ title_size
29
+ update_time
30
+ }
31
+ }
32
+ `;
33
+
34
+ export const FAQ_QUESTIONS = gql`
35
+ query faqQuestions {
36
+ faqQuestions {
37
+ _first_store_id
38
+ animation_class
39
+ animation_speed
40
+ answer
41
+ author_email
42
+ author_name
43
+ body_bg
44
+ body_color
45
+ body_size
46
+ border_width
47
+ creation_time
48
+ disklike
49
+ is_active
50
+ is_featured
51
+ like
52
+ meta_description
53
+ meta_keywords
54
+ page_title
55
+ question_active_icon
56
+ question_icon
57
+ question_id
58
+ question_margin
59
+ question_position
60
+ question_type
61
+ question_url
62
+ store_code
63
+ store_id
64
+ tags
65
+ title
66
+ title_bg
67
+ title_bg_active
68
+ title_border_color
69
+ title_border_radius
70
+ title_color
71
+ title_color_active
72
+ title_size
73
+ update_time
74
+ }
75
+ }
76
+ `;
77
+
78
+ export const FAQ_TAGS = gql`
79
+ query faqTags {
80
+ faqTags {
81
+ alias
82
+ name
83
+ question_id
84
+ tag_id
85
+ }
86
+ }
87
+ `;
88
+
89
+ export default {
90
+ faqCategoriesQuery: FAQ_CATEGORIES,
91
+ faqQuestionsQuery: FAQ_QUESTIONS,
92
+ faqTagsQuery: FAQ_TAGS
93
+ };
@@ -0,0 +1,59 @@
1
+ import { useMemo } from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { useQuery } from '@apollo/client';
4
+ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
5
+ import DEFAULT_OPERATIONS from './helpCenter.gql';
6
+
7
+ export const useHelpCenter = (props = {}) => {
8
+ const { formatMessage } = useIntl();
9
+
10
+ const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
11
+
12
+ const {
13
+ faqCategoriesQuery,
14
+ faqQuestionsQuery,
15
+ faqTagsQuery
16
+ } = operations;
17
+
18
+ const {
19
+ data: categoriesData,
20
+ loading: categoriesLoading,
21
+ error: categoriesError
22
+ } = useQuery(faqCategoriesQuery, {
23
+ fetchPolicy: 'cache-and-network'
24
+ });
25
+
26
+ const {
27
+ data: questionsData,
28
+ loading: questionsLoading,
29
+ error: questionsError
30
+ } = useQuery(faqQuestionsQuery, {
31
+ fetchPolicy: 'cache-and-network'
32
+ });
33
+
34
+ const {
35
+ data: tagsData,
36
+ loading: tagsLoading,
37
+ error: tagsError
38
+ } = useQuery(faqTagsQuery, {
39
+ fetchPolicy: 'cache-and-network'
40
+ });
41
+
42
+ const loading = categoriesLoading || questionsLoading || tagsLoading;
43
+ const error = categoriesError || questionsError || tagsError || null;
44
+
45
+ const data = useMemo(() => ({
46
+ categories: categoriesData?.faqCategories || [],
47
+ questions: questionsData?.faqQuestions || [],
48
+ tags: tagsData?.faqTags || []
49
+ }), [categoriesData, questionsData, tagsData]);
50
+
51
+ return {
52
+ loading,
53
+ error,
54
+ data,
55
+ formatMessage
56
+ };
57
+ };
58
+
59
+ export default useHelpCenter;
@@ -3,8 +3,12 @@ import { gql } from '@apollo/client';
3
3
  export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
4
4
  query getProductFiltersByCategory(
5
5
  $categoryIdFilter: FilterEqualTypeInput!
6
+ $category_uid: String
6
7
  ) {
7
- products(filter: { category_uid: $categoryIdFilter }) {
8
+ products(
9
+ filter: { category_uid: $categoryIdFilter }
10
+ category_uid: $category_uid
11
+ ) {
8
12
  aggregations {
9
13
  label
10
14
  count
@@ -87,7 +87,8 @@ export const useProductContent = props => {
87
87
  variables: {
88
88
  categoryIdFilter: {
89
89
  eq: categoryId
90
- }
90
+ },
91
+ category_uid: categoryId
91
92
  }
92
93
  });
93
94
  }
@@ -3,8 +3,12 @@ import { gql } from '@apollo/client';
3
3
  export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
4
4
  query getProductFiltersByCategory(
5
5
  $categoryIdFilter: FilterEqualTypeInput!
6
+ $category_uid: String
6
7
  ) {
7
- products(filter: { category_uid: $categoryIdFilter }) {
8
+ products(
9
+ filter: { category_uid: $categoryIdFilter }
10
+ category_uid: $category_uid
11
+ ) {
8
12
  aggregations {
9
13
  label
10
14
  count
@@ -75,7 +75,8 @@ export const useProductContent = props => {
75
75
  variables: {
76
76
  categoryIdFilter: {
77
77
  eq: categoryId
78
- }
78
+ },
79
+ category_uid: categoryId
79
80
  }
80
81
  });
81
82
  }
@@ -63,8 +63,9 @@ export const GET_FILTER_INPUTS = gql`
63
63
  export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
64
64
  query getProductMainFiltersByCategory(
65
65
  $filters: ProductAttributeFilterInput!
66
+ $category_uid: String
66
67
  ) {
67
- products(filter: $filters) {
68
+ products(filter: $filters category_uid: $category_uid) {
68
69
  aggregations {
69
70
  label
70
71
  count
@@ -133,11 +133,12 @@ export const useShopBy = props => {
133
133
 
134
134
  runQuery({
135
135
  variables: {
136
- filters: newFilters
136
+ filters: newFilters,
137
+ category_uid: categoryId
137
138
  }
138
139
  });
139
140
  }, [
140
- runQuery, filterTypeMap, search
141
+ runQuery, filterTypeMap, search, categoryId
141
142
  ]);
142
143
 
143
144
  const alpha = ['#', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
@@ -63,8 +63,9 @@ export const GET_FILTER_INPUTS = gql`
63
63
  export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql`
64
64
  query getProductMainFiltersByCategory(
65
65
  $filters: ProductAttributeFilterInput!
66
+ $category_uid: String
66
67
  ) {
67
- products(filter: $filters) {
68
+ products(filter: $filters category_uid: $category_uid) {
68
69
  aggregations {
69
70
  label
70
71
  count
@@ -1,280 +0,0 @@
1
- import { useQuery, useLazyQuery } from '@apollo/client';
2
- import { useEffect, useMemo } from 'react';
3
- import { useLocation } from 'react-router-dom';
4
-
5
- import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
6
- import DEFAULT_OPERATIONS from '@riosst100/pwa-marketplace/src/talons/ShowMore/shopBy.gql';
7
- import { getFilterInput, getFiltersFromSearch } from '@magento/peregrine/lib/talons/FilterModal/helpers';
8
-
9
- export const useShopBy = props => {
10
-
11
- const { searchQuery, activeFilter, active, setActive, currentSort, categoryId, shopby } = props
12
-
13
- const { value: sortby } = currentSort
14
-
15
- const operations = mergeOperations(DEFAULT_OPERATIONS, null);
16
- const { getStoreConfigData, getShopByDataQuery, getCategoryContentQuery, getFilterInputsQuery, getProductFiltersByCategoryQuery, getMasterAttributesQuery } = operations;
17
- const { pathname, search } = useLocation();
18
- // const [
19
- // ,
20
- // {
21
- // actions: { setPageLoading }
22
- // }
23
- // ] = useAppContext();
24
-
25
- const [runQuery, { data: queryResponse, loading, error }] = useLazyQuery(
26
- getProductFiltersByCategoryQuery,
27
- {
28
- fetchPolicy: 'cache-and-network',
29
- nextFetchPolicy: 'cache-first'
30
- }
31
- );
32
-
33
- // const [runQuery, {data: queryResponse, loading, error}] = useLazyQuery(getShopByDataQuery, {
34
- // fetchPolicy: 'cache-and-network',
35
- // nextFetchPolicy: 'cache-first'
36
- // });
37
-
38
- const { data: storeConfigData } = useQuery(getStoreConfigData, {
39
- fetchPolicy: 'cache-and-network',
40
- nextFetchPolicy: 'cache-first'
41
- });
42
-
43
- const pathnameArr = pathname.split('/');
44
-
45
- const categoryUrlKey = pathnameArr[pathnameArr.length - 1].replace('.html','');
46
-
47
- const categoryUrlSuffix = storeConfigData?.storeConfig?.category_url_suffix;
48
-
49
- const { data: introspectionData } = useQuery(getFilterInputsQuery);
50
-
51
- const filterTypeMap = useMemo(() => {
52
- const typeMap = new Map();
53
- if (introspectionData) {
54
- introspectionData.__type.inputFields.forEach(({ name, type }) => {
55
- typeMap.set(name, type.name);
56
- });
57
- }
58
- return typeMap;
59
- }, [introspectionData]);
60
-
61
- const filters = getFiltersFromSearch(search);
62
-
63
- const { newFilters, activeFilters } = useMemo(() => {
64
- const resultFilters = {};
65
- const resultActiveFilters = [];
66
-
67
- if (filterTypeMap.size) {
68
- filters.forEach((values, key) => {
69
- resultFilters[key] = getFilterInput(values, filterTypeMap.get(key));
70
-
71
- if (key === "sc_baseball_release") {
72
- for (let item of values) {
73
- if (item) {
74
- const data = search.split('&');
75
- data.pop();
76
- resultActiveFilters.push({
77
- label: item.split(',')[0],
78
- path: data
79
- });
80
- }
81
- }
82
- }
83
- });
84
- }
85
-
86
- return { newFilters: resultFilters, activeFilters: resultActiveFilters };
87
- }, [filterTypeMap]);
88
-
89
- // MASTER ATTRIBUTES
90
- const {
91
- called: masterAttributesCalled,
92
- data: masterAttributesData,
93
- loading: masterAttributesLoading
94
- } = useQuery(getMasterAttributesQuery,
95
- {
96
- fetchPolicy: 'cache-and-network',
97
- nextFetchPolicy: 'cache-first'
98
- });
99
-
100
- const masterAttributes = useMemo(() => {
101
- const masterAttributes = [];
102
-
103
- if (masterAttributesData) {
104
- masterAttributesData.masterAttributes.forEach(({ attribute_code }) => {
105
- masterAttributes.push(attribute_code);
106
- });
107
- }
108
-
109
- return masterAttributes;
110
- }, [masterAttributesData]);
111
-
112
- useEffect(() => {
113
-
114
- if (!filterTypeMap.size) {
115
- return;
116
- }
117
-
118
- const filters = getFiltersFromSearch(search);
119
-
120
- const mainAttributes = ['card_game'];
121
-
122
- // Construct the filter arg object.
123
- const newFilters = {};
124
- filters.forEach((values, key) => {
125
- if (mainAttributes.includes(key)) {
126
- newFilters[key] = getFilterInput(values, filterTypeMap.get(key));
127
- }
128
- });
129
-
130
- // Use the category uid for the current category page regardless of the
131
- // applied filters. Follow-up in PWA-404.
132
- // newFilters['category_uid'] = { eq: id };
133
-
134
- runQuery({
135
- variables: {
136
- filters: newFilters
137
- }
138
- });
139
- }, [
140
- runQuery, filterTypeMap, search
141
- ]);
142
-
143
- const alpha = ['#', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
144
-
145
- // const isBackgroundLoading = !!queryResponse && loading;
146
-
147
- const originalDataResult = useMemo(() => {
148
- if (!queryResponse) {
149
- return null;
150
- }
151
-
152
- const rawData = queryResponse?.products?.aggregations;
153
- if (!rawData.length) {
154
- return null;
155
- }
156
-
157
- let options = rawData.find(item => item.attribute_code === shopby).options;
158
-
159
- const mappingData = options.reduce((acc, item) => {
160
- let firstLetter = item.label.charAt(0).toUpperCase();
161
- if (!alpha.includes(firstLetter)) {
162
- firstLetter = '#';
163
- }
164
- if (shopby == "vehicles_year" || shopby == "trains_gauge" || shopby == "vehicles_scale" || shopby == "lego_theme" || shopby == "lego_subtheme" || shopby == "lego_interest") {
165
- firstLetter = '#';
166
- }
167
- acc[firstLetter] = acc[firstLetter] || [];
168
- acc[firstLetter].push(item);
169
- return acc;
170
- }, {});
171
-
172
- const sortbyData = [];
173
-
174
- return sortby != "all" ? sortbyData && sortbyData.length ? sortbyData.sort((a, b) => b.release_type.toLowerCase().localeCompare(a.release_type.toLowerCase())) : sortbyData : mappingData;
175
- }, [queryResponse, sortby]);
176
-
177
- const filteredOptions = useMemo(() => {
178
- if (!queryResponse) {
179
- return null;
180
- }
181
-
182
- const rawData = queryResponse?.products?.aggregations;
183
- if (!rawData.length) {
184
- return null;
185
- }
186
-
187
- let options = rawData.find(item => item.attribute_code === shopby).options;
188
-
189
- // const filteredSets = [];
190
-
191
- // let filteredOptions = [];
192
-
193
- // let mappingData = [];
194
-
195
- if (searchQuery) {
196
- if (active != "all") {
197
- setActive('all');
198
- }
199
-
200
- return options.filter(function(option) {
201
- return option.label.search(new RegExp(searchQuery, "i")) != -1;
202
- });
203
- }
204
-
205
- return options;
206
- }, [queryResponse, searchQuery]);
207
-
208
- const dataResult = useMemo(() => {
209
- if (filteredOptions) {
210
- return filteredOptions.reduce((acc, item) => {
211
- let firstLetter = item.label.charAt(0).toUpperCase();
212
- if (!alpha.includes(firstLetter)) {
213
- firstLetter = '#';
214
- }
215
- if (shopby == "vehicles_year" || shopby == "trains_gauge" || shopby == "vehicles_scale" || shopby == "lego_theme" || shopby == "lego_subtheme" || shopby == "lego_interest") {
216
- firstLetter = '#';
217
- }
218
- acc[firstLetter] = acc[firstLetter] || [];
219
- acc[firstLetter].push(item);
220
- return acc;
221
- }, {});
222
- }
223
-
224
- return filteredOptions;
225
- }, [filteredOptions]);
226
-
227
- let availableGroups = originalDataResult ? Object.keys(originalDataResult).sort() : [];
228
-
229
- let filteredAvailableGroups = dataResult ? Object.keys(dataResult).sort() : [];
230
-
231
- if (shopby == "vehicles_year" || shopby == "trains_gauge" || shopby == "vehicles_scale" || shopby == "lego_theme" || shopby == "lego_subtheme" || shopby == "lego_interest") {
232
- availableGroups = ['#'];
233
- filteredAvailableGroups = ['#'];
234
- }
235
-
236
-
237
- const attributeData = queryResponse?.products?.aggregations && queryResponse?.products.aggregations.length ? queryResponse.products.aggregations.find(item => item.attribute_code === shopby) : null;
238
-
239
- const { data: categoryData, loading: categoryLoading } = useQuery(
240
- getCategoryContentQuery,
241
- {
242
- fetchPolicy: 'cache-and-network',
243
- nextFetchPolicy: 'cache-first',
244
- skip: !categoryId,
245
- variables: {
246
- id: categoryId
247
- }
248
- }
249
- );
250
-
251
- const pageInfo = useMemo(() => {
252
- if (!queryResponse) {
253
- return null;
254
- }
255
-
256
- return queryResponse.products.aggregations.find(item => item.attribute_code === shopby);
257
- }, [queryResponse, shopby]);
258
-
259
- const category =
260
- categoryData && categoryData.categories.items.length
261
- ? categoryData.categories.items[0]
262
- : null;
263
-
264
- return {
265
- error,
266
- loading,
267
- dataResult,
268
- // collectibleGameSets,
269
- filteredAvailableGroups,
270
- categoryUrlSuffix,
271
- categoryUrlKey,
272
- availableGroups,
273
- attributeData,
274
- alpha,
275
- category,
276
- activeFilters,
277
- pageInfo
278
- // productType
279
- };
280
- };