@foxpixel/react 0.2.0 → 0.2.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.d.mts +49 -26
- package/dist/index.d.ts +49 -26
- package/dist/index.js +419 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +399 -181
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/context/FoxPixelContext.tsx
|
|
2
|
-
import { createContext, useContext, useMemo } from "react";
|
|
2
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
3
3
|
|
|
4
4
|
// src/client/http.ts
|
|
5
5
|
import axios from "axios";
|
|
@@ -111,15 +111,21 @@ var FoxPixelHttpClient = class {
|
|
|
111
111
|
|
|
112
112
|
// src/context/FoxPixelContext.tsx
|
|
113
113
|
import { jsx } from "react/jsx-runtime";
|
|
114
|
+
if (!React || typeof React.useMemo !== "function") {
|
|
115
|
+
throw new Error(
|
|
116
|
+
'@foxpixel/react: React is not available. Ensure your app uses a single React instance and the SDK is not bundled with a different React. In Next.js use transpilePackages: ["@foxpixel/react"] and ensure react/react-dom resolve to one module (see next.config.js).'
|
|
117
|
+
);
|
|
118
|
+
}
|
|
114
119
|
var FoxPixelContext = createContext(null);
|
|
115
|
-
function FoxPixelProvider({ children, config = {} }) {
|
|
120
|
+
function FoxPixelProvider({ children, config = {}, queryClient }) {
|
|
116
121
|
const client = useMemo(() => {
|
|
117
122
|
return new FoxPixelHttpClient(config);
|
|
118
123
|
}, [config.apiUrl, config.apiKey, config.tenantId]);
|
|
119
124
|
const value = useMemo(() => ({
|
|
120
125
|
client,
|
|
121
|
-
config
|
|
122
|
-
|
|
126
|
+
config,
|
|
127
|
+
queryClient: queryClient ?? null
|
|
128
|
+
}), [client, config, queryClient]);
|
|
123
129
|
return /* @__PURE__ */ jsx(FoxPixelContext.Provider, { value, children });
|
|
124
130
|
}
|
|
125
131
|
function useFoxPixelContext() {
|
|
@@ -346,12 +352,33 @@ function withAuth(Component, options = {}) {
|
|
|
346
352
|
}
|
|
347
353
|
|
|
348
354
|
// src/components/Editable.tsx
|
|
349
|
-
import { createElement, useCallback as useCallback3 } from "react";
|
|
355
|
+
import { createElement, useCallback as useCallback3, useState as useState7, useEffect as useEffect7 } from "react";
|
|
350
356
|
|
|
351
357
|
// src/hooks/useEditMode.ts
|
|
352
358
|
import { useEffect as useEffect5, useState as useState5, useCallback as useCallback2 } from "react";
|
|
353
|
-
import { useQueryClient } from "@tanstack/react-query";
|
|
354
359
|
var SITE_CONTENT_QUERY_KEY = "siteContent";
|
|
360
|
+
var contentKeysOnPage = /* @__PURE__ */ new Set();
|
|
361
|
+
var flushTimer = null;
|
|
362
|
+
function scheduleFlushContentKeys() {
|
|
363
|
+
if (flushTimer) return;
|
|
364
|
+
flushTimer = setTimeout(() => {
|
|
365
|
+
flushTimer = null;
|
|
366
|
+
if (typeof window !== "undefined" && window.parent !== window) {
|
|
367
|
+
window.parent.postMessage(
|
|
368
|
+
{ type: "FOXPIXEL_READY", payload: { contentKeys: Array.from(contentKeysOnPage) } },
|
|
369
|
+
"*"
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
}, 150);
|
|
373
|
+
}
|
|
374
|
+
function registerContentKey(key) {
|
|
375
|
+
contentKeysOnPage.add(key);
|
|
376
|
+
scheduleFlushContentKeys();
|
|
377
|
+
}
|
|
378
|
+
function unregisterContentKey(key) {
|
|
379
|
+
contentKeysOnPage.delete(key);
|
|
380
|
+
scheduleFlushContentKeys();
|
|
381
|
+
}
|
|
355
382
|
function useEditMode() {
|
|
356
383
|
const [isEditMode, setIsEditMode] = useState5(false);
|
|
357
384
|
useEffect5(() => {
|
|
@@ -362,18 +389,29 @@ function useEditMode() {
|
|
|
362
389
|
return isEditMode;
|
|
363
390
|
}
|
|
364
391
|
function useEditModeMessaging() {
|
|
365
|
-
const
|
|
392
|
+
const ctx = useFoxPixelContext();
|
|
393
|
+
const queryClient = ctx?.queryClient ?? null;
|
|
366
394
|
const isEditMode = useEditMode();
|
|
367
395
|
useEffect5(() => {
|
|
368
396
|
if (!isEditMode || typeof window === "undefined") return;
|
|
369
397
|
window.parent.postMessage({ type: "FOXPIXEL_READY" }, "*");
|
|
370
398
|
const handleMessage = (event) => {
|
|
399
|
+
if (!queryClient) return;
|
|
371
400
|
const { type, payload } = event.data || {};
|
|
372
|
-
if (type
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
401
|
+
if (type !== "FOXPIXEL_CONTENT_UPDATED" || !payload?.contentKey) return;
|
|
402
|
+
const { contentKey, newValue } = payload;
|
|
403
|
+
if (typeof newValue === "string") {
|
|
404
|
+
queryClient.setQueryData(
|
|
405
|
+
[SITE_CONTENT_QUERY_KEY, contentKey],
|
|
406
|
+
(prev) => ({
|
|
407
|
+
value: newValue,
|
|
408
|
+
contentType: prev?.contentType ?? "TEXT"
|
|
409
|
+
})
|
|
410
|
+
);
|
|
376
411
|
}
|
|
412
|
+
queryClient.invalidateQueries({
|
|
413
|
+
queryKey: [SITE_CONTENT_QUERY_KEY, contentKey]
|
|
414
|
+
});
|
|
377
415
|
};
|
|
378
416
|
window.addEventListener("message", handleMessage);
|
|
379
417
|
return () => window.removeEventListener("message", handleMessage);
|
|
@@ -406,16 +444,40 @@ function useSendEditRequest() {
|
|
|
406
444
|
}
|
|
407
445
|
|
|
408
446
|
// src/hooks/useSiteContentQuery.ts
|
|
409
|
-
import {
|
|
447
|
+
import { useState as useState6, useEffect as useEffect6, useRef } from "react";
|
|
448
|
+
function getCached(queryClient, contentKey) {
|
|
449
|
+
const data = queryClient.getQueryData([
|
|
450
|
+
SITE_CONTENT_QUERY_KEY,
|
|
451
|
+
contentKey
|
|
452
|
+
]);
|
|
453
|
+
if (data == null) return void 0;
|
|
454
|
+
return { value: data.value ?? "", contentType: data.contentType ?? "TEXT" };
|
|
455
|
+
}
|
|
410
456
|
function useSiteContentQuery(contentKey, options) {
|
|
411
457
|
const { defaultValue } = options;
|
|
412
|
-
const { client } = useFoxPixelContext();
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
458
|
+
const { client, queryClient } = useFoxPixelContext();
|
|
459
|
+
const [state, setState] = useState6(() => {
|
|
460
|
+
if (queryClient) {
|
|
461
|
+
const cached = getCached(queryClient, contentKey);
|
|
462
|
+
if (cached) {
|
|
463
|
+
return { value: cached.value, isLoading: false, contentType: cached.contentType };
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return { value: defaultValue, isLoading: true, contentType: "TEXT" };
|
|
467
|
+
});
|
|
468
|
+
const contentKeyRef = useRef(contentKey);
|
|
469
|
+
contentKeyRef.current = contentKey;
|
|
470
|
+
useEffect6(() => {
|
|
471
|
+
if (!queryClient) {
|
|
472
|
+
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const key = contentKeyRef.current;
|
|
476
|
+
const queryKey = [SITE_CONTENT_QUERY_KEY, key];
|
|
477
|
+
const queryFn = async () => {
|
|
416
478
|
try {
|
|
417
479
|
const content = await client.get(
|
|
418
|
-
`/api/site/content/${encodeURIComponent(
|
|
480
|
+
`/api/site/content/${encodeURIComponent(key)}`
|
|
419
481
|
);
|
|
420
482
|
if (!content) return null;
|
|
421
483
|
return {
|
|
@@ -423,23 +485,50 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
423
485
|
contentType: content.contentType ?? "TEXT"
|
|
424
486
|
};
|
|
425
487
|
} catch (err) {
|
|
426
|
-
const status = err?.status;
|
|
488
|
+
const status = err?.response?.status;
|
|
427
489
|
if (status === 404) return null;
|
|
428
490
|
throw err;
|
|
429
491
|
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
492
|
+
};
|
|
493
|
+
let cancelled = false;
|
|
494
|
+
queryClient.fetchQuery({
|
|
495
|
+
queryKey,
|
|
496
|
+
queryFn,
|
|
497
|
+
staleTime: 1e3 * 60 * 5,
|
|
498
|
+
retry: 1
|
|
499
|
+
}).then((data) => {
|
|
500
|
+
if (cancelled) return;
|
|
501
|
+
setState({
|
|
502
|
+
value: data?.value ?? defaultValue,
|
|
503
|
+
isLoading: false,
|
|
504
|
+
contentType: data?.contentType ?? "TEXT"
|
|
505
|
+
});
|
|
506
|
+
}).catch(() => {
|
|
507
|
+
if (cancelled) return;
|
|
508
|
+
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
509
|
+
});
|
|
510
|
+
const unsub = queryClient.getQueryCache().subscribe((event) => {
|
|
511
|
+
if (event?.type === "updated" && event?.query?.queryKey[1] === key) {
|
|
512
|
+
const cached = getCached(queryClient, key);
|
|
513
|
+
if (cached && !cancelled) {
|
|
514
|
+
setState({
|
|
515
|
+
value: cached.value,
|
|
516
|
+
isLoading: false,
|
|
517
|
+
contentType: cached.contentType
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
return () => {
|
|
523
|
+
cancelled = true;
|
|
524
|
+
unsub();
|
|
525
|
+
};
|
|
526
|
+
}, [queryClient, contentKey, defaultValue, client]);
|
|
527
|
+
return state;
|
|
439
528
|
}
|
|
440
529
|
|
|
441
530
|
// src/utils/sanitize.ts
|
|
442
|
-
import
|
|
531
|
+
import sanitizeHtmlLib from "sanitize-html";
|
|
443
532
|
var DEFAULT_ALLOWED_TAGS = [
|
|
444
533
|
"p",
|
|
445
534
|
"br",
|
|
@@ -470,13 +559,16 @@ var DEFAULT_ALLOWED_TAGS = [
|
|
|
470
559
|
"th",
|
|
471
560
|
"td"
|
|
472
561
|
];
|
|
473
|
-
var DEFAULT_ALLOWED_ATTR =
|
|
562
|
+
var DEFAULT_ALLOWED_ATTR = {
|
|
563
|
+
a: ["href", "target", "rel", "title"],
|
|
564
|
+
img: ["src", "alt", "title", "width", "height"],
|
|
565
|
+
"*": ["class"]
|
|
566
|
+
};
|
|
474
567
|
function sanitizeHtml(html) {
|
|
475
568
|
if (typeof html !== "string") return "";
|
|
476
|
-
return
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
ADD_ATTR: ["target"]
|
|
569
|
+
return sanitizeHtmlLib(html, {
|
|
570
|
+
allowedTags: DEFAULT_ALLOWED_TAGS,
|
|
571
|
+
allowedAttributes: DEFAULT_ALLOWED_ATTR
|
|
480
572
|
});
|
|
481
573
|
}
|
|
482
574
|
|
|
@@ -486,7 +578,24 @@ function cn(...args) {
|
|
|
486
578
|
}
|
|
487
579
|
|
|
488
580
|
// src/components/Editable.tsx
|
|
489
|
-
import {
|
|
581
|
+
import { jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
582
|
+
var EDIT_MODE_TOOLTIP_STYLE = {
|
|
583
|
+
position: "absolute",
|
|
584
|
+
top: "-28px",
|
|
585
|
+
left: "50%",
|
|
586
|
+
transform: "translateX(-50%)",
|
|
587
|
+
fontSize: "10px",
|
|
588
|
+
fontFamily: "system-ui, sans-serif",
|
|
589
|
+
padding: "4px 8px",
|
|
590
|
+
backgroundColor: "rgb(37 99 235)",
|
|
591
|
+
color: "white",
|
|
592
|
+
borderRadius: "4px",
|
|
593
|
+
whiteSpace: "nowrap",
|
|
594
|
+
pointerEvents: "none",
|
|
595
|
+
zIndex: 100,
|
|
596
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.2)",
|
|
597
|
+
transition: "opacity 0.15s ease"
|
|
598
|
+
};
|
|
490
599
|
function Editable({
|
|
491
600
|
contentKey,
|
|
492
601
|
defaultValue,
|
|
@@ -494,12 +603,19 @@ function Editable({
|
|
|
494
603
|
multiline = false,
|
|
495
604
|
className
|
|
496
605
|
}) {
|
|
606
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
497
607
|
const isEditMode = useEditModeMessaging();
|
|
498
608
|
const sendEditRequest = useSendEditRequest();
|
|
499
609
|
const { value, isLoading, contentType } = useSiteContentQuery(contentKey, {
|
|
500
610
|
defaultValue
|
|
501
611
|
});
|
|
502
612
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
613
|
+
useEffect7(() => {
|
|
614
|
+
if (isEditMode) {
|
|
615
|
+
registerContentKey(contentKey);
|
|
616
|
+
return () => unregisterContentKey(contentKey);
|
|
617
|
+
}
|
|
618
|
+
}, [isEditMode, contentKey]);
|
|
503
619
|
const handleClick = useCallback3(
|
|
504
620
|
(e) => {
|
|
505
621
|
if (isEditMode) {
|
|
@@ -527,36 +643,59 @@ function Editable({
|
|
|
527
643
|
"aria-label": "Loading content..."
|
|
528
644
|
});
|
|
529
645
|
}
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
646
|
+
const editModeWrapperStyle = isEditMode ? {
|
|
647
|
+
position: "relative",
|
|
648
|
+
display: "inline",
|
|
649
|
+
cursor: "pointer",
|
|
650
|
+
borderRadius: "2px",
|
|
651
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
652
|
+
outlineOffset: "2px",
|
|
653
|
+
backgroundColor: isHovered ? "rgba(59 130 246 / 0.08)" : void 0
|
|
654
|
+
} : {};
|
|
655
|
+
const tooltipSpan = isEditMode ? /* @__PURE__ */ jsx6(
|
|
656
|
+
"span",
|
|
657
|
+
{
|
|
658
|
+
style: {
|
|
659
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
660
|
+
opacity: isHovered ? 1 : 0
|
|
661
|
+
},
|
|
662
|
+
"aria-hidden": true,
|
|
663
|
+
children: "Click to edit"
|
|
664
|
+
}
|
|
665
|
+
) : null;
|
|
666
|
+
const hoverHandlers = isEditMode ? {
|
|
667
|
+
onMouseEnter: () => setIsHovered(true),
|
|
668
|
+
onMouseLeave: () => setIsHovered(false)
|
|
669
|
+
} : {};
|
|
536
670
|
if (multiline && value.includes("\n")) {
|
|
537
671
|
const safeBr = sanitizeHtml(value.replace(/\n/g, "<br />"));
|
|
538
|
-
return createElement(
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
672
|
+
return createElement(
|
|
673
|
+
"span",
|
|
674
|
+
{ style: editModeWrapperStyle, ...hoverHandlers },
|
|
675
|
+
createElement(as, {
|
|
676
|
+
className,
|
|
677
|
+
"data-content-key": contentKey,
|
|
678
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
679
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
680
|
+
dangerouslySetInnerHTML: { __html: safeBr }
|
|
681
|
+
}),
|
|
682
|
+
tooltipSpan
|
|
683
|
+
);
|
|
546
684
|
}
|
|
547
685
|
return createElement(
|
|
548
|
-
|
|
549
|
-
{
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
686
|
+
"span",
|
|
687
|
+
{ style: editModeWrapperStyle, ...hoverHandlers },
|
|
688
|
+
createElement(
|
|
689
|
+
as,
|
|
690
|
+
{
|
|
691
|
+
className,
|
|
692
|
+
"data-content-key": contentKey,
|
|
693
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
694
|
+
onClick: isEditMode ? handleClick : void 0
|
|
695
|
+
},
|
|
696
|
+
value
|
|
697
|
+
),
|
|
698
|
+
tooltipSpan
|
|
560
699
|
);
|
|
561
700
|
}
|
|
562
701
|
function EditableHTML({
|
|
@@ -565,12 +704,19 @@ function EditableHTML({
|
|
|
565
704
|
as = "div",
|
|
566
705
|
className
|
|
567
706
|
}) {
|
|
707
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
568
708
|
const isEditMode = useEditModeMessaging();
|
|
569
709
|
const sendEditRequest = useSendEditRequest();
|
|
570
710
|
const { value, isLoading } = useSiteContentQuery(contentKey, {
|
|
571
711
|
defaultValue
|
|
572
712
|
});
|
|
573
713
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
714
|
+
useEffect7(() => {
|
|
715
|
+
if (isEditMode) {
|
|
716
|
+
registerContentKey(contentKey);
|
|
717
|
+
return () => unregisterContentKey(contentKey);
|
|
718
|
+
}
|
|
719
|
+
}, [isEditMode, contentKey]);
|
|
574
720
|
const handleClick = useCallback3(
|
|
575
721
|
(e) => {
|
|
576
722
|
if (isEditMode) {
|
|
@@ -587,21 +733,39 @@ function EditableHTML({
|
|
|
587
733
|
"aria-busy": true
|
|
588
734
|
});
|
|
589
735
|
}
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
"
|
|
595
|
-
|
|
736
|
+
const wrapperStyle = isEditMode ? {
|
|
737
|
+
position: "relative",
|
|
738
|
+
cursor: "pointer",
|
|
739
|
+
borderRadius: "2px",
|
|
740
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
741
|
+
outlineOffset: "2px",
|
|
742
|
+
backgroundColor: isHovered ? "rgba(59 130 246 / 0.08)" : void 0
|
|
743
|
+
} : {};
|
|
596
744
|
const safeHtml = sanitizeHtml(value);
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
"
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
745
|
+
const hoverHandlers = isEditMode ? { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) } : {};
|
|
746
|
+
return createElement(
|
|
747
|
+
"div",
|
|
748
|
+
{ style: wrapperStyle, ...hoverHandlers },
|
|
749
|
+
createElement(as, {
|
|
750
|
+
className: cn("prose prose-slate dark:prose-invert", className),
|
|
751
|
+
"data-content-key": contentKey,
|
|
752
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
753
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
754
|
+
dangerouslySetInnerHTML: { __html: safeHtml }
|
|
755
|
+
}),
|
|
756
|
+
isEditMode && /* @__PURE__ */ jsx6(
|
|
757
|
+
"span",
|
|
758
|
+
{
|
|
759
|
+
style: {
|
|
760
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
761
|
+
top: "-24px",
|
|
762
|
+
opacity: isHovered ? 1 : 0
|
|
763
|
+
},
|
|
764
|
+
"aria-hidden": true,
|
|
765
|
+
children: "Click to edit"
|
|
766
|
+
}
|
|
767
|
+
)
|
|
768
|
+
);
|
|
605
769
|
}
|
|
606
770
|
function EditableImage({
|
|
607
771
|
contentKey,
|
|
@@ -612,12 +776,19 @@ function EditableImage({
|
|
|
612
776
|
height,
|
|
613
777
|
priority = false
|
|
614
778
|
}) {
|
|
779
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
615
780
|
const isEditMode = useEditModeMessaging();
|
|
616
781
|
const sendEditRequest = useSendEditRequest();
|
|
617
782
|
const { value: src, isLoading } = useSiteContentQuery(contentKey, {
|
|
618
783
|
defaultValue
|
|
619
784
|
});
|
|
620
785
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
786
|
+
useEffect7(() => {
|
|
787
|
+
if (isEditMode) {
|
|
788
|
+
registerContentKey(contentKey);
|
|
789
|
+
return () => unregisterContentKey(contentKey);
|
|
790
|
+
}
|
|
791
|
+
}, [isEditMode, contentKey]);
|
|
621
792
|
const handleClick = useCallback3(
|
|
622
793
|
(e) => {
|
|
623
794
|
if (isEditMode) {
|
|
@@ -638,39 +809,55 @@ function EditableImage({
|
|
|
638
809
|
}
|
|
639
810
|
);
|
|
640
811
|
}
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
812
|
+
const wrapperStyle = isEditMode ? {
|
|
813
|
+
position: "relative",
|
|
814
|
+
display: "inline-block",
|
|
815
|
+
cursor: "pointer",
|
|
816
|
+
borderRadius: "2px",
|
|
817
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
818
|
+
outlineOffset: "2px"
|
|
819
|
+
} : {};
|
|
820
|
+
const hoverHandlers = isEditMode ? { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) } : {};
|
|
821
|
+
return /* @__PURE__ */ jsxs("div", { style: wrapperStyle, ...hoverHandlers, children: [
|
|
648
822
|
/* @__PURE__ */ jsx6(
|
|
649
823
|
"img",
|
|
650
824
|
{
|
|
651
825
|
src,
|
|
652
826
|
alt,
|
|
653
|
-
className
|
|
827
|
+
className,
|
|
828
|
+
style: isEditMode && isHovered ? { opacity: 0.95 } : void 0,
|
|
654
829
|
width,
|
|
655
830
|
height,
|
|
656
831
|
loading: priority ? "eager" : "lazy",
|
|
657
832
|
"data-content-key": contentKey,
|
|
658
833
|
"data-editable": isEditMode ? "true" : void 0,
|
|
659
|
-
onClick: isEditMode ? handleClick : void 0
|
|
660
|
-
title: isEditMode ? "Click to edit image" : void 0
|
|
834
|
+
onClick: isEditMode ? handleClick : void 0
|
|
661
835
|
}
|
|
662
836
|
),
|
|
663
|
-
isEditMode && /* @__PURE__ */ jsx6(
|
|
837
|
+
isEditMode && /* @__PURE__ */ jsx6(
|
|
838
|
+
"span",
|
|
839
|
+
{
|
|
840
|
+
style: {
|
|
841
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
842
|
+
top: "8px",
|
|
843
|
+
left: "8px",
|
|
844
|
+
transform: "none",
|
|
845
|
+
opacity: isHovered ? 1 : 0
|
|
846
|
+
},
|
|
847
|
+
"aria-hidden": true,
|
|
848
|
+
children: "Click to edit image"
|
|
849
|
+
}
|
|
850
|
+
)
|
|
664
851
|
] });
|
|
665
852
|
}
|
|
666
853
|
|
|
667
854
|
// src/hooks/useServices.ts
|
|
668
|
-
import { useState as
|
|
855
|
+
import { useState as useState8, useEffect as useEffect8 } from "react";
|
|
669
856
|
function useServices(options = {}) {
|
|
670
857
|
const { client } = useFoxPixelContext();
|
|
671
|
-
const [services, setServices] =
|
|
672
|
-
const [isLoading, setIsLoading] =
|
|
673
|
-
const [error, setError] =
|
|
858
|
+
const [services, setServices] = useState8(null);
|
|
859
|
+
const [isLoading, setIsLoading] = useState8(true);
|
|
860
|
+
const [error, setError] = useState8(null);
|
|
674
861
|
const fetchServices = async () => {
|
|
675
862
|
try {
|
|
676
863
|
setIsLoading(true);
|
|
@@ -688,7 +875,7 @@ function useServices(options = {}) {
|
|
|
688
875
|
setIsLoading(false);
|
|
689
876
|
}
|
|
690
877
|
};
|
|
691
|
-
|
|
878
|
+
useEffect8(() => {
|
|
692
879
|
fetchServices();
|
|
693
880
|
}, [options.category, options.active]);
|
|
694
881
|
return {
|
|
@@ -700,11 +887,11 @@ function useServices(options = {}) {
|
|
|
700
887
|
}
|
|
701
888
|
|
|
702
889
|
// src/hooks/useLeadCapture.ts
|
|
703
|
-
import { useState as
|
|
890
|
+
import { useState as useState9 } from "react";
|
|
704
891
|
function useLeadCapture() {
|
|
705
892
|
const { client } = useFoxPixelContext();
|
|
706
|
-
const [isLoading, setIsLoading] =
|
|
707
|
-
const [error, setError] =
|
|
893
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
894
|
+
const [error, setError] = useState9(null);
|
|
708
895
|
const captureLead = async (data) => {
|
|
709
896
|
try {
|
|
710
897
|
setIsLoading(true);
|
|
@@ -727,11 +914,11 @@ function useLeadCapture() {
|
|
|
727
914
|
}
|
|
728
915
|
|
|
729
916
|
// src/hooks/useContactCapture.ts
|
|
730
|
-
import { useState as
|
|
917
|
+
import { useState as useState10 } from "react";
|
|
731
918
|
function useContactCapture() {
|
|
732
919
|
const { client } = useFoxPixelContext();
|
|
733
|
-
const [isLoading, setIsLoading] =
|
|
734
|
-
const [error, setError] =
|
|
920
|
+
const [isLoading, setIsLoading] = useState10(false);
|
|
921
|
+
const [error, setError] = useState10(null);
|
|
735
922
|
const captureContact = async (data) => {
|
|
736
923
|
try {
|
|
737
924
|
setIsLoading(true);
|
|
@@ -754,14 +941,14 @@ function useContactCapture() {
|
|
|
754
941
|
}
|
|
755
942
|
|
|
756
943
|
// src/hooks/useSiteContent.ts
|
|
757
|
-
import { useState as
|
|
944
|
+
import { useState as useState11, useEffect as useEffect9, useCallback as useCallback4 } from "react";
|
|
758
945
|
function useSiteContent(contentKey, options = {}) {
|
|
759
946
|
const { defaultValue = "", fetchOnMount = true } = options;
|
|
760
947
|
const { client } = useFoxPixelContext();
|
|
761
948
|
const { user, hasPermission } = useAuth();
|
|
762
|
-
const [data, setData] =
|
|
763
|
-
const [isLoading, setIsLoading] =
|
|
764
|
-
const [error, setError] =
|
|
949
|
+
const [data, setData] = useState11(null);
|
|
950
|
+
const [isLoading, setIsLoading] = useState11(fetchOnMount);
|
|
951
|
+
const [error, setError] = useState11(null);
|
|
765
952
|
const canEdit = user !== null && hasPermission("site:content:update");
|
|
766
953
|
const fetchContent = useCallback4(async () => {
|
|
767
954
|
try {
|
|
@@ -794,7 +981,7 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
794
981
|
throw err;
|
|
795
982
|
}
|
|
796
983
|
}, [client, contentKey]);
|
|
797
|
-
|
|
984
|
+
useEffect9(() => {
|
|
798
985
|
if (fetchOnMount) {
|
|
799
986
|
fetchContent();
|
|
800
987
|
}
|
|
@@ -813,9 +1000,9 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
813
1000
|
function useSiteContents(contentKeys, options = {}) {
|
|
814
1001
|
const { defaults = {} } = options;
|
|
815
1002
|
const { client } = useFoxPixelContext();
|
|
816
|
-
const [data, setData] =
|
|
817
|
-
const [isLoading, setIsLoading] =
|
|
818
|
-
const [error, setError] =
|
|
1003
|
+
const [data, setData] = useState11({});
|
|
1004
|
+
const [isLoading, setIsLoading] = useState11(true);
|
|
1005
|
+
const [error, setError] = useState11(null);
|
|
819
1006
|
const fetchContents = useCallback4(async () => {
|
|
820
1007
|
if (contentKeys.length === 0) {
|
|
821
1008
|
setData({});
|
|
@@ -836,7 +1023,7 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
836
1023
|
setIsLoading(false);
|
|
837
1024
|
}
|
|
838
1025
|
}, [client, contentKeys.join(",")]);
|
|
839
|
-
|
|
1026
|
+
useEffect9(() => {
|
|
840
1027
|
fetchContents();
|
|
841
1028
|
}, [fetchContents]);
|
|
842
1029
|
const getValue = useCallback4((key, defaultValue) => {
|
|
@@ -856,9 +1043,9 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
856
1043
|
}
|
|
857
1044
|
function useSiteContentSection(section) {
|
|
858
1045
|
const { client } = useFoxPixelContext();
|
|
859
|
-
const [contents, setContents] =
|
|
860
|
-
const [isLoading, setIsLoading] =
|
|
861
|
-
const [error, setError] =
|
|
1046
|
+
const [contents, setContents] = useState11([]);
|
|
1047
|
+
const [isLoading, setIsLoading] = useState11(true);
|
|
1048
|
+
const [error, setError] = useState11(null);
|
|
862
1049
|
const fetchContents = useCallback4(async () => {
|
|
863
1050
|
try {
|
|
864
1051
|
setIsLoading(true);
|
|
@@ -873,7 +1060,7 @@ function useSiteContentSection(section) {
|
|
|
873
1060
|
setIsLoading(false);
|
|
874
1061
|
}
|
|
875
1062
|
}, [client, section]);
|
|
876
|
-
|
|
1063
|
+
useEffect9(() => {
|
|
877
1064
|
fetchContents();
|
|
878
1065
|
}, [fetchContents]);
|
|
879
1066
|
return {
|
|
@@ -884,13 +1071,43 @@ function useSiteContentSection(section) {
|
|
|
884
1071
|
};
|
|
885
1072
|
}
|
|
886
1073
|
|
|
1074
|
+
// src/prefetchSiteContent.ts
|
|
1075
|
+
async function prefetchSiteContent(queryClient, options) {
|
|
1076
|
+
const { apiUrl, apiKey, tenantId, contentKeys } = options;
|
|
1077
|
+
const client = new FoxPixelHttpClient({ apiUrl, apiKey, tenantId });
|
|
1078
|
+
await Promise.all(
|
|
1079
|
+
contentKeys.map(async (contentKey) => {
|
|
1080
|
+
try {
|
|
1081
|
+
const content = await client.get(
|
|
1082
|
+
`/api/site/content/${encodeURIComponent(contentKey)}`
|
|
1083
|
+
);
|
|
1084
|
+
queryClient.setQueryData(
|
|
1085
|
+
[SITE_CONTENT_QUERY_KEY, contentKey],
|
|
1086
|
+
{
|
|
1087
|
+
value: content?.value ?? "",
|
|
1088
|
+
contentType: content?.contentType ?? "TEXT"
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
} catch (err) {
|
|
1092
|
+
const status = err?.response?.status;
|
|
1093
|
+
if (status === 404) {
|
|
1094
|
+
queryClient.setQueryData([SITE_CONTENT_QUERY_KEY, contentKey], {
|
|
1095
|
+
value: "",
|
|
1096
|
+
contentType: "TEXT"
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
})
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
887
1104
|
// src/blog/hooks.ts
|
|
888
|
-
import { useState as
|
|
1105
|
+
import { useState as useState12, useEffect as useEffect10 } from "react";
|
|
889
1106
|
function useBlogPosts(options = {}) {
|
|
890
1107
|
const { client } = useFoxPixelContext();
|
|
891
|
-
const [data, setData] =
|
|
892
|
-
const [isLoading, setIsLoading] =
|
|
893
|
-
const [error, setError] =
|
|
1108
|
+
const [data, setData] = useState12(null);
|
|
1109
|
+
const [isLoading, setIsLoading] = useState12(true);
|
|
1110
|
+
const [error, setError] = useState12(null);
|
|
894
1111
|
const page = options.page ?? 0;
|
|
895
1112
|
const limit = options.limit ?? 10;
|
|
896
1113
|
const fetchPosts = async () => {
|
|
@@ -910,7 +1127,7 @@ function useBlogPosts(options = {}) {
|
|
|
910
1127
|
setIsLoading(false);
|
|
911
1128
|
}
|
|
912
1129
|
};
|
|
913
|
-
|
|
1130
|
+
useEffect10(() => {
|
|
914
1131
|
fetchPosts();
|
|
915
1132
|
}, [page, limit]);
|
|
916
1133
|
return {
|
|
@@ -922,9 +1139,9 @@ function useBlogPosts(options = {}) {
|
|
|
922
1139
|
}
|
|
923
1140
|
function useBlogPost(slug) {
|
|
924
1141
|
const { client } = useFoxPixelContext();
|
|
925
|
-
const [data, setData] =
|
|
926
|
-
const [isLoading, setIsLoading] =
|
|
927
|
-
const [error, setError] =
|
|
1142
|
+
const [data, setData] = useState12(null);
|
|
1143
|
+
const [isLoading, setIsLoading] = useState12(!!slug);
|
|
1144
|
+
const [error, setError] = useState12(null);
|
|
928
1145
|
const fetchPost = async () => {
|
|
929
1146
|
if (!slug) {
|
|
930
1147
|
setData(null);
|
|
@@ -943,7 +1160,7 @@ function useBlogPost(slug) {
|
|
|
943
1160
|
setIsLoading(false);
|
|
944
1161
|
}
|
|
945
1162
|
};
|
|
946
|
-
|
|
1163
|
+
useEffect10(() => {
|
|
947
1164
|
fetchPost();
|
|
948
1165
|
}, [slug]);
|
|
949
1166
|
return {
|
|
@@ -955,9 +1172,9 @@ function useBlogPost(slug) {
|
|
|
955
1172
|
}
|
|
956
1173
|
function useBlogCategories() {
|
|
957
1174
|
const { client } = useFoxPixelContext();
|
|
958
|
-
const [data, setData] =
|
|
959
|
-
const [isLoading, setIsLoading] =
|
|
960
|
-
const [error, setError] =
|
|
1175
|
+
const [data, setData] = useState12(null);
|
|
1176
|
+
const [isLoading, setIsLoading] = useState12(true);
|
|
1177
|
+
const [error, setError] = useState12(null);
|
|
961
1178
|
const fetchCategories = async () => {
|
|
962
1179
|
try {
|
|
963
1180
|
setIsLoading(true);
|
|
@@ -971,7 +1188,7 @@ function useBlogCategories() {
|
|
|
971
1188
|
setIsLoading(false);
|
|
972
1189
|
}
|
|
973
1190
|
};
|
|
974
|
-
|
|
1191
|
+
useEffect10(() => {
|
|
975
1192
|
fetchCategories();
|
|
976
1193
|
}, []);
|
|
977
1194
|
return {
|
|
@@ -983,9 +1200,9 @@ function useBlogCategories() {
|
|
|
983
1200
|
}
|
|
984
1201
|
function useBlogTags() {
|
|
985
1202
|
const { client } = useFoxPixelContext();
|
|
986
|
-
const [data, setData] =
|
|
987
|
-
const [isLoading, setIsLoading] =
|
|
988
|
-
const [error, setError] =
|
|
1203
|
+
const [data, setData] = useState12(null);
|
|
1204
|
+
const [isLoading, setIsLoading] = useState12(true);
|
|
1205
|
+
const [error, setError] = useState12(null);
|
|
989
1206
|
const fetchTags = async () => {
|
|
990
1207
|
try {
|
|
991
1208
|
setIsLoading(true);
|
|
@@ -999,7 +1216,7 @@ function useBlogTags() {
|
|
|
999
1216
|
setIsLoading(false);
|
|
1000
1217
|
}
|
|
1001
1218
|
};
|
|
1002
|
-
|
|
1219
|
+
useEffect10(() => {
|
|
1003
1220
|
fetchTags();
|
|
1004
1221
|
}, []);
|
|
1005
1222
|
return {
|
|
@@ -1011,9 +1228,9 @@ function useBlogTags() {
|
|
|
1011
1228
|
}
|
|
1012
1229
|
function useBlogComments(slug) {
|
|
1013
1230
|
const { client } = useFoxPixelContext();
|
|
1014
|
-
const [data, setData] =
|
|
1015
|
-
const [isLoading, setIsLoading] =
|
|
1016
|
-
const [error, setError] =
|
|
1231
|
+
const [data, setData] = useState12(null);
|
|
1232
|
+
const [isLoading, setIsLoading] = useState12(!!slug);
|
|
1233
|
+
const [error, setError] = useState12(null);
|
|
1017
1234
|
const fetchComments = async () => {
|
|
1018
1235
|
if (!slug) {
|
|
1019
1236
|
setData(null);
|
|
@@ -1034,7 +1251,7 @@ function useBlogComments(slug) {
|
|
|
1034
1251
|
setIsLoading(false);
|
|
1035
1252
|
}
|
|
1036
1253
|
};
|
|
1037
|
-
|
|
1254
|
+
useEffect10(() => {
|
|
1038
1255
|
fetchComments();
|
|
1039
1256
|
}, [slug]);
|
|
1040
1257
|
return {
|
|
@@ -1046,8 +1263,8 @@ function useBlogComments(slug) {
|
|
|
1046
1263
|
}
|
|
1047
1264
|
function useBlogCommentSubmit(slug) {
|
|
1048
1265
|
const { client } = useFoxPixelContext();
|
|
1049
|
-
const [isSubmitting, setIsSubmitting] =
|
|
1050
|
-
const [error, setError] =
|
|
1266
|
+
const [isSubmitting, setIsSubmitting] = useState12(false);
|
|
1267
|
+
const [error, setError] = useState12(null);
|
|
1051
1268
|
const submit = async (payload) => {
|
|
1052
1269
|
if (!slug) return null;
|
|
1053
1270
|
try {
|
|
@@ -1075,9 +1292,9 @@ function useBlogCommentSubmit(slug) {
|
|
|
1075
1292
|
}
|
|
1076
1293
|
function useBlogFeaturedPosts(limit = 6) {
|
|
1077
1294
|
const { client } = useFoxPixelContext();
|
|
1078
|
-
const [data, setData] =
|
|
1079
|
-
const [isLoading, setIsLoading] =
|
|
1080
|
-
const [error, setError] =
|
|
1295
|
+
const [data, setData] = useState12(null);
|
|
1296
|
+
const [isLoading, setIsLoading] = useState12(true);
|
|
1297
|
+
const [error, setError] = useState12(null);
|
|
1081
1298
|
const fetchFeatured = async () => {
|
|
1082
1299
|
try {
|
|
1083
1300
|
setIsLoading(true);
|
|
@@ -1095,7 +1312,7 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
1095
1312
|
setIsLoading(false);
|
|
1096
1313
|
}
|
|
1097
1314
|
};
|
|
1098
|
-
|
|
1315
|
+
useEffect10(() => {
|
|
1099
1316
|
fetchFeatured();
|
|
1100
1317
|
}, [limit]);
|
|
1101
1318
|
return {
|
|
@@ -1107,9 +1324,9 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
1107
1324
|
}
|
|
1108
1325
|
function useNewsletterSubscribe() {
|
|
1109
1326
|
const { client } = useFoxPixelContext();
|
|
1110
|
-
const [isSubmitting, setIsSubmitting] =
|
|
1111
|
-
const [error, setError] =
|
|
1112
|
-
const [success, setSuccess] =
|
|
1327
|
+
const [isSubmitting, setIsSubmitting] = useState12(false);
|
|
1328
|
+
const [error, setError] = useState12(null);
|
|
1329
|
+
const [success, setSuccess] = useState12(false);
|
|
1113
1330
|
const subscribe = async (payload) => {
|
|
1114
1331
|
try {
|
|
1115
1332
|
setIsSubmitting(true);
|
|
@@ -1142,9 +1359,9 @@ function useNewsletterSubscribe() {
|
|
|
1142
1359
|
}
|
|
1143
1360
|
function useNewsletterUnsubscribe() {
|
|
1144
1361
|
const { client } = useFoxPixelContext();
|
|
1145
|
-
const [isSubmitting, setIsSubmitting] =
|
|
1146
|
-
const [error, setError] =
|
|
1147
|
-
const [success, setSuccess] =
|
|
1362
|
+
const [isSubmitting, setIsSubmitting] = useState12(false);
|
|
1363
|
+
const [error, setError] = useState12(null);
|
|
1364
|
+
const [success, setSuccess] = useState12(false);
|
|
1148
1365
|
const unsubscribe = async (email) => {
|
|
1149
1366
|
try {
|
|
1150
1367
|
setIsSubmitting(true);
|
|
@@ -1189,12 +1406,12 @@ function useNewsletterUnsubscribe() {
|
|
|
1189
1406
|
}
|
|
1190
1407
|
|
|
1191
1408
|
// src/blog/admin-hooks.ts
|
|
1192
|
-
import { useState as
|
|
1409
|
+
import { useState as useState13, useEffect as useEffect11, useCallback as useCallback5 } from "react";
|
|
1193
1410
|
function useAdminBlogPosts(options = {}) {
|
|
1194
1411
|
const { client } = useFoxPixelContext();
|
|
1195
|
-
const [data, setData] =
|
|
1196
|
-
const [isLoading, setIsLoading] =
|
|
1197
|
-
const [error, setError] =
|
|
1412
|
+
const [data, setData] = useState13(null);
|
|
1413
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1414
|
+
const [error, setError] = useState13(null);
|
|
1198
1415
|
const page = options.page ?? 0;
|
|
1199
1416
|
const size = options.size ?? 20;
|
|
1200
1417
|
const fetchPosts = useCallback5(async () => {
|
|
@@ -1212,16 +1429,16 @@ function useAdminBlogPosts(options = {}) {
|
|
|
1212
1429
|
setIsLoading(false);
|
|
1213
1430
|
}
|
|
1214
1431
|
}, [client, page, size]);
|
|
1215
|
-
|
|
1432
|
+
useEffect11(() => {
|
|
1216
1433
|
fetchPosts();
|
|
1217
1434
|
}, [fetchPosts]);
|
|
1218
1435
|
return { data, isLoading, error, refetch: fetchPosts };
|
|
1219
1436
|
}
|
|
1220
1437
|
function useAdminBlogPost(id) {
|
|
1221
1438
|
const { client } = useFoxPixelContext();
|
|
1222
|
-
const [data, setData] =
|
|
1223
|
-
const [isLoading, setIsLoading] =
|
|
1224
|
-
const [error, setError] =
|
|
1439
|
+
const [data, setData] = useState13(null);
|
|
1440
|
+
const [isLoading, setIsLoading] = useState13(!!id);
|
|
1441
|
+
const [error, setError] = useState13(null);
|
|
1225
1442
|
const fetchPost = useCallback5(async () => {
|
|
1226
1443
|
if (!id) {
|
|
1227
1444
|
setData(null);
|
|
@@ -1239,15 +1456,15 @@ function useAdminBlogPost(id) {
|
|
|
1239
1456
|
setIsLoading(false);
|
|
1240
1457
|
}
|
|
1241
1458
|
}, [client, id]);
|
|
1242
|
-
|
|
1459
|
+
useEffect11(() => {
|
|
1243
1460
|
fetchPost();
|
|
1244
1461
|
}, [fetchPost]);
|
|
1245
1462
|
return { data, isLoading, error, refetch: fetchPost };
|
|
1246
1463
|
}
|
|
1247
1464
|
function useAdminBlogPostMutations() {
|
|
1248
1465
|
const { client } = useFoxPixelContext();
|
|
1249
|
-
const [isLoading, setIsLoading] =
|
|
1250
|
-
const [error, setError] =
|
|
1466
|
+
const [isLoading, setIsLoading] = useState13(false);
|
|
1467
|
+
const [error, setError] = useState13(null);
|
|
1251
1468
|
const create = async (payload) => {
|
|
1252
1469
|
try {
|
|
1253
1470
|
setIsLoading(true);
|
|
@@ -1291,9 +1508,9 @@ function useAdminBlogPostMutations() {
|
|
|
1291
1508
|
}
|
|
1292
1509
|
function useAdminBlogCategories() {
|
|
1293
1510
|
const { client } = useFoxPixelContext();
|
|
1294
|
-
const [data, setData] =
|
|
1295
|
-
const [isLoading, setIsLoading] =
|
|
1296
|
-
const [error, setError] =
|
|
1511
|
+
const [data, setData] = useState13(null);
|
|
1512
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1513
|
+
const [error, setError] = useState13(null);
|
|
1297
1514
|
const fetchCategories = useCallback5(async () => {
|
|
1298
1515
|
try {
|
|
1299
1516
|
setIsLoading(true);
|
|
@@ -1306,7 +1523,7 @@ function useAdminBlogCategories() {
|
|
|
1306
1523
|
setIsLoading(false);
|
|
1307
1524
|
}
|
|
1308
1525
|
}, [client]);
|
|
1309
|
-
|
|
1526
|
+
useEffect11(() => {
|
|
1310
1527
|
fetchCategories();
|
|
1311
1528
|
}, [fetchCategories]);
|
|
1312
1529
|
const create = async (payload) => {
|
|
@@ -1343,9 +1560,9 @@ function useAdminBlogCategories() {
|
|
|
1343
1560
|
}
|
|
1344
1561
|
function useAdminBlogTags() {
|
|
1345
1562
|
const { client } = useFoxPixelContext();
|
|
1346
|
-
const [data, setData] =
|
|
1347
|
-
const [isLoading, setIsLoading] =
|
|
1348
|
-
const [error, setError] =
|
|
1563
|
+
const [data, setData] = useState13(null);
|
|
1564
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1565
|
+
const [error, setError] = useState13(null);
|
|
1349
1566
|
const fetchTags = useCallback5(async () => {
|
|
1350
1567
|
try {
|
|
1351
1568
|
setIsLoading(true);
|
|
@@ -1358,7 +1575,7 @@ function useAdminBlogTags() {
|
|
|
1358
1575
|
setIsLoading(false);
|
|
1359
1576
|
}
|
|
1360
1577
|
}, [client]);
|
|
1361
|
-
|
|
1578
|
+
useEffect11(() => {
|
|
1362
1579
|
fetchTags();
|
|
1363
1580
|
}, [fetchTags]);
|
|
1364
1581
|
const create = async (payload) => {
|
|
@@ -1395,9 +1612,9 @@ function useAdminBlogTags() {
|
|
|
1395
1612
|
}
|
|
1396
1613
|
function useAdminBlogComments(options = {}) {
|
|
1397
1614
|
const { client } = useFoxPixelContext();
|
|
1398
|
-
const [data, setData] =
|
|
1399
|
-
const [isLoading, setIsLoading] =
|
|
1400
|
-
const [error, setError] =
|
|
1615
|
+
const [data, setData] = useState13(null);
|
|
1616
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1617
|
+
const [error, setError] = useState13(null);
|
|
1401
1618
|
const { status, postId, page = 0, size = 20 } = options;
|
|
1402
1619
|
const fetchComments = useCallback5(async () => {
|
|
1403
1620
|
try {
|
|
@@ -1416,7 +1633,7 @@ function useAdminBlogComments(options = {}) {
|
|
|
1416
1633
|
setIsLoading(false);
|
|
1417
1634
|
}
|
|
1418
1635
|
}, [client, status, postId, page, size]);
|
|
1419
|
-
|
|
1636
|
+
useEffect11(() => {
|
|
1420
1637
|
fetchComments();
|
|
1421
1638
|
}, [fetchComments]);
|
|
1422
1639
|
const updateStatus = async (id, newStatus) => {
|
|
@@ -1443,9 +1660,9 @@ function useAdminBlogComments(options = {}) {
|
|
|
1443
1660
|
}
|
|
1444
1661
|
function useAdminNewsletterSubscribers(options = {}) {
|
|
1445
1662
|
const { client } = useFoxPixelContext();
|
|
1446
|
-
const [data, setData] =
|
|
1447
|
-
const [isLoading, setIsLoading] =
|
|
1448
|
-
const [error, setError] =
|
|
1663
|
+
const [data, setData] = useState13(null);
|
|
1664
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1665
|
+
const [error, setError] = useState13(null);
|
|
1449
1666
|
const { status, page = 0, size = 20 } = options;
|
|
1450
1667
|
const fetchSubscribers = useCallback5(async () => {
|
|
1451
1668
|
try {
|
|
@@ -1463,7 +1680,7 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1463
1680
|
setIsLoading(false);
|
|
1464
1681
|
}
|
|
1465
1682
|
}, [client, status, page, size]);
|
|
1466
|
-
|
|
1683
|
+
useEffect11(() => {
|
|
1467
1684
|
fetchSubscribers();
|
|
1468
1685
|
}, [fetchSubscribers]);
|
|
1469
1686
|
const remove = async (id) => {
|
|
@@ -1480,9 +1697,9 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1480
1697
|
}
|
|
1481
1698
|
function useAdminNewsletterStats() {
|
|
1482
1699
|
const { client } = useFoxPixelContext();
|
|
1483
|
-
const [data, setData] =
|
|
1484
|
-
const [isLoading, setIsLoading] =
|
|
1485
|
-
const [error, setError] =
|
|
1700
|
+
const [data, setData] = useState13(null);
|
|
1701
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1702
|
+
const [error, setError] = useState13(null);
|
|
1486
1703
|
const fetchStats = useCallback5(async () => {
|
|
1487
1704
|
try {
|
|
1488
1705
|
setIsLoading(true);
|
|
@@ -1495,16 +1712,16 @@ function useAdminNewsletterStats() {
|
|
|
1495
1712
|
setIsLoading(false);
|
|
1496
1713
|
}
|
|
1497
1714
|
}, [client]);
|
|
1498
|
-
|
|
1715
|
+
useEffect11(() => {
|
|
1499
1716
|
fetchStats();
|
|
1500
1717
|
}, [fetchStats]);
|
|
1501
1718
|
return { data, isLoading, error, refetch: fetchStats };
|
|
1502
1719
|
}
|
|
1503
1720
|
function useAdminBlogSettings() {
|
|
1504
1721
|
const { client } = useFoxPixelContext();
|
|
1505
|
-
const [data, setData] =
|
|
1506
|
-
const [isLoading, setIsLoading] =
|
|
1507
|
-
const [error, setError] =
|
|
1722
|
+
const [data, setData] = useState13(null);
|
|
1723
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1724
|
+
const [error, setError] = useState13(null);
|
|
1508
1725
|
const fetchSettings = useCallback5(async () => {
|
|
1509
1726
|
try {
|
|
1510
1727
|
setIsLoading(true);
|
|
@@ -1517,7 +1734,7 @@ function useAdminBlogSettings() {
|
|
|
1517
1734
|
setIsLoading(false);
|
|
1518
1735
|
}
|
|
1519
1736
|
}, [client]);
|
|
1520
|
-
|
|
1737
|
+
useEffect11(() => {
|
|
1521
1738
|
fetchSettings();
|
|
1522
1739
|
}, [fetchSettings]);
|
|
1523
1740
|
const update = async (settings) => {
|
|
@@ -1534,9 +1751,9 @@ function useAdminBlogSettings() {
|
|
|
1534
1751
|
}
|
|
1535
1752
|
function useAdminBlogAnalytics() {
|
|
1536
1753
|
const { client } = useFoxPixelContext();
|
|
1537
|
-
const [data, setData] =
|
|
1538
|
-
const [isLoading, setIsLoading] =
|
|
1539
|
-
const [error, setError] =
|
|
1754
|
+
const [data, setData] = useState13(null);
|
|
1755
|
+
const [isLoading, setIsLoading] = useState13(true);
|
|
1756
|
+
const [error, setError] = useState13(null);
|
|
1540
1757
|
const fetchAnalytics = useCallback5(async () => {
|
|
1541
1758
|
try {
|
|
1542
1759
|
setIsLoading(true);
|
|
@@ -1549,7 +1766,7 @@ function useAdminBlogAnalytics() {
|
|
|
1549
1766
|
setIsLoading(false);
|
|
1550
1767
|
}
|
|
1551
1768
|
}, [client]);
|
|
1552
|
-
|
|
1769
|
+
useEffect11(() => {
|
|
1553
1770
|
fetchAnalytics();
|
|
1554
1771
|
}, [fetchAnalytics]);
|
|
1555
1772
|
return { data, isLoading, error, refetch: fetchAnalytics };
|
|
@@ -1597,6 +1814,7 @@ export {
|
|
|
1597
1814
|
ProtectedRoute,
|
|
1598
1815
|
SITE_CONTENT_QUERY_KEY,
|
|
1599
1816
|
getBlogPostSchemaLd,
|
|
1817
|
+
prefetchSiteContent,
|
|
1600
1818
|
useAdminBlogAnalytics,
|
|
1601
1819
|
useAdminBlogCategories,
|
|
1602
1820
|
useAdminBlogComments,
|