@tecof/theme-editor 0.0.22 → 0.0.24

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.d.mts CHANGED
@@ -206,6 +206,14 @@ declare class TecofApiClient {
206
206
  code: string;
207
207
  value: string;
208
208
  }[]>>;
209
+ /**
210
+ * Get a component preview screenshot as a Blob URL.
211
+ * Calls POST /api/store/component-preview with domain + componentName.
212
+ * Returns a blob:// URL that can be used as an img src.
213
+ * Results are cached client-side in a Map.
214
+ */
215
+ private previewBlobCache;
216
+ getComponentPreview(domain: string, componentName: string): Promise<string | null>;
209
217
  /** CDN base URL (defaults to apiUrl if not set) */
210
218
  get cdnUrl(): string;
211
219
  }
package/dist/index.d.ts CHANGED
@@ -206,6 +206,14 @@ declare class TecofApiClient {
206
206
  code: string;
207
207
  value: string;
208
208
  }[]>>;
209
+ /**
210
+ * Get a component preview screenshot as a Blob URL.
211
+ * Calls POST /api/store/component-preview with domain + componentName.
212
+ * Returns a blob:// URL that can be used as an img src.
213
+ * Results are cached client-side in a Map.
214
+ */
215
+ private previewBlobCache;
216
+ getComponentPreview(domain: string, componentName: string): Promise<string | null>;
209
217
  /** CDN base URL (defaults to apiUrl if not set) */
210
218
  get cdnUrl(): string;
211
219
  }
package/dist/index.js CHANGED
@@ -65,6 +65,13 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
65
65
  // src/api.ts
66
66
  var TecofApiClient = class {
67
67
  constructor(apiUrl, secretKey, customCdnUrl) {
68
+ /**
69
+ * Get a component preview screenshot as a Blob URL.
70
+ * Calls POST /api/store/component-preview with domain + componentName.
71
+ * Returns a blob:// URL that can be used as an img src.
72
+ * Results are cached client-side in a Map.
73
+ */
74
+ this.previewBlobCache = /* @__PURE__ */ new Map();
68
75
  this.apiUrl = apiUrl.replace(/\/+$/, "");
69
76
  this.secretKey = secretKey;
70
77
  this.customCdnUrl = customCdnUrl ? customCdnUrl.replace(/\/+$/, "") : void 0;
@@ -228,6 +235,30 @@ var TecofApiClient = class {
228
235
  };
229
236
  }
230
237
  }
238
+ async getComponentPreview(domain, componentName) {
239
+ const cacheKey = `${domain}:${componentName}`;
240
+ if (this.previewBlobCache.has(cacheKey)) {
241
+ return this.previewBlobCache.get(cacheKey);
242
+ }
243
+ try {
244
+ const res2 = await fetch(`${this.apiUrl}/api/store/component-preview`, {
245
+ method: "POST",
246
+ headers: {
247
+ "x-secret-key": this.secretKey,
248
+ Accept: "image/png",
249
+ "Content-Type": "application/json"
250
+ },
251
+ body: JSON.stringify({ domain, componentName })
252
+ });
253
+ if (!res2.ok) return null;
254
+ const blob2 = await res2.blob();
255
+ const blobUrl = URL.createObjectURL(blob2);
256
+ this.previewBlobCache.set(cacheKey, blobUrl);
257
+ return blobUrl;
258
+ } catch {
259
+ return null;
260
+ }
261
+ }
231
262
  /** CDN base URL (defaults to apiUrl if not set) */
232
263
  get cdnUrl() {
233
264
  return this.customCdnUrl || this.apiUrl;
@@ -254,6 +285,55 @@ function useTecof() {
254
285
  return ctx;
255
286
  }
256
287
  var EMPTY_PAGE = { content: [], root: { props: {} }, zones: {} };
288
+ var ComponentDrawerItem = ({
289
+ name: name3,
290
+ apiClient,
291
+ children
292
+ }) => {
293
+ const [imgSrc, setImgSrc] = React__default.useState(null);
294
+ const [loading, setLoading] = React__default.useState(false);
295
+ const [error2, setError] = React__default.useState(false);
296
+ const fetchedRef = React__default.useRef(false);
297
+ const handleMouseEnter = React__default.useCallback(async () => {
298
+ if (fetchedRef.current) return;
299
+ fetchedRef.current = true;
300
+ setLoading(true);
301
+ try {
302
+ const domain = typeof window !== "undefined" ? window.location.hostname : "";
303
+ const blobUrl = await apiClient.getComponentPreview(domain, name3);
304
+ if (blobUrl) {
305
+ setImgSrc(blobUrl);
306
+ } else {
307
+ setError(true);
308
+ }
309
+ } catch {
310
+ setError(true);
311
+ } finally {
312
+ setLoading(false);
313
+ }
314
+ }, [name3, apiClient]);
315
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-item-group group", onMouseEnter: handleMouseEnter, children: [
316
+ children,
317
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover", children: [
318
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover-header", children: [
319
+ name3,
320
+ " \xD6nizleme"
321
+ ] }),
322
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover-body", children: [
323
+ (loading || !imgSrc && !error2) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drawer-skeleton" }),
324
+ imgSrc && /* @__PURE__ */ jsxRuntime.jsx(
325
+ "img",
326
+ {
327
+ src: imgSrc,
328
+ alt: `${name3} preview`,
329
+ className: "tecof-drawer-img"
330
+ }
331
+ ),
332
+ error2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drawer-preview-error", children: "\xD6nizleme y\xFCklenemedi" })
333
+ ] })
334
+ ] })
335
+ ] });
336
+ };
257
337
  var TecofEditor = ({
258
338
  pageId,
259
339
  config: config3,
@@ -395,36 +475,7 @@ var TecofEditor = ({
395
475
  const mergedOverrides = {
396
476
  header: () => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}),
397
477
  drawerItem: ({ children, name: name3 }) => {
398
- const token = secretKey;
399
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-item-group group", children: [
400
- children,
401
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover", children: [
402
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover-header", children: [
403
- name3,
404
- " \xD6nizleme"
405
- ] }),
406
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-drawer-popover-body", children: [
407
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drawer-skeleton" }),
408
- /* @__PURE__ */ jsxRuntime.jsx(
409
- "img",
410
- {
411
- src: `/api/screenshot?componentName=${name3}&token=${token}`,
412
- alt: `${name3} preview`,
413
- className: "tecof-drawer-img",
414
- onLoad: (e3) => {
415
- const loader2 = e3.currentTarget.previousElementSibling;
416
- if (loader2) loader2.remove();
417
- },
418
- onError: (e3) => {
419
- const loader2 = e3.currentTarget.previousElementSibling;
420
- if (loader2) loader2.remove();
421
- e3.currentTarget.style.display = "none";
422
- }
423
- }
424
- )
425
- ] })
426
- ] })
427
- ] });
478
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentDrawerItem, { name: name3, apiClient, children });
428
479
  },
429
480
  ...overrides || {}
430
481
  };
@@ -933,8 +984,11 @@ var LanguageField = ({
933
984
  return existing || { code, value: "" };
934
985
  });
935
986
  }, [value, merchantInfo]);
987
+ const valuesRef = React__default.useRef(values);
988
+ valuesRef.current = values;
936
989
  const handleChange = React__default.useCallback((code, newVal) => {
937
- const updated = [...values];
990
+ const current = valuesRef.current;
991
+ const updated = [...current];
938
992
  const idx = updated.findIndex((v2) => v2.code === code);
939
993
  if (idx >= 0) {
940
994
  updated[idx] = { ...updated[idx], value: newVal };
@@ -942,10 +996,10 @@ var LanguageField = ({
942
996
  updated.push({ code, value: newVal });
943
997
  }
944
998
  onChange(updated);
945
- }, [values, onChange]);
999
+ }, [onChange]);
946
1000
  const getCurrentText = React__default.useCallback(() => {
947
- return values.find((v2) => v2.code === activeTab)?.value || "";
948
- }, [values, activeTab]);
1001
+ return valuesRef.current.find((v2) => v2.code === activeTab)?.value || "";
1002
+ }, [activeTab]);
949
1003
  const handleFastFill = React__default.useCallback(() => {
950
1004
  const text2 = getCurrentText();
951
1005
  if (!text2) return;
@@ -968,7 +1022,7 @@ var LanguageField = ({
968
1022
  try {
969
1023
  const res2 = await apiClient.translate(text2, activeTab, otherLocales, isHtml);
970
1024
  if (res2.success && Array.isArray(res2.data)) {
971
- const updated = [...values];
1025
+ const updated = [...valuesRef.current];
972
1026
  for (const t2 of res2.data) {
973
1027
  const idx = updated.findIndex((v2) => v2.code === t2.code);
974
1028
  if (idx >= 0) {
@@ -988,7 +1042,7 @@ var LanguageField = ({
988
1042
  setTranslating(false);
989
1043
  setTimeout(() => setStatusMsg(null), 3e3);
990
1044
  }
991
- }, [getCurrentText, merchantInfo, activeTab, values, onChange, apiClient, isHtml]);
1045
+ }, [getCurrentText, merchantInfo, activeTab, onChange, apiClient, isHtml]);
992
1046
  if (loading) return /* @__PURE__ */ jsxRuntime.jsx(FieldLoading, {});
993
1047
  if (error2 && !merchantInfo) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-lang-error", children: error2 });
994
1048
  if (!merchantInfo) return null;