@marvalt/shcoder 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import require$$0, { useState, useEffect } from 'react';
2
+ import { useSearchParams } from 'react-router-dom';
2
3
 
3
4
  /**
4
5
  * @license GPL-3.0-or-later
@@ -34,6 +35,42 @@ function getApiUrl$1() {
34
35
  }
35
36
  // Initialize API URL
36
37
  apiUrl$1 = getApiUrl$1();
38
+ let staticDataProvider = null;
39
+ function setStaticDataProvider(provider) {
40
+ staticDataProvider = provider;
41
+ }
42
+ // Helper function to extract featured image from member data
43
+ function extractFeaturedImage(member) {
44
+ if (member.featured_image_urls) {
45
+ return member.featured_image_urls;
46
+ }
47
+ if (member._embedded?.['wp:featuredmedia']?.[0]) {
48
+ const featuredMedia = member._embedded['wp:featuredmedia'][0];
49
+ return {
50
+ thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
51
+ url: featuredMedia.media_details.sizes.thumbnail.source_url,
52
+ width: featuredMedia.media_details.sizes.thumbnail.width,
53
+ height: featuredMedia.media_details.sizes.thumbnail.height,
54
+ } : undefined,
55
+ medium: featuredMedia.media_details?.sizes?.medium ? {
56
+ url: featuredMedia.media_details.sizes.medium.source_url,
57
+ width: featuredMedia.media_details.sizes.medium.width,
58
+ height: featuredMedia.media_details.sizes.medium.height,
59
+ } : undefined,
60
+ large: featuredMedia.media_details?.sizes?.large ? {
61
+ url: featuredMedia.media_details.sizes.large.source_url,
62
+ width: featuredMedia.media_details.sizes.large.width,
63
+ height: featuredMedia.media_details.sizes.large.height,
64
+ } : undefined,
65
+ full: {
66
+ url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
67
+ width: featuredMedia.media_details?.width || 0,
68
+ height: featuredMedia.media_details?.height || 0,
69
+ },
70
+ };
71
+ }
72
+ return undefined;
73
+ }
37
74
  /**
38
75
  * Hook to fetch members based on shortcode attributes
39
76
  */
@@ -42,15 +79,39 @@ function useMembers(attrs) {
42
79
  const [loading, setLoading] = useState(true);
43
80
  const [error, setError] = useState(null);
44
81
  useEffect(() => {
45
- if (!apiUrl$1) {
46
- setError(new Error('WordPress API URL not configured'));
47
- setLoading(false);
48
- return;
49
- }
50
82
  async function fetchMembers() {
51
83
  try {
52
84
  setLoading(true);
53
85
  setError(null);
86
+ // Use static data if available (preferred method)
87
+ if (staticDataProvider) {
88
+ const provider = staticDataProvider();
89
+ const filtered = provider.filterMembers({
90
+ category: attrs.tax || attrs.category,
91
+ role: attrs.role,
92
+ limit: attrs.limit ? parseInt(attrs.limit, 10) : undefined,
93
+ orderby: attrs.orderby || 'date',
94
+ order: attrs.order || 'desc',
95
+ });
96
+ // Process members to match Member interface
97
+ const processedMembers = filtered.map((member) => {
98
+ const processed = {
99
+ ...member,
100
+ member_meta: member.member_meta || {},
101
+ featured_image_urls: extractFeaturedImage(member),
102
+ };
103
+ return processed;
104
+ });
105
+ setMembers(processedMembers);
106
+ setLoading(false);
107
+ return;
108
+ }
109
+ // Fallback to API (should not happen in production with static data)
110
+ if (!apiUrl$1) {
111
+ setError(new Error('WordPress API URL not configured and no static data provider available'));
112
+ setLoading(false);
113
+ return;
114
+ }
54
115
  // Build query params from shortcode attributes
55
116
  const params = {
56
117
  per_page: (attrs.limit ? parseInt(attrs.limit, 10) : 100).toString(),
@@ -83,33 +144,8 @@ function useMembers(attrs) {
83
144
  const processed = {
84
145
  ...member,
85
146
  member_meta: member.member_meta || {},
147
+ featured_image_urls: extractFeaturedImage(member),
86
148
  };
87
- // Extract featured image from _embedded
88
- if (member._embedded && member._embedded['wp:featuredmedia'] && member._embedded['wp:featuredmedia'][0]) {
89
- const featuredMedia = member._embedded['wp:featuredmedia'][0];
90
- processed.featured_image_urls = {
91
- thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
92
- url: featuredMedia.media_details.sizes.thumbnail.source_url,
93
- width: featuredMedia.media_details.sizes.thumbnail.width,
94
- height: featuredMedia.media_details.sizes.thumbnail.height,
95
- } : undefined,
96
- medium: featuredMedia.media_details?.sizes?.medium ? {
97
- url: featuredMedia.media_details.sizes.medium.source_url,
98
- width: featuredMedia.media_details.sizes.medium.width,
99
- height: featuredMedia.media_details.sizes.medium.height,
100
- } : undefined,
101
- large: featuredMedia.media_details?.sizes?.large ? {
102
- url: featuredMedia.media_details.sizes.large.source_url,
103
- width: featuredMedia.media_details.sizes.large.width,
104
- height: featuredMedia.media_details.sizes.large.height,
105
- } : undefined,
106
- full: {
107
- url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
108
- width: featuredMedia.media_details?.width || 0,
109
- height: featuredMedia.media_details?.height || 0,
110
- },
111
- };
112
- }
113
149
  return processed;
114
150
  });
115
151
  setMembers(processedMembers);
@@ -134,7 +170,7 @@ function useMember(id) {
134
170
  const [loading, setLoading] = useState(true);
135
171
  const [error, setError] = useState(null);
136
172
  useEffect(() => {
137
- if (!apiUrl$1 || !id) {
173
+ if (!id) {
138
174
  setLoading(false);
139
175
  return;
140
176
  }
@@ -142,6 +178,31 @@ function useMember(id) {
142
178
  try {
143
179
  setLoading(true);
144
180
  setError(null);
181
+ // Use static data if available (preferred method)
182
+ if (staticDataProvider) {
183
+ const provider = staticDataProvider();
184
+ const found = provider.getMemberById(id);
185
+ if (found) {
186
+ // Process member to match Member interface
187
+ const processed = {
188
+ ...found,
189
+ member_meta: found.member_meta || {},
190
+ featured_image_urls: extractFeaturedImage(found),
191
+ };
192
+ setMember(processed);
193
+ }
194
+ else {
195
+ setMember(null);
196
+ }
197
+ setLoading(false);
198
+ return;
199
+ }
200
+ // Fallback to API (should not happen in production with static data)
201
+ if (!apiUrl$1) {
202
+ setError(new Error('WordPress API URL not configured and no static data provider available'));
203
+ setLoading(false);
204
+ return;
205
+ }
145
206
  const response = await fetch(`${apiUrl$1}/wp/v2/member/${id}?_embed=true`);
146
207
  if (!response.ok) {
147
208
  throw new Error(`Failed to fetch member: ${response.statusText}`);
@@ -151,33 +212,8 @@ function useMember(id) {
151
212
  const processed = {
152
213
  ...data,
153
214
  member_meta: data.member_meta || {},
215
+ featured_image_urls: extractFeaturedImage(data),
154
216
  };
155
- // Extract featured image from _embedded
156
- if (data._embedded && data._embedded['wp:featuredmedia'] && data._embedded['wp:featuredmedia'][0]) {
157
- const featuredMedia = data._embedded['wp:featuredmedia'][0];
158
- processed.featured_image_urls = {
159
- thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
160
- url: featuredMedia.media_details.sizes.thumbnail.source_url,
161
- width: featuredMedia.media_details.sizes.thumbnail.width,
162
- height: featuredMedia.media_details.sizes.thumbnail.height,
163
- } : undefined,
164
- medium: featuredMedia.media_details?.sizes?.medium ? {
165
- url: featuredMedia.media_details.sizes.medium.source_url,
166
- width: featuredMedia.media_details.sizes.medium.width,
167
- height: featuredMedia.media_details.sizes.medium.height,
168
- } : undefined,
169
- large: featuredMedia.media_details?.sizes?.large ? {
170
- url: featuredMedia.media_details.sizes.large.source_url,
171
- width: featuredMedia.media_details.sizes.large.width,
172
- height: featuredMedia.media_details.sizes.large.height,
173
- } : undefined,
174
- full: {
175
- url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
176
- width: featuredMedia.media_details?.width || 0,
177
- height: featuredMedia.media_details?.height || 0,
178
- },
179
- };
180
- }
181
217
  setMember(processed);
182
218
  }
183
219
  catch (err) {
@@ -1685,10 +1721,13 @@ var jsxRuntimeExports = jsxRuntime.exports;
1685
1721
 
1686
1722
  /**
1687
1723
  * MemberCard component - displays a single member profile
1688
- * Usage: [member_card id="123"]
1724
+ * Usage: [member_card id="123"] or [member_card] with ?member_id=123 in URL
1689
1725
  */
1690
1726
  const MemberCard = ({ id, className = '' }) => {
1691
- const { member, loading, error } = useMember(id || '');
1727
+ // Read from query params as fallback if id not provided in shortcode
1728
+ const [searchParams] = useSearchParams();
1729
+ const memberId = id || searchParams.get('member_id') || '';
1730
+ const { member, loading, error } = useMember(memberId);
1692
1731
  if (loading) {
1693
1732
  return jsxRuntimeExports.jsx("div", { className: `member-card-loading ${className}`, children: "Loading member..." });
1694
1733
  }
@@ -1786,10 +1825,13 @@ const MemberSlideshow = ({ tax, category, role, limit = '5', interval = '5000',
1786
1825
 
1787
1826
  /**
1788
1827
  * TestimonialCard component - displays a single testimonial
1789
- * Usage: [testimonial_card id="123"]
1828
+ * Usage: [testimonial_card id="123"] or [testimonial_card] with ?testimonial_id=123 in URL
1790
1829
  */
1791
1830
  const TestimonialCard = ({ id, className = '' }) => {
1792
- const { testimonial, loading, error } = useTestimonial(id || '');
1831
+ // Read from query params as fallback if id not provided in shortcode
1832
+ const [searchParams] = useSearchParams();
1833
+ const testimonialId = id || searchParams.get('testimonial_id') || '';
1834
+ const { testimonial, loading, error } = useTestimonial(testimonialId);
1793
1835
  if (loading) {
1794
1836
  return jsxRuntimeExports.jsx("div", { className: `testimonial-card-loading ${className}`, children: "Loading testimonial..." });
1795
1837
  }
@@ -1871,5 +1913,5 @@ const TestimonialSlideshow = ({ tax, category, forPostId, limit = '5', interval
1871
1913
  return (jsxRuntimeExports.jsxs("div", { className: `testimonial-slideshow relative ${className}`, children: [jsxRuntimeExports.jsxs("div", { className: "testimonial-slideshow-slide bg-white rounded-lg shadow-md p-8", children: [showContent === 'true' && (jsxRuntimeExports.jsx("div", { className: "testimonial-slideshow-content text-xl mb-6 italic", dangerouslySetInnerHTML: { __html: currentTestimonial.content.rendered } })), jsxRuntimeExports.jsxs("div", { className: "testimonial-slideshow-author", children: [showName === 'true' && (jsxRuntimeExports.jsx("p", { className: "testimonial-slideshow-name text-lg font-bold", children: meta.submitter_name || 'Anonymous' })), showRole === 'true' && meta.submitter_role && (jsxRuntimeExports.jsx("p", { className: "testimonial-slideshow-role text-sm text-gray-600", children: meta.submitter_role })), showBusinessName === 'true' && meta.submitter_business_name && (jsxRuntimeExports.jsx("p", { className: "testimonial-slideshow-business text-sm text-gray-500", children: meta.submitter_business_name })), showCompanyUrl === 'true' && meta.submitter_company && (jsxRuntimeExports.jsx("a", { href: meta.submitter_company, target: "_blank", rel: "noopener noreferrer", className: "testimonial-slideshow-company text-sm text-blue-600 hover:underline", children: meta.submitter_company }))] }), showKudos === 'true' && meta.kudos && meta.kudos.length > 0 && (jsxRuntimeExports.jsx("div", { className: "testimonial-slideshow-kudos mt-4 flex gap-2 justify-center", children: meta.kudos.map((kudo, index) => (jsxRuntimeExports.jsx("span", { className: "text-2xl", title: kudo, children: kudo }, index))) }))] }), testimonials.length > 1 && (jsxRuntimeExports.jsx("div", { className: "testimonial-slideshow-dots flex justify-center gap-2 mt-6", children: testimonials.map((_, index) => (jsxRuntimeExports.jsx("button", { onClick: () => setCurrentIndex(index), className: `w-3 h-3 rounded-full transition-colors ${index === currentIndex ? 'bg-blue-600' : 'bg-gray-300'}`, "aria-label": `Go to slide ${index + 1}` }, index))) }))] }));
1872
1914
  };
1873
1915
 
1874
- export { MemberCard, MemberCardsGrid, MemberSlideshow, TestimonialCard, TestimonialCardsGrid, TestimonialSlideshow, setWordPressApiUrl, useMember, useMembers, useTestimonial, useTestimonials };
1916
+ export { MemberCard, MemberCardsGrid, MemberSlideshow, TestimonialCard, TestimonialCardsGrid, TestimonialSlideshow, setStaticDataProvider, setWordPressApiUrl, useMember, useMembers, useTestimonial, useTestimonials };
1875
1917
  //# sourceMappingURL=index.esm.js.map