@marvalt/shcoder 0.1.1 → 0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"MemberCardsGrid.d.ts","sourceRoot":"","sources":["../../src/components/MemberCardsGrid.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAyF1D,CAAC"}
1
+ {"version":3,"file":"MemberCardsGrid.d.ts","sourceRoot":"","sources":["../../src/components/MemberCardsGrid.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA8F1D,CAAC"}
@@ -7,6 +7,18 @@
7
7
  import type { Member } from '../types/member';
8
8
  import type { ShortcodeAttributes } from '../types/shortcode';
9
9
  export declare function setWordPressApiUrl(url: string): void;
10
+ type StaticDataProvider = () => {
11
+ members: any[];
12
+ getMemberById: (id: string | number) => any | null;
13
+ filterMembers: (filters: {
14
+ category?: string;
15
+ role?: string;
16
+ limit?: number;
17
+ orderby?: string;
18
+ order?: string;
19
+ }) => any[];
20
+ };
21
+ export declare function setStaticDataProvider(provider: StaticDataProvider): void;
10
22
  /**
11
23
  * Hook to fetch members based on shortcode attributes
12
24
  */
@@ -23,4 +35,5 @@ export declare function useMember(id: string | number): {
23
35
  loading: boolean;
24
36
  error: Error | null;
25
37
  };
38
+ export {};
26
39
  //# sourceMappingURL=useMembers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMembers.d.ts","sourceRoot":"","sources":["../../src/hooks/useMembers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAS9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,QAE7C;AAyBD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB;;;;EAsGpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;;;;EAwE5C"}
1
+ {"version":3,"file":"useMembers.d.ts","sourceRoot":"","sources":["../../src/hooks/useMembers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAS9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,QAE7C;AA0BD,KAAK,kBAAkB,GAAG,MAAM;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;IACnD,aAAa,EAAE,CAAC,OAAO,EAAE;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,GAAG,EAAE,CAAC;CACb,CAAC;AAIF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,QAEjE;AAqCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB;;;;EAwGpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;;;;EA0E5C"}
package/dist/index.cjs CHANGED
@@ -37,6 +37,42 @@ function getApiUrl$1() {
37
37
  }
38
38
  // Initialize API URL
39
39
  apiUrl$1 = getApiUrl$1();
40
+ let staticDataProvider = null;
41
+ function setStaticDataProvider(provider) {
42
+ staticDataProvider = provider;
43
+ }
44
+ // Helper function to extract featured image from member data
45
+ function extractFeaturedImage(member) {
46
+ if (member.featured_image_urls) {
47
+ return member.featured_image_urls;
48
+ }
49
+ if (member._embedded?.['wp:featuredmedia']?.[0]) {
50
+ const featuredMedia = member._embedded['wp:featuredmedia'][0];
51
+ return {
52
+ thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
53
+ url: featuredMedia.media_details.sizes.thumbnail.source_url,
54
+ width: featuredMedia.media_details.sizes.thumbnail.width,
55
+ height: featuredMedia.media_details.sizes.thumbnail.height,
56
+ } : undefined,
57
+ medium: featuredMedia.media_details?.sizes?.medium ? {
58
+ url: featuredMedia.media_details.sizes.medium.source_url,
59
+ width: featuredMedia.media_details.sizes.medium.width,
60
+ height: featuredMedia.media_details.sizes.medium.height,
61
+ } : undefined,
62
+ large: featuredMedia.media_details?.sizes?.large ? {
63
+ url: featuredMedia.media_details.sizes.large.source_url,
64
+ width: featuredMedia.media_details.sizes.large.width,
65
+ height: featuredMedia.media_details.sizes.large.height,
66
+ } : undefined,
67
+ full: {
68
+ url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
69
+ width: featuredMedia.media_details?.width || 0,
70
+ height: featuredMedia.media_details?.height || 0,
71
+ },
72
+ };
73
+ }
74
+ return undefined;
75
+ }
40
76
  /**
41
77
  * Hook to fetch members based on shortcode attributes
42
78
  */
@@ -45,15 +81,39 @@ function useMembers(attrs) {
45
81
  const [loading, setLoading] = require$$0.useState(true);
46
82
  const [error, setError] = require$$0.useState(null);
47
83
  require$$0.useEffect(() => {
48
- if (!apiUrl$1) {
49
- setError(new Error('WordPress API URL not configured'));
50
- setLoading(false);
51
- return;
52
- }
53
84
  async function fetchMembers() {
54
85
  try {
55
86
  setLoading(true);
56
87
  setError(null);
88
+ // Use static data if available (preferred method)
89
+ if (staticDataProvider) {
90
+ const provider = staticDataProvider();
91
+ const filtered = provider.filterMembers({
92
+ category: attrs.tax || attrs.category,
93
+ role: attrs.role,
94
+ limit: attrs.limit ? parseInt(attrs.limit, 10) : undefined,
95
+ orderby: attrs.orderby || 'date',
96
+ order: attrs.order || 'desc',
97
+ });
98
+ // Process members to match Member interface
99
+ const processedMembers = filtered.map((member) => {
100
+ const processed = {
101
+ ...member,
102
+ member_meta: member.member_meta || {},
103
+ featured_image_urls: extractFeaturedImage(member),
104
+ };
105
+ return processed;
106
+ });
107
+ setMembers(processedMembers);
108
+ setLoading(false);
109
+ return;
110
+ }
111
+ // Fallback to API (should not happen in production with static data)
112
+ if (!apiUrl$1) {
113
+ setError(new Error('WordPress API URL not configured and no static data provider available'));
114
+ setLoading(false);
115
+ return;
116
+ }
57
117
  // Build query params from shortcode attributes
58
118
  const params = {
59
119
  per_page: (attrs.limit ? parseInt(attrs.limit, 10) : 100).toString(),
@@ -86,33 +146,8 @@ function useMembers(attrs) {
86
146
  const processed = {
87
147
  ...member,
88
148
  member_meta: member.member_meta || {},
149
+ featured_image_urls: extractFeaturedImage(member),
89
150
  };
90
- // Extract featured image from _embedded
91
- if (member._embedded && member._embedded['wp:featuredmedia'] && member._embedded['wp:featuredmedia'][0]) {
92
- const featuredMedia = member._embedded['wp:featuredmedia'][0];
93
- processed.featured_image_urls = {
94
- thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
95
- url: featuredMedia.media_details.sizes.thumbnail.source_url,
96
- width: featuredMedia.media_details.sizes.thumbnail.width,
97
- height: featuredMedia.media_details.sizes.thumbnail.height,
98
- } : undefined,
99
- medium: featuredMedia.media_details?.sizes?.medium ? {
100
- url: featuredMedia.media_details.sizes.medium.source_url,
101
- width: featuredMedia.media_details.sizes.medium.width,
102
- height: featuredMedia.media_details.sizes.medium.height,
103
- } : undefined,
104
- large: featuredMedia.media_details?.sizes?.large ? {
105
- url: featuredMedia.media_details.sizes.large.source_url,
106
- width: featuredMedia.media_details.sizes.large.width,
107
- height: featuredMedia.media_details.sizes.large.height,
108
- } : undefined,
109
- full: {
110
- url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
111
- width: featuredMedia.media_details?.width || 0,
112
- height: featuredMedia.media_details?.height || 0,
113
- },
114
- };
115
- }
116
151
  return processed;
117
152
  });
118
153
  setMembers(processedMembers);
@@ -137,7 +172,7 @@ function useMember(id) {
137
172
  const [loading, setLoading] = require$$0.useState(true);
138
173
  const [error, setError] = require$$0.useState(null);
139
174
  require$$0.useEffect(() => {
140
- if (!apiUrl$1 || !id) {
175
+ if (!id) {
141
176
  setLoading(false);
142
177
  return;
143
178
  }
@@ -145,6 +180,31 @@ function useMember(id) {
145
180
  try {
146
181
  setLoading(true);
147
182
  setError(null);
183
+ // Use static data if available (preferred method)
184
+ if (staticDataProvider) {
185
+ const provider = staticDataProvider();
186
+ const found = provider.getMemberById(id);
187
+ if (found) {
188
+ // Process member to match Member interface
189
+ const processed = {
190
+ ...found,
191
+ member_meta: found.member_meta || {},
192
+ featured_image_urls: extractFeaturedImage(found),
193
+ };
194
+ setMember(processed);
195
+ }
196
+ else {
197
+ setMember(null);
198
+ }
199
+ setLoading(false);
200
+ return;
201
+ }
202
+ // Fallback to API (should not happen in production with static data)
203
+ if (!apiUrl$1) {
204
+ setError(new Error('WordPress API URL not configured and no static data provider available'));
205
+ setLoading(false);
206
+ return;
207
+ }
148
208
  const response = await fetch(`${apiUrl$1}/wp/v2/member/${id}?_embed=true`);
149
209
  if (!response.ok) {
150
210
  throw new Error(`Failed to fetch member: ${response.statusText}`);
@@ -154,33 +214,8 @@ function useMember(id) {
154
214
  const processed = {
155
215
  ...data,
156
216
  member_meta: data.member_meta || {},
217
+ featured_image_urls: extractFeaturedImage(data),
157
218
  };
158
- // Extract featured image from _embedded
159
- if (data._embedded && data._embedded['wp:featuredmedia'] && data._embedded['wp:featuredmedia'][0]) {
160
- const featuredMedia = data._embedded['wp:featuredmedia'][0];
161
- processed.featured_image_urls = {
162
- thumbnail: featuredMedia.media_details?.sizes?.thumbnail ? {
163
- url: featuredMedia.media_details.sizes.thumbnail.source_url,
164
- width: featuredMedia.media_details.sizes.thumbnail.width,
165
- height: featuredMedia.media_details.sizes.thumbnail.height,
166
- } : undefined,
167
- medium: featuredMedia.media_details?.sizes?.medium ? {
168
- url: featuredMedia.media_details.sizes.medium.source_url,
169
- width: featuredMedia.media_details.sizes.medium.width,
170
- height: featuredMedia.media_details.sizes.medium.height,
171
- } : undefined,
172
- large: featuredMedia.media_details?.sizes?.large ? {
173
- url: featuredMedia.media_details.sizes.large.source_url,
174
- width: featuredMedia.media_details.sizes.large.width,
175
- height: featuredMedia.media_details.sizes.large.height,
176
- } : undefined,
177
- full: {
178
- url: featuredMedia.source_url || featuredMedia.media_details?.sizes?.full?.source_url || '',
179
- width: featuredMedia.media_details?.width || 0,
180
- height: featuredMedia.media_details?.height || 0,
181
- },
182
- };
183
- }
184
219
  setMember(processed);
185
220
  }
186
221
  catch (err) {
@@ -1707,6 +1742,37 @@ const MemberCard = ({ id, className = '' }) => {
1707
1742
  return (jsxRuntimeExports.jsxs("div", { className: `member-card ${className}`, children: [imageUrl && (jsxRuntimeExports.jsx("div", { className: "member-card-image", children: jsxRuntimeExports.jsx("img", { src: imageUrl, alt: fullName, className: "w-full h-auto rounded-lg" }) })), jsxRuntimeExports.jsxs("div", { className: "member-card-content", children: [jsxRuntimeExports.jsx("h3", { className: "member-card-name", children: fullName }), meta.member_role && jsxRuntimeExports.jsx("p", { className: "member-card-role", children: meta.member_role }), meta.business_name && jsxRuntimeExports.jsx("p", { className: "member-card-company", children: meta.business_name }), meta.tagline && jsxRuntimeExports.jsx("p", { className: "member-card-tagline", children: meta.tagline }), meta.member_bio && (jsxRuntimeExports.jsx("div", { className: "member-card-bio", dangerouslySetInnerHTML: { __html: meta.member_bio } })), meta.website && (jsxRuntimeExports.jsx("a", { href: meta.website, target: "_blank", rel: "noopener noreferrer", className: "member-card-website", children: "Visit Website" }))] })] }));
1708
1743
  };
1709
1744
 
1745
+ /**
1746
+ * Cloudflare Images variant URL helper for member card images.
1747
+ * Only Cloudflare URLs (imagedelivery.net) are supported; WordPress URLs are not used.
1748
+ */
1749
+ function isCloudflareImageUrl(url) {
1750
+ if (!url)
1751
+ return false;
1752
+ try {
1753
+ const u = new URL(url);
1754
+ return u.hostname.toLowerCase().includes('imagedelivery.net');
1755
+ }
1756
+ catch {
1757
+ return false;
1758
+ }
1759
+ }
1760
+ /**
1761
+ * Append Cloudflare Images variant (e.g. w=720,h=1280 for 9:16) to the base URL.
1762
+ * Returns the original url if it is not a Cloudflare URL.
1763
+ */
1764
+ function getCloudflareVariantUrl(url, options) {
1765
+ if (!isCloudflareImageUrl(url))
1766
+ return url;
1767
+ if (/\/w=\d+/.test(url) || /\/(public|thumbnail|banner|avatar)/.test(url)) {
1768
+ return url;
1769
+ }
1770
+ const { width, height } = options;
1771
+ const base = url.endsWith('/') ? url.slice(0, -1) : url;
1772
+ const variant = `w=${Math.max(1, Math.floor(width))}` + (`,h=${Math.max(1, Math.floor(height))}` );
1773
+ return `${base}/${variant}`;
1774
+ }
1775
+
1710
1776
  /**
1711
1777
  * MemberCardsGrid component - displays multiple members in a grid
1712
1778
  * Usage: [member_cards tax="leadership" cols="3" image="true"]
@@ -1739,12 +1805,16 @@ const MemberCardsGrid = ({ tax, category, role, cols = '3', image = 'true', limi
1739
1805
  }[colsNum] || 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3';
1740
1806
  return (jsxRuntimeExports.jsx("div", { className: `member-cards-grid grid ${gridCols} gap-6 ${className}`, children: members.map((member) => {
1741
1807
  const meta = member.member_meta || {};
1742
- const imageUrl = showImage
1808
+ const rawImageUrl = showImage
1743
1809
  ? (member.featured_image_urls?.medium?.url || member.featured_image_urls?.full?.url)
1744
1810
  : null;
1811
+ // Only use Cloudflare URLs; request 9:16 at 720x1280 for sharp display
1812
+ const imageUrl = rawImageUrl && isCloudflareImageUrl(rawImageUrl)
1813
+ ? getCloudflareVariantUrl(rawImageUrl, { width: 720, height: 1280 })
1814
+ : null;
1745
1815
  const fullName = [meta.members_firstname, meta.members_last_name].filter(Boolean).join(' ')
1746
1816
  || member.title.rendered;
1747
- return (jsxRuntimeExports.jsxs("div", { className: "member-card bg-white rounded-lg shadow-md overflow-hidden", children: [imageUrl && (jsxRuntimeExports.jsx("div", { className: "member-card-image", children: jsxRuntimeExports.jsx("img", { src: imageUrl, alt: fullName, className: "w-full h-48 object-cover" }) })), jsxRuntimeExports.jsxs("div", { className: "member-card-content p-6", children: [jsxRuntimeExports.jsx("h3", { className: "member-card-name text-xl font-bold mb-2", children: fullName }), meta.member_role && (jsxRuntimeExports.jsx("p", { className: "member-card-role text-gray-600 mb-2", children: meta.member_role })), meta.business_name && (jsxRuntimeExports.jsx("p", { className: "member-card-company text-sm text-gray-500 mb-2", children: meta.business_name })), meta.tagline && (jsxRuntimeExports.jsx("p", { className: "member-card-tagline text-sm italic mb-3", children: meta.tagline })), meta.member_pitch && (jsxRuntimeExports.jsx("p", { className: "member-card-pitch text-sm mb-3 line-clamp-3", children: meta.member_pitch })), meta.website && (jsxRuntimeExports.jsx("a", { href: meta.website, target: "_blank", rel: "noopener noreferrer", className: "member-card-website text-blue-600 hover:underline text-sm", children: "Visit Website \u2192" }))] })] }, member.id));
1817
+ return (jsxRuntimeExports.jsxs("div", { className: "member-card bg-white rounded-lg shadow-md overflow-hidden", children: [imageUrl && (jsxRuntimeExports.jsx("div", { className: "member-card-image aspect-[9/16] w-full overflow-hidden bg-slate-100", children: jsxRuntimeExports.jsx("img", { src: imageUrl, alt: fullName, className: "h-full w-full object-cover" }) })), jsxRuntimeExports.jsxs("div", { className: "member-card-content p-6", children: [jsxRuntimeExports.jsx("h3", { className: "member-card-name text-xl font-bold mb-2", children: fullName }), meta.member_role && (jsxRuntimeExports.jsx("p", { className: "member-card-role text-gray-600 mb-2", children: meta.member_role })), meta.business_name && (jsxRuntimeExports.jsx("p", { className: "member-card-company text-sm text-gray-500 mb-2", children: meta.business_name })), meta.tagline && (jsxRuntimeExports.jsx("p", { className: "member-card-tagline text-sm italic mb-3", children: meta.tagline })), meta.member_pitch && (jsxRuntimeExports.jsx("p", { className: "member-card-pitch text-sm mb-3 line-clamp-3", children: meta.member_pitch })), meta.website && (jsxRuntimeExports.jsx("a", { href: meta.website, target: "_blank", rel: "noopener noreferrer", className: "member-card-website text-blue-600 hover:underline text-sm", children: "Visit Website \u2192" }))] })] }, member.id));
1748
1818
  }) }));
1749
1819
  };
1750
1820
 
@@ -1886,6 +1956,7 @@ exports.MemberSlideshow = MemberSlideshow;
1886
1956
  exports.TestimonialCard = TestimonialCard;
1887
1957
  exports.TestimonialCardsGrid = TestimonialCardsGrid;
1888
1958
  exports.TestimonialSlideshow = TestimonialSlideshow;
1959
+ exports.setStaticDataProvider = setStaticDataProvider;
1889
1960
  exports.setWordPressApiUrl = setWordPressApiUrl;
1890
1961
  exports.useMember = useMember;
1891
1962
  exports.useMembers = useMembers;