@foxpixel/react 0.2.0 → 0.2.1
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 +379 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +359 -181
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
ProtectedRoute: () => ProtectedRoute,
|
|
41
41
|
SITE_CONTENT_QUERY_KEY: () => SITE_CONTENT_QUERY_KEY,
|
|
42
42
|
getBlogPostSchemaLd: () => getBlogPostSchemaLd,
|
|
43
|
+
prefetchSiteContent: () => prefetchSiteContent,
|
|
43
44
|
useAdminBlogAnalytics: () => useAdminBlogAnalytics,
|
|
44
45
|
useAdminBlogCategories: () => useAdminBlogCategories,
|
|
45
46
|
useAdminBlogComments: () => useAdminBlogComments,
|
|
@@ -76,7 +77,7 @@ __export(index_exports, {
|
|
|
76
77
|
module.exports = __toCommonJS(index_exports);
|
|
77
78
|
|
|
78
79
|
// src/context/FoxPixelContext.tsx
|
|
79
|
-
var import_react = require("react");
|
|
80
|
+
var import_react = __toESM(require("react"));
|
|
80
81
|
|
|
81
82
|
// src/client/http.ts
|
|
82
83
|
var import_axios = __toESM(require("axios"));
|
|
@@ -188,15 +189,21 @@ var FoxPixelHttpClient = class {
|
|
|
188
189
|
|
|
189
190
|
// src/context/FoxPixelContext.tsx
|
|
190
191
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
192
|
+
if (!import_react.default || typeof import_react.default.useMemo !== "function") {
|
|
193
|
+
throw new Error(
|
|
194
|
+
'@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).'
|
|
195
|
+
);
|
|
196
|
+
}
|
|
191
197
|
var FoxPixelContext = (0, import_react.createContext)(null);
|
|
192
|
-
function FoxPixelProvider({ children, config = {} }) {
|
|
198
|
+
function FoxPixelProvider({ children, config = {}, queryClient }) {
|
|
193
199
|
const client = (0, import_react.useMemo)(() => {
|
|
194
200
|
return new FoxPixelHttpClient(config);
|
|
195
201
|
}, [config.apiUrl, config.apiKey, config.tenantId]);
|
|
196
202
|
const value = (0, import_react.useMemo)(() => ({
|
|
197
203
|
client,
|
|
198
|
-
config
|
|
199
|
-
|
|
204
|
+
config,
|
|
205
|
+
queryClient: queryClient ?? null
|
|
206
|
+
}), [client, config, queryClient]);
|
|
200
207
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FoxPixelContext.Provider, { value, children });
|
|
201
208
|
}
|
|
202
209
|
function useFoxPixelContext() {
|
|
@@ -423,11 +430,10 @@ function withAuth(Component, options = {}) {
|
|
|
423
430
|
}
|
|
424
431
|
|
|
425
432
|
// src/components/Editable.tsx
|
|
426
|
-
var
|
|
433
|
+
var import_react8 = require("react");
|
|
427
434
|
|
|
428
435
|
// src/hooks/useEditMode.ts
|
|
429
436
|
var import_react6 = require("react");
|
|
430
|
-
var import_react_query = require("@tanstack/react-query");
|
|
431
437
|
var SITE_CONTENT_QUERY_KEY = "siteContent";
|
|
432
438
|
function useEditMode() {
|
|
433
439
|
const [isEditMode, setIsEditMode] = (0, import_react6.useState)(false);
|
|
@@ -439,18 +445,29 @@ function useEditMode() {
|
|
|
439
445
|
return isEditMode;
|
|
440
446
|
}
|
|
441
447
|
function useEditModeMessaging() {
|
|
442
|
-
const
|
|
448
|
+
const ctx = useFoxPixelContext();
|
|
449
|
+
const queryClient = ctx?.queryClient ?? null;
|
|
443
450
|
const isEditMode = useEditMode();
|
|
444
451
|
(0, import_react6.useEffect)(() => {
|
|
445
452
|
if (!isEditMode || typeof window === "undefined") return;
|
|
446
453
|
window.parent.postMessage({ type: "FOXPIXEL_READY" }, "*");
|
|
447
454
|
const handleMessage = (event) => {
|
|
455
|
+
if (!queryClient) return;
|
|
448
456
|
const { type, payload } = event.data || {};
|
|
449
|
-
if (type
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
457
|
+
if (type !== "FOXPIXEL_CONTENT_UPDATED" || !payload?.contentKey) return;
|
|
458
|
+
const { contentKey, newValue } = payload;
|
|
459
|
+
if (typeof newValue === "string") {
|
|
460
|
+
queryClient.setQueryData(
|
|
461
|
+
[SITE_CONTENT_QUERY_KEY, contentKey],
|
|
462
|
+
(prev) => ({
|
|
463
|
+
value: newValue,
|
|
464
|
+
contentType: prev?.contentType ?? "TEXT"
|
|
465
|
+
})
|
|
466
|
+
);
|
|
453
467
|
}
|
|
468
|
+
queryClient.invalidateQueries({
|
|
469
|
+
queryKey: [SITE_CONTENT_QUERY_KEY, contentKey]
|
|
470
|
+
});
|
|
454
471
|
};
|
|
455
472
|
window.addEventListener("message", handleMessage);
|
|
456
473
|
return () => window.removeEventListener("message", handleMessage);
|
|
@@ -483,16 +500,40 @@ function useSendEditRequest() {
|
|
|
483
500
|
}
|
|
484
501
|
|
|
485
502
|
// src/hooks/useSiteContentQuery.ts
|
|
486
|
-
var
|
|
503
|
+
var import_react7 = require("react");
|
|
504
|
+
function getCached(queryClient, contentKey) {
|
|
505
|
+
const data = queryClient.getQueryData([
|
|
506
|
+
SITE_CONTENT_QUERY_KEY,
|
|
507
|
+
contentKey
|
|
508
|
+
]);
|
|
509
|
+
if (data == null) return void 0;
|
|
510
|
+
return { value: data.value ?? "", contentType: data.contentType ?? "TEXT" };
|
|
511
|
+
}
|
|
487
512
|
function useSiteContentQuery(contentKey, options) {
|
|
488
513
|
const { defaultValue } = options;
|
|
489
|
-
const { client } = useFoxPixelContext();
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
514
|
+
const { client, queryClient } = useFoxPixelContext();
|
|
515
|
+
const [state, setState] = (0, import_react7.useState)(() => {
|
|
516
|
+
if (queryClient) {
|
|
517
|
+
const cached = getCached(queryClient, contentKey);
|
|
518
|
+
if (cached) {
|
|
519
|
+
return { value: cached.value, isLoading: false, contentType: cached.contentType };
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return { value: defaultValue, isLoading: true, contentType: "TEXT" };
|
|
523
|
+
});
|
|
524
|
+
const contentKeyRef = (0, import_react7.useRef)(contentKey);
|
|
525
|
+
contentKeyRef.current = contentKey;
|
|
526
|
+
(0, import_react7.useEffect)(() => {
|
|
527
|
+
if (!queryClient) {
|
|
528
|
+
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const key = contentKeyRef.current;
|
|
532
|
+
const queryKey = [SITE_CONTENT_QUERY_KEY, key];
|
|
533
|
+
const queryFn = async () => {
|
|
493
534
|
try {
|
|
494
535
|
const content = await client.get(
|
|
495
|
-
`/api/site/content/${encodeURIComponent(
|
|
536
|
+
`/api/site/content/${encodeURIComponent(key)}`
|
|
496
537
|
);
|
|
497
538
|
if (!content) return null;
|
|
498
539
|
return {
|
|
@@ -500,23 +541,50 @@ function useSiteContentQuery(contentKey, options) {
|
|
|
500
541
|
contentType: content.contentType ?? "TEXT"
|
|
501
542
|
};
|
|
502
543
|
} catch (err) {
|
|
503
|
-
const status = err?.status;
|
|
544
|
+
const status = err?.response?.status;
|
|
504
545
|
if (status === 404) return null;
|
|
505
546
|
throw err;
|
|
506
547
|
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
548
|
+
};
|
|
549
|
+
let cancelled = false;
|
|
550
|
+
queryClient.fetchQuery({
|
|
551
|
+
queryKey,
|
|
552
|
+
queryFn,
|
|
553
|
+
staleTime: 1e3 * 60 * 5,
|
|
554
|
+
retry: 1
|
|
555
|
+
}).then((data) => {
|
|
556
|
+
if (cancelled) return;
|
|
557
|
+
setState({
|
|
558
|
+
value: data?.value ?? defaultValue,
|
|
559
|
+
isLoading: false,
|
|
560
|
+
contentType: data?.contentType ?? "TEXT"
|
|
561
|
+
});
|
|
562
|
+
}).catch(() => {
|
|
563
|
+
if (cancelled) return;
|
|
564
|
+
setState((s) => ({ ...s, value: defaultValue, isLoading: false }));
|
|
565
|
+
});
|
|
566
|
+
const unsub = queryClient.getQueryCache().subscribe((event) => {
|
|
567
|
+
if (event?.type === "updated" && event?.query?.queryKey[1] === key) {
|
|
568
|
+
const cached = getCached(queryClient, key);
|
|
569
|
+
if (cached && !cancelled) {
|
|
570
|
+
setState({
|
|
571
|
+
value: cached.value,
|
|
572
|
+
isLoading: false,
|
|
573
|
+
contentType: cached.contentType
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
return () => {
|
|
579
|
+
cancelled = true;
|
|
580
|
+
unsub();
|
|
581
|
+
};
|
|
582
|
+
}, [queryClient, contentKey, defaultValue, client]);
|
|
583
|
+
return state;
|
|
516
584
|
}
|
|
517
585
|
|
|
518
586
|
// src/utils/sanitize.ts
|
|
519
|
-
var
|
|
587
|
+
var import_sanitize_html = __toESM(require("sanitize-html"));
|
|
520
588
|
var DEFAULT_ALLOWED_TAGS = [
|
|
521
589
|
"p",
|
|
522
590
|
"br",
|
|
@@ -547,13 +615,16 @@ var DEFAULT_ALLOWED_TAGS = [
|
|
|
547
615
|
"th",
|
|
548
616
|
"td"
|
|
549
617
|
];
|
|
550
|
-
var DEFAULT_ALLOWED_ATTR =
|
|
618
|
+
var DEFAULT_ALLOWED_ATTR = {
|
|
619
|
+
a: ["href", "target", "rel", "title"],
|
|
620
|
+
img: ["src", "alt", "title", "width", "height"],
|
|
621
|
+
"*": ["class"]
|
|
622
|
+
};
|
|
551
623
|
function sanitizeHtml(html) {
|
|
552
624
|
if (typeof html !== "string") return "";
|
|
553
|
-
return
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
ADD_ATTR: ["target"]
|
|
625
|
+
return (0, import_sanitize_html.default)(html, {
|
|
626
|
+
allowedTags: DEFAULT_ALLOWED_TAGS,
|
|
627
|
+
allowedAttributes: DEFAULT_ALLOWED_ATTR
|
|
557
628
|
});
|
|
558
629
|
}
|
|
559
630
|
|
|
@@ -564,6 +635,23 @@ function cn(...args) {
|
|
|
564
635
|
|
|
565
636
|
// src/components/Editable.tsx
|
|
566
637
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
638
|
+
var EDIT_MODE_TOOLTIP_STYLE = {
|
|
639
|
+
position: "absolute",
|
|
640
|
+
top: "-28px",
|
|
641
|
+
left: "50%",
|
|
642
|
+
transform: "translateX(-50%)",
|
|
643
|
+
fontSize: "10px",
|
|
644
|
+
fontFamily: "system-ui, sans-serif",
|
|
645
|
+
padding: "4px 8px",
|
|
646
|
+
backgroundColor: "rgb(37 99 235)",
|
|
647
|
+
color: "white",
|
|
648
|
+
borderRadius: "4px",
|
|
649
|
+
whiteSpace: "nowrap",
|
|
650
|
+
pointerEvents: "none",
|
|
651
|
+
zIndex: 100,
|
|
652
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.2)",
|
|
653
|
+
transition: "opacity 0.15s ease"
|
|
654
|
+
};
|
|
567
655
|
function Editable({
|
|
568
656
|
contentKey,
|
|
569
657
|
defaultValue,
|
|
@@ -571,13 +659,14 @@ function Editable({
|
|
|
571
659
|
multiline = false,
|
|
572
660
|
className
|
|
573
661
|
}) {
|
|
662
|
+
const [isHovered, setIsHovered] = (0, import_react8.useState)(false);
|
|
574
663
|
const isEditMode = useEditModeMessaging();
|
|
575
664
|
const sendEditRequest = useSendEditRequest();
|
|
576
665
|
const { value, isLoading, contentType } = useSiteContentQuery(contentKey, {
|
|
577
666
|
defaultValue
|
|
578
667
|
});
|
|
579
668
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
580
|
-
const handleClick = (0,
|
|
669
|
+
const handleClick = (0, import_react8.useCallback)(
|
|
581
670
|
(e) => {
|
|
582
671
|
if (isEditMode) {
|
|
583
672
|
e.preventDefault();
|
|
@@ -593,7 +682,7 @@ function Editable({
|
|
|
593
682
|
[isEditMode, contentKey, value, contentType, section, sendEditRequest]
|
|
594
683
|
);
|
|
595
684
|
if (isLoading) {
|
|
596
|
-
return (0,
|
|
685
|
+
return (0, import_react8.createElement)(as, {
|
|
597
686
|
className: cn(
|
|
598
687
|
"animate-pulse bg-muted rounded",
|
|
599
688
|
multiline ? "h-20" : "h-6",
|
|
@@ -604,36 +693,59 @@ function Editable({
|
|
|
604
693
|
"aria-label": "Loading content..."
|
|
605
694
|
});
|
|
606
695
|
}
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
696
|
+
const editModeWrapperStyle = isEditMode ? {
|
|
697
|
+
position: "relative",
|
|
698
|
+
display: "inline",
|
|
699
|
+
cursor: "pointer",
|
|
700
|
+
borderRadius: "2px",
|
|
701
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
702
|
+
outlineOffset: "2px",
|
|
703
|
+
backgroundColor: isHovered ? "rgba(59 130 246 / 0.08)" : void 0
|
|
704
|
+
} : {};
|
|
705
|
+
const tooltipSpan = isEditMode ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
706
|
+
"span",
|
|
707
|
+
{
|
|
708
|
+
style: {
|
|
709
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
710
|
+
opacity: isHovered ? 1 : 0
|
|
711
|
+
},
|
|
712
|
+
"aria-hidden": true,
|
|
713
|
+
children: "Click to edit"
|
|
714
|
+
}
|
|
715
|
+
) : null;
|
|
716
|
+
const hoverHandlers = isEditMode ? {
|
|
717
|
+
onMouseEnter: () => setIsHovered(true),
|
|
718
|
+
onMouseLeave: () => setIsHovered(false)
|
|
719
|
+
} : {};
|
|
613
720
|
if (multiline && value.includes("\n")) {
|
|
614
721
|
const safeBr = sanitizeHtml(value.replace(/\n/g, "<br />"));
|
|
615
|
-
return (0,
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
722
|
+
return (0, import_react8.createElement)(
|
|
723
|
+
"span",
|
|
724
|
+
{ style: editModeWrapperStyle, ...hoverHandlers },
|
|
725
|
+
(0, import_react8.createElement)(as, {
|
|
726
|
+
className,
|
|
727
|
+
"data-content-key": contentKey,
|
|
728
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
729
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
730
|
+
dangerouslySetInnerHTML: { __html: safeBr }
|
|
731
|
+
}),
|
|
732
|
+
tooltipSpan
|
|
733
|
+
);
|
|
623
734
|
}
|
|
624
|
-
return (0,
|
|
625
|
-
|
|
626
|
-
{
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
735
|
+
return (0, import_react8.createElement)(
|
|
736
|
+
"span",
|
|
737
|
+
{ style: editModeWrapperStyle, ...hoverHandlers },
|
|
738
|
+
(0, import_react8.createElement)(
|
|
739
|
+
as,
|
|
740
|
+
{
|
|
741
|
+
className,
|
|
742
|
+
"data-content-key": contentKey,
|
|
743
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
744
|
+
onClick: isEditMode ? handleClick : void 0
|
|
745
|
+
},
|
|
746
|
+
value
|
|
747
|
+
),
|
|
748
|
+
tooltipSpan
|
|
637
749
|
);
|
|
638
750
|
}
|
|
639
751
|
function EditableHTML({
|
|
@@ -642,13 +754,14 @@ function EditableHTML({
|
|
|
642
754
|
as = "div",
|
|
643
755
|
className
|
|
644
756
|
}) {
|
|
757
|
+
const [isHovered, setIsHovered] = (0, import_react8.useState)(false);
|
|
645
758
|
const isEditMode = useEditModeMessaging();
|
|
646
759
|
const sendEditRequest = useSendEditRequest();
|
|
647
760
|
const { value, isLoading } = useSiteContentQuery(contentKey, {
|
|
648
761
|
defaultValue
|
|
649
762
|
});
|
|
650
763
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
651
|
-
const handleClick = (0,
|
|
764
|
+
const handleClick = (0, import_react8.useCallback)(
|
|
652
765
|
(e) => {
|
|
653
766
|
if (isEditMode) {
|
|
654
767
|
e.preventDefault();
|
|
@@ -659,26 +772,44 @@ function EditableHTML({
|
|
|
659
772
|
[isEditMode, contentKey, value, section, sendEditRequest]
|
|
660
773
|
);
|
|
661
774
|
if (isLoading) {
|
|
662
|
-
return (0,
|
|
775
|
+
return (0, import_react8.createElement)(as, {
|
|
663
776
|
className: cn("animate-pulse bg-muted rounded h-32", className),
|
|
664
777
|
"aria-busy": true
|
|
665
778
|
});
|
|
666
779
|
}
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
"
|
|
672
|
-
|
|
780
|
+
const wrapperStyle = isEditMode ? {
|
|
781
|
+
position: "relative",
|
|
782
|
+
cursor: "pointer",
|
|
783
|
+
borderRadius: "2px",
|
|
784
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
785
|
+
outlineOffset: "2px",
|
|
786
|
+
backgroundColor: isHovered ? "rgba(59 130 246 / 0.08)" : void 0
|
|
787
|
+
} : {};
|
|
673
788
|
const safeHtml = sanitizeHtml(value);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
"
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
789
|
+
const hoverHandlers = isEditMode ? { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) } : {};
|
|
790
|
+
return (0, import_react8.createElement)(
|
|
791
|
+
"div",
|
|
792
|
+
{ style: wrapperStyle, ...hoverHandlers },
|
|
793
|
+
(0, import_react8.createElement)(as, {
|
|
794
|
+
className: cn("prose prose-slate dark:prose-invert", className),
|
|
795
|
+
"data-content-key": contentKey,
|
|
796
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
797
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
798
|
+
dangerouslySetInnerHTML: { __html: safeHtml }
|
|
799
|
+
}),
|
|
800
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
801
|
+
"span",
|
|
802
|
+
{
|
|
803
|
+
style: {
|
|
804
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
805
|
+
top: "-24px",
|
|
806
|
+
opacity: isHovered ? 1 : 0
|
|
807
|
+
},
|
|
808
|
+
"aria-hidden": true,
|
|
809
|
+
children: "Click to edit"
|
|
810
|
+
}
|
|
811
|
+
)
|
|
812
|
+
);
|
|
682
813
|
}
|
|
683
814
|
function EditableImage({
|
|
684
815
|
contentKey,
|
|
@@ -689,13 +820,14 @@ function EditableImage({
|
|
|
689
820
|
height,
|
|
690
821
|
priority = false
|
|
691
822
|
}) {
|
|
823
|
+
const [isHovered, setIsHovered] = (0, import_react8.useState)(false);
|
|
692
824
|
const isEditMode = useEditModeMessaging();
|
|
693
825
|
const sendEditRequest = useSendEditRequest();
|
|
694
826
|
const { value: src, isLoading } = useSiteContentQuery(contentKey, {
|
|
695
827
|
defaultValue
|
|
696
828
|
});
|
|
697
829
|
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
698
|
-
const handleClick = (0,
|
|
830
|
+
const handleClick = (0, import_react8.useCallback)(
|
|
699
831
|
(e) => {
|
|
700
832
|
if (isEditMode) {
|
|
701
833
|
e.preventDefault();
|
|
@@ -715,39 +847,55 @@ function EditableImage({
|
|
|
715
847
|
}
|
|
716
848
|
);
|
|
717
849
|
}
|
|
718
|
-
const
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
850
|
+
const wrapperStyle = isEditMode ? {
|
|
851
|
+
position: "relative",
|
|
852
|
+
display: "inline-block",
|
|
853
|
+
cursor: "pointer",
|
|
854
|
+
borderRadius: "2px",
|
|
855
|
+
outline: isHovered ? "2px solid rgb(59 130 246)" : "none",
|
|
856
|
+
outlineOffset: "2px"
|
|
857
|
+
} : {};
|
|
858
|
+
const hoverHandlers = isEditMode ? { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false) } : {};
|
|
859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: wrapperStyle, ...hoverHandlers, children: [
|
|
725
860
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
726
861
|
"img",
|
|
727
862
|
{
|
|
728
863
|
src,
|
|
729
864
|
alt,
|
|
730
|
-
className
|
|
865
|
+
className,
|
|
866
|
+
style: isEditMode && isHovered ? { opacity: 0.95 } : void 0,
|
|
731
867
|
width,
|
|
732
868
|
height,
|
|
733
869
|
loading: priority ? "eager" : "lazy",
|
|
734
870
|
"data-content-key": contentKey,
|
|
735
871
|
"data-editable": isEditMode ? "true" : void 0,
|
|
736
|
-
onClick: isEditMode ? handleClick : void 0
|
|
737
|
-
title: isEditMode ? "Click to edit image" : void 0
|
|
872
|
+
onClick: isEditMode ? handleClick : void 0
|
|
738
873
|
}
|
|
739
874
|
),
|
|
740
|
-
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
875
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
876
|
+
"span",
|
|
877
|
+
{
|
|
878
|
+
style: {
|
|
879
|
+
...EDIT_MODE_TOOLTIP_STYLE,
|
|
880
|
+
top: "8px",
|
|
881
|
+
left: "8px",
|
|
882
|
+
transform: "none",
|
|
883
|
+
opacity: isHovered ? 1 : 0
|
|
884
|
+
},
|
|
885
|
+
"aria-hidden": true,
|
|
886
|
+
children: "Click to edit image"
|
|
887
|
+
}
|
|
888
|
+
)
|
|
741
889
|
] });
|
|
742
890
|
}
|
|
743
891
|
|
|
744
892
|
// src/hooks/useServices.ts
|
|
745
|
-
var
|
|
893
|
+
var import_react9 = require("react");
|
|
746
894
|
function useServices(options = {}) {
|
|
747
895
|
const { client } = useFoxPixelContext();
|
|
748
|
-
const [services, setServices] = (0,
|
|
749
|
-
const [isLoading, setIsLoading] = (0,
|
|
750
|
-
const [error, setError] = (0,
|
|
896
|
+
const [services, setServices] = (0, import_react9.useState)(null);
|
|
897
|
+
const [isLoading, setIsLoading] = (0, import_react9.useState)(true);
|
|
898
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
751
899
|
const fetchServices = async () => {
|
|
752
900
|
try {
|
|
753
901
|
setIsLoading(true);
|
|
@@ -765,7 +913,7 @@ function useServices(options = {}) {
|
|
|
765
913
|
setIsLoading(false);
|
|
766
914
|
}
|
|
767
915
|
};
|
|
768
|
-
(0,
|
|
916
|
+
(0, import_react9.useEffect)(() => {
|
|
769
917
|
fetchServices();
|
|
770
918
|
}, [options.category, options.active]);
|
|
771
919
|
return {
|
|
@@ -777,11 +925,11 @@ function useServices(options = {}) {
|
|
|
777
925
|
}
|
|
778
926
|
|
|
779
927
|
// src/hooks/useLeadCapture.ts
|
|
780
|
-
var
|
|
928
|
+
var import_react10 = require("react");
|
|
781
929
|
function useLeadCapture() {
|
|
782
930
|
const { client } = useFoxPixelContext();
|
|
783
|
-
const [isLoading, setIsLoading] = (0,
|
|
784
|
-
const [error, setError] = (0,
|
|
931
|
+
const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
|
|
932
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
785
933
|
const captureLead = async (data) => {
|
|
786
934
|
try {
|
|
787
935
|
setIsLoading(true);
|
|
@@ -804,11 +952,11 @@ function useLeadCapture() {
|
|
|
804
952
|
}
|
|
805
953
|
|
|
806
954
|
// src/hooks/useContactCapture.ts
|
|
807
|
-
var
|
|
955
|
+
var import_react11 = require("react");
|
|
808
956
|
function useContactCapture() {
|
|
809
957
|
const { client } = useFoxPixelContext();
|
|
810
|
-
const [isLoading, setIsLoading] = (0,
|
|
811
|
-
const [error, setError] = (0,
|
|
958
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
|
|
959
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
812
960
|
const captureContact = async (data) => {
|
|
813
961
|
try {
|
|
814
962
|
setIsLoading(true);
|
|
@@ -831,16 +979,16 @@ function useContactCapture() {
|
|
|
831
979
|
}
|
|
832
980
|
|
|
833
981
|
// src/hooks/useSiteContent.ts
|
|
834
|
-
var
|
|
982
|
+
var import_react12 = require("react");
|
|
835
983
|
function useSiteContent(contentKey, options = {}) {
|
|
836
984
|
const { defaultValue = "", fetchOnMount = true } = options;
|
|
837
985
|
const { client } = useFoxPixelContext();
|
|
838
986
|
const { user, hasPermission } = useAuth();
|
|
839
|
-
const [data, setData] = (0,
|
|
840
|
-
const [isLoading, setIsLoading] = (0,
|
|
841
|
-
const [error, setError] = (0,
|
|
987
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
988
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(fetchOnMount);
|
|
989
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
842
990
|
const canEdit = user !== null && hasPermission("site:content:update");
|
|
843
|
-
const fetchContent = (0,
|
|
991
|
+
const fetchContent = (0, import_react12.useCallback)(async () => {
|
|
844
992
|
try {
|
|
845
993
|
setIsLoading(true);
|
|
846
994
|
setError(null);
|
|
@@ -858,7 +1006,7 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
858
1006
|
setIsLoading(false);
|
|
859
1007
|
}
|
|
860
1008
|
}, [client, contentKey]);
|
|
861
|
-
const updateContent = (0,
|
|
1009
|
+
const updateContent = (0, import_react12.useCallback)(async (newValue) => {
|
|
862
1010
|
try {
|
|
863
1011
|
setError(null);
|
|
864
1012
|
const updated = await client.put(
|
|
@@ -871,7 +1019,7 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
871
1019
|
throw err;
|
|
872
1020
|
}
|
|
873
1021
|
}, [client, contentKey]);
|
|
874
|
-
(0,
|
|
1022
|
+
(0, import_react12.useEffect)(() => {
|
|
875
1023
|
if (fetchOnMount) {
|
|
876
1024
|
fetchContent();
|
|
877
1025
|
}
|
|
@@ -890,10 +1038,10 @@ function useSiteContent(contentKey, options = {}) {
|
|
|
890
1038
|
function useSiteContents(contentKeys, options = {}) {
|
|
891
1039
|
const { defaults = {} } = options;
|
|
892
1040
|
const { client } = useFoxPixelContext();
|
|
893
|
-
const [data, setData] = (0,
|
|
894
|
-
const [isLoading, setIsLoading] = (0,
|
|
895
|
-
const [error, setError] = (0,
|
|
896
|
-
const fetchContents = (0,
|
|
1041
|
+
const [data, setData] = (0, import_react12.useState)({});
|
|
1042
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
1043
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1044
|
+
const fetchContents = (0, import_react12.useCallback)(async () => {
|
|
897
1045
|
if (contentKeys.length === 0) {
|
|
898
1046
|
setData({});
|
|
899
1047
|
setIsLoading(false);
|
|
@@ -913,10 +1061,10 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
913
1061
|
setIsLoading(false);
|
|
914
1062
|
}
|
|
915
1063
|
}, [client, contentKeys.join(",")]);
|
|
916
|
-
(0,
|
|
1064
|
+
(0, import_react12.useEffect)(() => {
|
|
917
1065
|
fetchContents();
|
|
918
1066
|
}, [fetchContents]);
|
|
919
|
-
const getValue = (0,
|
|
1067
|
+
const getValue = (0, import_react12.useCallback)((key, defaultValue) => {
|
|
920
1068
|
const content = data[key];
|
|
921
1069
|
if (content?.value) {
|
|
922
1070
|
return content.value;
|
|
@@ -933,10 +1081,10 @@ function useSiteContents(contentKeys, options = {}) {
|
|
|
933
1081
|
}
|
|
934
1082
|
function useSiteContentSection(section) {
|
|
935
1083
|
const { client } = useFoxPixelContext();
|
|
936
|
-
const [contents, setContents] = (0,
|
|
937
|
-
const [isLoading, setIsLoading] = (0,
|
|
938
|
-
const [error, setError] = (0,
|
|
939
|
-
const fetchContents = (0,
|
|
1084
|
+
const [contents, setContents] = (0, import_react12.useState)([]);
|
|
1085
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
1086
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1087
|
+
const fetchContents = (0, import_react12.useCallback)(async () => {
|
|
940
1088
|
try {
|
|
941
1089
|
setIsLoading(true);
|
|
942
1090
|
setError(null);
|
|
@@ -950,7 +1098,7 @@ function useSiteContentSection(section) {
|
|
|
950
1098
|
setIsLoading(false);
|
|
951
1099
|
}
|
|
952
1100
|
}, [client, section]);
|
|
953
|
-
(0,
|
|
1101
|
+
(0, import_react12.useEffect)(() => {
|
|
954
1102
|
fetchContents();
|
|
955
1103
|
}, [fetchContents]);
|
|
956
1104
|
return {
|
|
@@ -961,13 +1109,43 @@ function useSiteContentSection(section) {
|
|
|
961
1109
|
};
|
|
962
1110
|
}
|
|
963
1111
|
|
|
1112
|
+
// src/prefetchSiteContent.ts
|
|
1113
|
+
async function prefetchSiteContent(queryClient, options) {
|
|
1114
|
+
const { apiUrl, apiKey, tenantId, contentKeys } = options;
|
|
1115
|
+
const client = new FoxPixelHttpClient({ apiUrl, apiKey, tenantId });
|
|
1116
|
+
await Promise.all(
|
|
1117
|
+
contentKeys.map(async (contentKey) => {
|
|
1118
|
+
try {
|
|
1119
|
+
const content = await client.get(
|
|
1120
|
+
`/api/site/content/${encodeURIComponent(contentKey)}`
|
|
1121
|
+
);
|
|
1122
|
+
queryClient.setQueryData(
|
|
1123
|
+
[SITE_CONTENT_QUERY_KEY, contentKey],
|
|
1124
|
+
{
|
|
1125
|
+
value: content?.value ?? "",
|
|
1126
|
+
contentType: content?.contentType ?? "TEXT"
|
|
1127
|
+
}
|
|
1128
|
+
);
|
|
1129
|
+
} catch (err) {
|
|
1130
|
+
const status = err?.response?.status;
|
|
1131
|
+
if (status === 404) {
|
|
1132
|
+
queryClient.setQueryData([SITE_CONTENT_QUERY_KEY, contentKey], {
|
|
1133
|
+
value: "",
|
|
1134
|
+
contentType: "TEXT"
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
})
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
964
1142
|
// src/blog/hooks.ts
|
|
965
|
-
var
|
|
1143
|
+
var import_react13 = require("react");
|
|
966
1144
|
function useBlogPosts(options = {}) {
|
|
967
1145
|
const { client } = useFoxPixelContext();
|
|
968
|
-
const [data, setData] = (0,
|
|
969
|
-
const [isLoading, setIsLoading] = (0,
|
|
970
|
-
const [error, setError] = (0,
|
|
1146
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1147
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1148
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
971
1149
|
const page = options.page ?? 0;
|
|
972
1150
|
const limit = options.limit ?? 10;
|
|
973
1151
|
const fetchPosts = async () => {
|
|
@@ -987,7 +1165,7 @@ function useBlogPosts(options = {}) {
|
|
|
987
1165
|
setIsLoading(false);
|
|
988
1166
|
}
|
|
989
1167
|
};
|
|
990
|
-
(0,
|
|
1168
|
+
(0, import_react13.useEffect)(() => {
|
|
991
1169
|
fetchPosts();
|
|
992
1170
|
}, [page, limit]);
|
|
993
1171
|
return {
|
|
@@ -999,9 +1177,9 @@ function useBlogPosts(options = {}) {
|
|
|
999
1177
|
}
|
|
1000
1178
|
function useBlogPost(slug) {
|
|
1001
1179
|
const { client } = useFoxPixelContext();
|
|
1002
|
-
const [data, setData] = (0,
|
|
1003
|
-
const [isLoading, setIsLoading] = (0,
|
|
1004
|
-
const [error, setError] = (0,
|
|
1180
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1181
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(!!slug);
|
|
1182
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1005
1183
|
const fetchPost = async () => {
|
|
1006
1184
|
if (!slug) {
|
|
1007
1185
|
setData(null);
|
|
@@ -1020,7 +1198,7 @@ function useBlogPost(slug) {
|
|
|
1020
1198
|
setIsLoading(false);
|
|
1021
1199
|
}
|
|
1022
1200
|
};
|
|
1023
|
-
(0,
|
|
1201
|
+
(0, import_react13.useEffect)(() => {
|
|
1024
1202
|
fetchPost();
|
|
1025
1203
|
}, [slug]);
|
|
1026
1204
|
return {
|
|
@@ -1032,9 +1210,9 @@ function useBlogPost(slug) {
|
|
|
1032
1210
|
}
|
|
1033
1211
|
function useBlogCategories() {
|
|
1034
1212
|
const { client } = useFoxPixelContext();
|
|
1035
|
-
const [data, setData] = (0,
|
|
1036
|
-
const [isLoading, setIsLoading] = (0,
|
|
1037
|
-
const [error, setError] = (0,
|
|
1213
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1214
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1215
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1038
1216
|
const fetchCategories = async () => {
|
|
1039
1217
|
try {
|
|
1040
1218
|
setIsLoading(true);
|
|
@@ -1048,7 +1226,7 @@ function useBlogCategories() {
|
|
|
1048
1226
|
setIsLoading(false);
|
|
1049
1227
|
}
|
|
1050
1228
|
};
|
|
1051
|
-
(0,
|
|
1229
|
+
(0, import_react13.useEffect)(() => {
|
|
1052
1230
|
fetchCategories();
|
|
1053
1231
|
}, []);
|
|
1054
1232
|
return {
|
|
@@ -1060,9 +1238,9 @@ function useBlogCategories() {
|
|
|
1060
1238
|
}
|
|
1061
1239
|
function useBlogTags() {
|
|
1062
1240
|
const { client } = useFoxPixelContext();
|
|
1063
|
-
const [data, setData] = (0,
|
|
1064
|
-
const [isLoading, setIsLoading] = (0,
|
|
1065
|
-
const [error, setError] = (0,
|
|
1241
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1242
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1243
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1066
1244
|
const fetchTags = async () => {
|
|
1067
1245
|
try {
|
|
1068
1246
|
setIsLoading(true);
|
|
@@ -1076,7 +1254,7 @@ function useBlogTags() {
|
|
|
1076
1254
|
setIsLoading(false);
|
|
1077
1255
|
}
|
|
1078
1256
|
};
|
|
1079
|
-
(0,
|
|
1257
|
+
(0, import_react13.useEffect)(() => {
|
|
1080
1258
|
fetchTags();
|
|
1081
1259
|
}, []);
|
|
1082
1260
|
return {
|
|
@@ -1088,9 +1266,9 @@ function useBlogTags() {
|
|
|
1088
1266
|
}
|
|
1089
1267
|
function useBlogComments(slug) {
|
|
1090
1268
|
const { client } = useFoxPixelContext();
|
|
1091
|
-
const [data, setData] = (0,
|
|
1092
|
-
const [isLoading, setIsLoading] = (0,
|
|
1093
|
-
const [error, setError] = (0,
|
|
1269
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1270
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(!!slug);
|
|
1271
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1094
1272
|
const fetchComments = async () => {
|
|
1095
1273
|
if (!slug) {
|
|
1096
1274
|
setData(null);
|
|
@@ -1111,7 +1289,7 @@ function useBlogComments(slug) {
|
|
|
1111
1289
|
setIsLoading(false);
|
|
1112
1290
|
}
|
|
1113
1291
|
};
|
|
1114
|
-
(0,
|
|
1292
|
+
(0, import_react13.useEffect)(() => {
|
|
1115
1293
|
fetchComments();
|
|
1116
1294
|
}, [slug]);
|
|
1117
1295
|
return {
|
|
@@ -1123,8 +1301,8 @@ function useBlogComments(slug) {
|
|
|
1123
1301
|
}
|
|
1124
1302
|
function useBlogCommentSubmit(slug) {
|
|
1125
1303
|
const { client } = useFoxPixelContext();
|
|
1126
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
1127
|
-
const [error, setError] = (0,
|
|
1304
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react13.useState)(false);
|
|
1305
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1128
1306
|
const submit = async (payload) => {
|
|
1129
1307
|
if (!slug) return null;
|
|
1130
1308
|
try {
|
|
@@ -1152,9 +1330,9 @@ function useBlogCommentSubmit(slug) {
|
|
|
1152
1330
|
}
|
|
1153
1331
|
function useBlogFeaturedPosts(limit = 6) {
|
|
1154
1332
|
const { client } = useFoxPixelContext();
|
|
1155
|
-
const [data, setData] = (0,
|
|
1156
|
-
const [isLoading, setIsLoading] = (0,
|
|
1157
|
-
const [error, setError] = (0,
|
|
1333
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1334
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1335
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1158
1336
|
const fetchFeatured = async () => {
|
|
1159
1337
|
try {
|
|
1160
1338
|
setIsLoading(true);
|
|
@@ -1172,7 +1350,7 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
1172
1350
|
setIsLoading(false);
|
|
1173
1351
|
}
|
|
1174
1352
|
};
|
|
1175
|
-
(0,
|
|
1353
|
+
(0, import_react13.useEffect)(() => {
|
|
1176
1354
|
fetchFeatured();
|
|
1177
1355
|
}, [limit]);
|
|
1178
1356
|
return {
|
|
@@ -1184,9 +1362,9 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
1184
1362
|
}
|
|
1185
1363
|
function useNewsletterSubscribe() {
|
|
1186
1364
|
const { client } = useFoxPixelContext();
|
|
1187
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
1188
|
-
const [error, setError] = (0,
|
|
1189
|
-
const [success, setSuccess] = (0,
|
|
1365
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react13.useState)(false);
|
|
1366
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1367
|
+
const [success, setSuccess] = (0, import_react13.useState)(false);
|
|
1190
1368
|
const subscribe = async (payload) => {
|
|
1191
1369
|
try {
|
|
1192
1370
|
setIsSubmitting(true);
|
|
@@ -1219,9 +1397,9 @@ function useNewsletterSubscribe() {
|
|
|
1219
1397
|
}
|
|
1220
1398
|
function useNewsletterUnsubscribe() {
|
|
1221
1399
|
const { client } = useFoxPixelContext();
|
|
1222
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
1223
|
-
const [error, setError] = (0,
|
|
1224
|
-
const [success, setSuccess] = (0,
|
|
1400
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react13.useState)(false);
|
|
1401
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1402
|
+
const [success, setSuccess] = (0, import_react13.useState)(false);
|
|
1225
1403
|
const unsubscribe = async (email) => {
|
|
1226
1404
|
try {
|
|
1227
1405
|
setIsSubmitting(true);
|
|
@@ -1266,15 +1444,15 @@ function useNewsletterUnsubscribe() {
|
|
|
1266
1444
|
}
|
|
1267
1445
|
|
|
1268
1446
|
// src/blog/admin-hooks.ts
|
|
1269
|
-
var
|
|
1447
|
+
var import_react14 = require("react");
|
|
1270
1448
|
function useAdminBlogPosts(options = {}) {
|
|
1271
1449
|
const { client } = useFoxPixelContext();
|
|
1272
|
-
const [data, setData] = (0,
|
|
1273
|
-
const [isLoading, setIsLoading] = (0,
|
|
1274
|
-
const [error, setError] = (0,
|
|
1450
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1451
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1452
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1275
1453
|
const page = options.page ?? 0;
|
|
1276
1454
|
const size = options.size ?? 20;
|
|
1277
|
-
const fetchPosts = (0,
|
|
1455
|
+
const fetchPosts = (0, import_react14.useCallback)(async () => {
|
|
1278
1456
|
try {
|
|
1279
1457
|
setIsLoading(true);
|
|
1280
1458
|
setError(null);
|
|
@@ -1289,17 +1467,17 @@ function useAdminBlogPosts(options = {}) {
|
|
|
1289
1467
|
setIsLoading(false);
|
|
1290
1468
|
}
|
|
1291
1469
|
}, [client, page, size]);
|
|
1292
|
-
(0,
|
|
1470
|
+
(0, import_react14.useEffect)(() => {
|
|
1293
1471
|
fetchPosts();
|
|
1294
1472
|
}, [fetchPosts]);
|
|
1295
1473
|
return { data, isLoading, error, refetch: fetchPosts };
|
|
1296
1474
|
}
|
|
1297
1475
|
function useAdminBlogPost(id) {
|
|
1298
1476
|
const { client } = useFoxPixelContext();
|
|
1299
|
-
const [data, setData] = (0,
|
|
1300
|
-
const [isLoading, setIsLoading] = (0,
|
|
1301
|
-
const [error, setError] = (0,
|
|
1302
|
-
const fetchPost = (0,
|
|
1477
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1478
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(!!id);
|
|
1479
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1480
|
+
const fetchPost = (0, import_react14.useCallback)(async () => {
|
|
1303
1481
|
if (!id) {
|
|
1304
1482
|
setData(null);
|
|
1305
1483
|
setIsLoading(false);
|
|
@@ -1316,15 +1494,15 @@ function useAdminBlogPost(id) {
|
|
|
1316
1494
|
setIsLoading(false);
|
|
1317
1495
|
}
|
|
1318
1496
|
}, [client, id]);
|
|
1319
|
-
(0,
|
|
1497
|
+
(0, import_react14.useEffect)(() => {
|
|
1320
1498
|
fetchPost();
|
|
1321
1499
|
}, [fetchPost]);
|
|
1322
1500
|
return { data, isLoading, error, refetch: fetchPost };
|
|
1323
1501
|
}
|
|
1324
1502
|
function useAdminBlogPostMutations() {
|
|
1325
1503
|
const { client } = useFoxPixelContext();
|
|
1326
|
-
const [isLoading, setIsLoading] = (0,
|
|
1327
|
-
const [error, setError] = (0,
|
|
1504
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
|
|
1505
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1328
1506
|
const create = async (payload) => {
|
|
1329
1507
|
try {
|
|
1330
1508
|
setIsLoading(true);
|
|
@@ -1368,10 +1546,10 @@ function useAdminBlogPostMutations() {
|
|
|
1368
1546
|
}
|
|
1369
1547
|
function useAdminBlogCategories() {
|
|
1370
1548
|
const { client } = useFoxPixelContext();
|
|
1371
|
-
const [data, setData] = (0,
|
|
1372
|
-
const [isLoading, setIsLoading] = (0,
|
|
1373
|
-
const [error, setError] = (0,
|
|
1374
|
-
const fetchCategories = (0,
|
|
1549
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1550
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1551
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1552
|
+
const fetchCategories = (0, import_react14.useCallback)(async () => {
|
|
1375
1553
|
try {
|
|
1376
1554
|
setIsLoading(true);
|
|
1377
1555
|
setError(null);
|
|
@@ -1383,7 +1561,7 @@ function useAdminBlogCategories() {
|
|
|
1383
1561
|
setIsLoading(false);
|
|
1384
1562
|
}
|
|
1385
1563
|
}, [client]);
|
|
1386
|
-
(0,
|
|
1564
|
+
(0, import_react14.useEffect)(() => {
|
|
1387
1565
|
fetchCategories();
|
|
1388
1566
|
}, [fetchCategories]);
|
|
1389
1567
|
const create = async (payload) => {
|
|
@@ -1420,10 +1598,10 @@ function useAdminBlogCategories() {
|
|
|
1420
1598
|
}
|
|
1421
1599
|
function useAdminBlogTags() {
|
|
1422
1600
|
const { client } = useFoxPixelContext();
|
|
1423
|
-
const [data, setData] = (0,
|
|
1424
|
-
const [isLoading, setIsLoading] = (0,
|
|
1425
|
-
const [error, setError] = (0,
|
|
1426
|
-
const fetchTags = (0,
|
|
1601
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1602
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1603
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1604
|
+
const fetchTags = (0, import_react14.useCallback)(async () => {
|
|
1427
1605
|
try {
|
|
1428
1606
|
setIsLoading(true);
|
|
1429
1607
|
setError(null);
|
|
@@ -1435,7 +1613,7 @@ function useAdminBlogTags() {
|
|
|
1435
1613
|
setIsLoading(false);
|
|
1436
1614
|
}
|
|
1437
1615
|
}, [client]);
|
|
1438
|
-
(0,
|
|
1616
|
+
(0, import_react14.useEffect)(() => {
|
|
1439
1617
|
fetchTags();
|
|
1440
1618
|
}, [fetchTags]);
|
|
1441
1619
|
const create = async (payload) => {
|
|
@@ -1472,11 +1650,11 @@ function useAdminBlogTags() {
|
|
|
1472
1650
|
}
|
|
1473
1651
|
function useAdminBlogComments(options = {}) {
|
|
1474
1652
|
const { client } = useFoxPixelContext();
|
|
1475
|
-
const [data, setData] = (0,
|
|
1476
|
-
const [isLoading, setIsLoading] = (0,
|
|
1477
|
-
const [error, setError] = (0,
|
|
1653
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1654
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1655
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1478
1656
|
const { status, postId, page = 0, size = 20 } = options;
|
|
1479
|
-
const fetchComments = (0,
|
|
1657
|
+
const fetchComments = (0, import_react14.useCallback)(async () => {
|
|
1480
1658
|
try {
|
|
1481
1659
|
setIsLoading(true);
|
|
1482
1660
|
setError(null);
|
|
@@ -1493,7 +1671,7 @@ function useAdminBlogComments(options = {}) {
|
|
|
1493
1671
|
setIsLoading(false);
|
|
1494
1672
|
}
|
|
1495
1673
|
}, [client, status, postId, page, size]);
|
|
1496
|
-
(0,
|
|
1674
|
+
(0, import_react14.useEffect)(() => {
|
|
1497
1675
|
fetchComments();
|
|
1498
1676
|
}, [fetchComments]);
|
|
1499
1677
|
const updateStatus = async (id, newStatus) => {
|
|
@@ -1520,11 +1698,11 @@ function useAdminBlogComments(options = {}) {
|
|
|
1520
1698
|
}
|
|
1521
1699
|
function useAdminNewsletterSubscribers(options = {}) {
|
|
1522
1700
|
const { client } = useFoxPixelContext();
|
|
1523
|
-
const [data, setData] = (0,
|
|
1524
|
-
const [isLoading, setIsLoading] = (0,
|
|
1525
|
-
const [error, setError] = (0,
|
|
1701
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1702
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1703
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1526
1704
|
const { status, page = 0, size = 20 } = options;
|
|
1527
|
-
const fetchSubscribers = (0,
|
|
1705
|
+
const fetchSubscribers = (0, import_react14.useCallback)(async () => {
|
|
1528
1706
|
try {
|
|
1529
1707
|
setIsLoading(true);
|
|
1530
1708
|
setError(null);
|
|
@@ -1540,7 +1718,7 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1540
1718
|
setIsLoading(false);
|
|
1541
1719
|
}
|
|
1542
1720
|
}, [client, status, page, size]);
|
|
1543
|
-
(0,
|
|
1721
|
+
(0, import_react14.useEffect)(() => {
|
|
1544
1722
|
fetchSubscribers();
|
|
1545
1723
|
}, [fetchSubscribers]);
|
|
1546
1724
|
const remove = async (id) => {
|
|
@@ -1557,10 +1735,10 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1557
1735
|
}
|
|
1558
1736
|
function useAdminNewsletterStats() {
|
|
1559
1737
|
const { client } = useFoxPixelContext();
|
|
1560
|
-
const [data, setData] = (0,
|
|
1561
|
-
const [isLoading, setIsLoading] = (0,
|
|
1562
|
-
const [error, setError] = (0,
|
|
1563
|
-
const fetchStats = (0,
|
|
1738
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1739
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1740
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1741
|
+
const fetchStats = (0, import_react14.useCallback)(async () => {
|
|
1564
1742
|
try {
|
|
1565
1743
|
setIsLoading(true);
|
|
1566
1744
|
setError(null);
|
|
@@ -1572,17 +1750,17 @@ function useAdminNewsletterStats() {
|
|
|
1572
1750
|
setIsLoading(false);
|
|
1573
1751
|
}
|
|
1574
1752
|
}, [client]);
|
|
1575
|
-
(0,
|
|
1753
|
+
(0, import_react14.useEffect)(() => {
|
|
1576
1754
|
fetchStats();
|
|
1577
1755
|
}, [fetchStats]);
|
|
1578
1756
|
return { data, isLoading, error, refetch: fetchStats };
|
|
1579
1757
|
}
|
|
1580
1758
|
function useAdminBlogSettings() {
|
|
1581
1759
|
const { client } = useFoxPixelContext();
|
|
1582
|
-
const [data, setData] = (0,
|
|
1583
|
-
const [isLoading, setIsLoading] = (0,
|
|
1584
|
-
const [error, setError] = (0,
|
|
1585
|
-
const fetchSettings = (0,
|
|
1760
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1761
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1762
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1763
|
+
const fetchSettings = (0, import_react14.useCallback)(async () => {
|
|
1586
1764
|
try {
|
|
1587
1765
|
setIsLoading(true);
|
|
1588
1766
|
setError(null);
|
|
@@ -1594,7 +1772,7 @@ function useAdminBlogSettings() {
|
|
|
1594
1772
|
setIsLoading(false);
|
|
1595
1773
|
}
|
|
1596
1774
|
}, [client]);
|
|
1597
|
-
(0,
|
|
1775
|
+
(0, import_react14.useEffect)(() => {
|
|
1598
1776
|
fetchSettings();
|
|
1599
1777
|
}, [fetchSettings]);
|
|
1600
1778
|
const update = async (settings) => {
|
|
@@ -1611,10 +1789,10 @@ function useAdminBlogSettings() {
|
|
|
1611
1789
|
}
|
|
1612
1790
|
function useAdminBlogAnalytics() {
|
|
1613
1791
|
const { client } = useFoxPixelContext();
|
|
1614
|
-
const [data, setData] = (0,
|
|
1615
|
-
const [isLoading, setIsLoading] = (0,
|
|
1616
|
-
const [error, setError] = (0,
|
|
1617
|
-
const fetchAnalytics = (0,
|
|
1792
|
+
const [data, setData] = (0, import_react14.useState)(null);
|
|
1793
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
1794
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1795
|
+
const fetchAnalytics = (0, import_react14.useCallback)(async () => {
|
|
1618
1796
|
try {
|
|
1619
1797
|
setIsLoading(true);
|
|
1620
1798
|
setError(null);
|
|
@@ -1626,7 +1804,7 @@ function useAdminBlogAnalytics() {
|
|
|
1626
1804
|
setIsLoading(false);
|
|
1627
1805
|
}
|
|
1628
1806
|
}, [client]);
|
|
1629
|
-
(0,
|
|
1807
|
+
(0, import_react14.useEffect)(() => {
|
|
1630
1808
|
fetchAnalytics();
|
|
1631
1809
|
}, [fetchAnalytics]);
|
|
1632
1810
|
return { data, isLoading, error, refetch: fetchAnalytics };
|
|
@@ -1675,6 +1853,7 @@ function getBlogPostSchemaLd(post, options) {
|
|
|
1675
1853
|
ProtectedRoute,
|
|
1676
1854
|
SITE_CONTENT_QUERY_KEY,
|
|
1677
1855
|
getBlogPostSchemaLd,
|
|
1856
|
+
prefetchSiteContent,
|
|
1678
1857
|
useAdminBlogAnalytics,
|
|
1679
1858
|
useAdminBlogCategories,
|
|
1680
1859
|
useAdminBlogComments,
|