@foxpixel/react 0.1.1 → 0.2.0
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 +285 -2
- package/dist/index.d.ts +285 -2
- package/dist/index.js +584 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +573 -93
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -3
package/dist/index.js
CHANGED
|
@@ -31,10 +31,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AuthProvider: () => AuthProvider,
|
|
34
|
+
Editable: () => Editable,
|
|
35
|
+
EditableHTML: () => EditableHTML,
|
|
36
|
+
EditableImage: () => EditableImage,
|
|
34
37
|
FoxPixelHttpClient: () => FoxPixelHttpClient,
|
|
35
38
|
FoxPixelProvider: () => FoxPixelProvider,
|
|
36
39
|
GuestOnlyRoute: () => GuestOnlyRoute,
|
|
37
40
|
ProtectedRoute: () => ProtectedRoute,
|
|
41
|
+
SITE_CONTENT_QUERY_KEY: () => SITE_CONTENT_QUERY_KEY,
|
|
38
42
|
getBlogPostSchemaLd: () => getBlogPostSchemaLd,
|
|
39
43
|
useAdminBlogAnalytics: () => useAdminBlogAnalytics,
|
|
40
44
|
useAdminBlogCategories: () => useAdminBlogCategories,
|
|
@@ -55,11 +59,18 @@ __export(index_exports, {
|
|
|
55
59
|
useBlogPosts: () => useBlogPosts,
|
|
56
60
|
useBlogTags: () => useBlogTags,
|
|
57
61
|
useContactCapture: () => useContactCapture,
|
|
62
|
+
useEditMode: () => useEditMode,
|
|
63
|
+
useEditModeMessaging: () => useEditModeMessaging,
|
|
58
64
|
useFoxPixelContext: () => useFoxPixelContext,
|
|
59
65
|
useLeadCapture: () => useLeadCapture,
|
|
60
66
|
useNewsletterSubscribe: () => useNewsletterSubscribe,
|
|
61
67
|
useNewsletterUnsubscribe: () => useNewsletterUnsubscribe,
|
|
68
|
+
useSendEditRequest: () => useSendEditRequest,
|
|
62
69
|
useServices: () => useServices,
|
|
70
|
+
useSiteContent: () => useSiteContent,
|
|
71
|
+
useSiteContentQuery: () => useSiteContentQuery,
|
|
72
|
+
useSiteContentSection: () => useSiteContentSection,
|
|
73
|
+
useSiteContents: () => useSiteContents,
|
|
63
74
|
withAuth: () => withAuth
|
|
64
75
|
});
|
|
65
76
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -304,7 +315,8 @@ function AuthProvider({
|
|
|
304
315
|
logout,
|
|
305
316
|
register,
|
|
306
317
|
updateProfile,
|
|
307
|
-
refetch: fetchCurrentUser
|
|
318
|
+
refetch: fetchCurrentUser,
|
|
319
|
+
hasPermission: (permission) => user !== null && permission === "site:content:update"
|
|
308
320
|
};
|
|
309
321
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthContext.Provider, { value, children });
|
|
310
322
|
}
|
|
@@ -410,13 +422,332 @@ function withAuth(Component, options = {}) {
|
|
|
410
422
|
};
|
|
411
423
|
}
|
|
412
424
|
|
|
413
|
-
// src/
|
|
425
|
+
// src/components/Editable.tsx
|
|
426
|
+
var import_react7 = require("react");
|
|
427
|
+
|
|
428
|
+
// src/hooks/useEditMode.ts
|
|
414
429
|
var import_react6 = require("react");
|
|
430
|
+
var import_react_query = require("@tanstack/react-query");
|
|
431
|
+
var SITE_CONTENT_QUERY_KEY = "siteContent";
|
|
432
|
+
function useEditMode() {
|
|
433
|
+
const [isEditMode, setIsEditMode] = (0, import_react6.useState)(false);
|
|
434
|
+
(0, import_react6.useEffect)(() => {
|
|
435
|
+
if (typeof window === "undefined") return;
|
|
436
|
+
const params = new URLSearchParams(window.location.search);
|
|
437
|
+
setIsEditMode(params.get("edit-mode") === "true");
|
|
438
|
+
}, []);
|
|
439
|
+
return isEditMode;
|
|
440
|
+
}
|
|
441
|
+
function useEditModeMessaging() {
|
|
442
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
443
|
+
const isEditMode = useEditMode();
|
|
444
|
+
(0, import_react6.useEffect)(() => {
|
|
445
|
+
if (!isEditMode || typeof window === "undefined") return;
|
|
446
|
+
window.parent.postMessage({ type: "FOXPIXEL_READY" }, "*");
|
|
447
|
+
const handleMessage = (event) => {
|
|
448
|
+
const { type, payload } = event.data || {};
|
|
449
|
+
if (type === "FOXPIXEL_CONTENT_UPDATED" && payload?.contentKey) {
|
|
450
|
+
queryClient.invalidateQueries({
|
|
451
|
+
queryKey: [SITE_CONTENT_QUERY_KEY, payload.contentKey]
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
window.addEventListener("message", handleMessage);
|
|
456
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
457
|
+
}, [isEditMode, queryClient]);
|
|
458
|
+
return isEditMode;
|
|
459
|
+
}
|
|
460
|
+
function useSendEditRequest() {
|
|
461
|
+
const isEditMode = useEditMode();
|
|
462
|
+
return (0, import_react6.useCallback)(
|
|
463
|
+
(contentKey, currentValue, contentType = "text", section, description) => {
|
|
464
|
+
if (!isEditMode) return;
|
|
465
|
+
if (typeof window !== "undefined" && window.parent !== window) {
|
|
466
|
+
window.parent.postMessage(
|
|
467
|
+
{
|
|
468
|
+
type: "FOXPIXEL_EDIT_CONTENT",
|
|
469
|
+
payload: {
|
|
470
|
+
contentKey,
|
|
471
|
+
currentValue,
|
|
472
|
+
contentType,
|
|
473
|
+
section,
|
|
474
|
+
description
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
"*"
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
[isEditMode]
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/hooks/useSiteContentQuery.ts
|
|
486
|
+
var import_react_query2 = require("@tanstack/react-query");
|
|
487
|
+
function useSiteContentQuery(contentKey, options) {
|
|
488
|
+
const { defaultValue } = options;
|
|
489
|
+
const { client } = useFoxPixelContext();
|
|
490
|
+
const { data, isLoading } = (0, import_react_query2.useQuery)({
|
|
491
|
+
queryKey: [SITE_CONTENT_QUERY_KEY, contentKey],
|
|
492
|
+
queryFn: async () => {
|
|
493
|
+
try {
|
|
494
|
+
const content = await client.get(
|
|
495
|
+
`/api/site/content/${encodeURIComponent(contentKey)}`
|
|
496
|
+
);
|
|
497
|
+
if (!content) return null;
|
|
498
|
+
return {
|
|
499
|
+
value: content.value ?? "",
|
|
500
|
+
contentType: content.contentType ?? "TEXT"
|
|
501
|
+
};
|
|
502
|
+
} catch (err) {
|
|
503
|
+
const status = err?.status;
|
|
504
|
+
if (status === 404) return null;
|
|
505
|
+
throw err;
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
staleTime: 1e3 * 60 * 5,
|
|
509
|
+
retry: 1
|
|
510
|
+
});
|
|
511
|
+
return {
|
|
512
|
+
value: data?.value ?? defaultValue,
|
|
513
|
+
isLoading,
|
|
514
|
+
contentType: data?.contentType ?? "TEXT"
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// src/utils/sanitize.ts
|
|
519
|
+
var import_isomorphic_dompurify = __toESM(require("isomorphic-dompurify"));
|
|
520
|
+
var DEFAULT_ALLOWED_TAGS = [
|
|
521
|
+
"p",
|
|
522
|
+
"br",
|
|
523
|
+
"strong",
|
|
524
|
+
"em",
|
|
525
|
+
"u",
|
|
526
|
+
"s",
|
|
527
|
+
"a",
|
|
528
|
+
"ul",
|
|
529
|
+
"ol",
|
|
530
|
+
"li",
|
|
531
|
+
"h1",
|
|
532
|
+
"h2",
|
|
533
|
+
"h3",
|
|
534
|
+
"h4",
|
|
535
|
+
"h5",
|
|
536
|
+
"h6",
|
|
537
|
+
"blockquote",
|
|
538
|
+
"code",
|
|
539
|
+
"pre",
|
|
540
|
+
"span",
|
|
541
|
+
"div",
|
|
542
|
+
"img",
|
|
543
|
+
"table",
|
|
544
|
+
"thead",
|
|
545
|
+
"tbody",
|
|
546
|
+
"tr",
|
|
547
|
+
"th",
|
|
548
|
+
"td"
|
|
549
|
+
];
|
|
550
|
+
var DEFAULT_ALLOWED_ATTR = ["href", "target", "rel", "src", "alt", "title", "class"];
|
|
551
|
+
function sanitizeHtml(html) {
|
|
552
|
+
if (typeof html !== "string") return "";
|
|
553
|
+
return import_isomorphic_dompurify.default.sanitize(html, {
|
|
554
|
+
ALLOWED_TAGS: DEFAULT_ALLOWED_TAGS,
|
|
555
|
+
ALLOWED_ATTR: DEFAULT_ALLOWED_ATTR,
|
|
556
|
+
ADD_ATTR: ["target"]
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/utils/cn.ts
|
|
561
|
+
function cn(...args) {
|
|
562
|
+
return args.filter(Boolean).join(" ");
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/components/Editable.tsx
|
|
566
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
567
|
+
function Editable({
|
|
568
|
+
contentKey,
|
|
569
|
+
defaultValue,
|
|
570
|
+
as = "span",
|
|
571
|
+
multiline = false,
|
|
572
|
+
className
|
|
573
|
+
}) {
|
|
574
|
+
const isEditMode = useEditModeMessaging();
|
|
575
|
+
const sendEditRequest = useSendEditRequest();
|
|
576
|
+
const { value, isLoading, contentType } = useSiteContentQuery(contentKey, {
|
|
577
|
+
defaultValue
|
|
578
|
+
});
|
|
579
|
+
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
580
|
+
const handleClick = (0, import_react7.useCallback)(
|
|
581
|
+
(e) => {
|
|
582
|
+
if (isEditMode) {
|
|
583
|
+
e.preventDefault();
|
|
584
|
+
e.stopPropagation();
|
|
585
|
+
sendEditRequest(
|
|
586
|
+
contentKey,
|
|
587
|
+
value,
|
|
588
|
+
contentType?.toLowerCase() || "text",
|
|
589
|
+
section
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
[isEditMode, contentKey, value, contentType, section, sendEditRequest]
|
|
594
|
+
);
|
|
595
|
+
if (isLoading) {
|
|
596
|
+
return (0, import_react7.createElement)(as, {
|
|
597
|
+
className: cn(
|
|
598
|
+
"animate-pulse bg-muted rounded",
|
|
599
|
+
multiline ? "h-20" : "h-6",
|
|
600
|
+
"inline-block min-w-[100px]",
|
|
601
|
+
className
|
|
602
|
+
),
|
|
603
|
+
"aria-busy": true,
|
|
604
|
+
"aria-label": "Loading content..."
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
const editModeStyles = isEditMode ? cn(
|
|
608
|
+
"cursor-pointer transition-all duration-200",
|
|
609
|
+
"hover:ring-2 hover:ring-blue-500 hover:ring-offset-2",
|
|
610
|
+
"hover:bg-blue-50/50 dark:hover:bg-blue-950/30",
|
|
611
|
+
"relative group"
|
|
612
|
+
) : "";
|
|
613
|
+
if (multiline && value.includes("\n")) {
|
|
614
|
+
const safeBr = sanitizeHtml(value.replace(/\n/g, "<br />"));
|
|
615
|
+
return (0, import_react7.createElement)(as, {
|
|
616
|
+
className: cn(className, editModeStyles),
|
|
617
|
+
"data-content-key": contentKey,
|
|
618
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
619
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
620
|
+
dangerouslySetInnerHTML: { __html: safeBr },
|
|
621
|
+
title: isEditMode ? "Click to edit" : void 0
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
return (0, import_react7.createElement)(
|
|
625
|
+
as,
|
|
626
|
+
{
|
|
627
|
+
className: cn(className, editModeStyles),
|
|
628
|
+
"data-content-key": contentKey,
|
|
629
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
630
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
631
|
+
title: isEditMode ? "Click to edit" : void 0
|
|
632
|
+
},
|
|
633
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
634
|
+
value,
|
|
635
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "absolute -top-6 left-1/2 -translate-x-1/2 px-2 py-0.5 bg-blue-600 text-white text-[10px] rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50", children: "Click to edit" })
|
|
636
|
+
] })
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
function EditableHTML({
|
|
640
|
+
contentKey,
|
|
641
|
+
defaultValue,
|
|
642
|
+
as = "div",
|
|
643
|
+
className
|
|
644
|
+
}) {
|
|
645
|
+
const isEditMode = useEditModeMessaging();
|
|
646
|
+
const sendEditRequest = useSendEditRequest();
|
|
647
|
+
const { value, isLoading } = useSiteContentQuery(contentKey, {
|
|
648
|
+
defaultValue
|
|
649
|
+
});
|
|
650
|
+
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
651
|
+
const handleClick = (0, import_react7.useCallback)(
|
|
652
|
+
(e) => {
|
|
653
|
+
if (isEditMode) {
|
|
654
|
+
e.preventDefault();
|
|
655
|
+
e.stopPropagation();
|
|
656
|
+
sendEditRequest(contentKey, value, "html", section);
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
[isEditMode, contentKey, value, section, sendEditRequest]
|
|
660
|
+
);
|
|
661
|
+
if (isLoading) {
|
|
662
|
+
return (0, import_react7.createElement)(as, {
|
|
663
|
+
className: cn("animate-pulse bg-muted rounded h-32", className),
|
|
664
|
+
"aria-busy": true
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
const editModeStyles = isEditMode ? cn(
|
|
668
|
+
"cursor-pointer transition-all duration-200",
|
|
669
|
+
"hover:ring-2 hover:ring-blue-500 hover:ring-offset-2",
|
|
670
|
+
"hover:bg-blue-50/50 dark:hover:bg-blue-950/30",
|
|
671
|
+
"relative group"
|
|
672
|
+
) : "";
|
|
673
|
+
const safeHtml = sanitizeHtml(value);
|
|
674
|
+
return (0, import_react7.createElement)(as, {
|
|
675
|
+
className: cn("prose prose-slate dark:prose-invert", className, editModeStyles),
|
|
676
|
+
"data-content-key": contentKey,
|
|
677
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
678
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
679
|
+
title: isEditMode ? "Click to edit" : void 0,
|
|
680
|
+
dangerouslySetInnerHTML: { __html: safeHtml }
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
function EditableImage({
|
|
684
|
+
contentKey,
|
|
685
|
+
defaultValue,
|
|
686
|
+
alt,
|
|
687
|
+
className,
|
|
688
|
+
width,
|
|
689
|
+
height,
|
|
690
|
+
priority = false
|
|
691
|
+
}) {
|
|
692
|
+
const isEditMode = useEditModeMessaging();
|
|
693
|
+
const sendEditRequest = useSendEditRequest();
|
|
694
|
+
const { value: src, isLoading } = useSiteContentQuery(contentKey, {
|
|
695
|
+
defaultValue
|
|
696
|
+
});
|
|
697
|
+
const section = contentKey.includes(".") ? contentKey.split(".")[0] : void 0;
|
|
698
|
+
const handleClick = (0, import_react7.useCallback)(
|
|
699
|
+
(e) => {
|
|
700
|
+
if (isEditMode) {
|
|
701
|
+
e.preventDefault();
|
|
702
|
+
e.stopPropagation();
|
|
703
|
+
sendEditRequest(contentKey, src, "image", section);
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
[isEditMode, contentKey, src, section, sendEditRequest]
|
|
707
|
+
);
|
|
708
|
+
if (isLoading) {
|
|
709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
710
|
+
"div",
|
|
711
|
+
{
|
|
712
|
+
className: cn("animate-pulse bg-muted rounded", className),
|
|
713
|
+
style: { width, height },
|
|
714
|
+
"aria-busy": "true"
|
|
715
|
+
}
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
const editModeStyles = isEditMode ? cn(
|
|
719
|
+
"cursor-pointer transition-all duration-200",
|
|
720
|
+
"hover:ring-2 hover:ring-blue-500 hover:ring-offset-2",
|
|
721
|
+
"hover:opacity-90",
|
|
722
|
+
"relative group"
|
|
723
|
+
) : "";
|
|
724
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cn("relative", isEditMode && "group"), children: [
|
|
725
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
726
|
+
"img",
|
|
727
|
+
{
|
|
728
|
+
src,
|
|
729
|
+
alt,
|
|
730
|
+
className: cn(className, editModeStyles),
|
|
731
|
+
width,
|
|
732
|
+
height,
|
|
733
|
+
loading: priority ? "eager" : "lazy",
|
|
734
|
+
"data-content-key": contentKey,
|
|
735
|
+
"data-editable": isEditMode ? "true" : void 0,
|
|
736
|
+
onClick: isEditMode ? handleClick : void 0,
|
|
737
|
+
title: isEditMode ? "Click to edit image" : void 0
|
|
738
|
+
}
|
|
739
|
+
),
|
|
740
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "absolute top-2 left-2 px-2 py-0.5 bg-blue-600 text-white text-[10px] rounded opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none", children: "Click to edit image" })
|
|
741
|
+
] });
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// src/hooks/useServices.ts
|
|
745
|
+
var import_react8 = require("react");
|
|
415
746
|
function useServices(options = {}) {
|
|
416
747
|
const { client } = useFoxPixelContext();
|
|
417
|
-
const [services, setServices] = (0,
|
|
418
|
-
const [isLoading, setIsLoading] = (0,
|
|
419
|
-
const [error, setError] = (0,
|
|
748
|
+
const [services, setServices] = (0, import_react8.useState)(null);
|
|
749
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
|
|
750
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
420
751
|
const fetchServices = async () => {
|
|
421
752
|
try {
|
|
422
753
|
setIsLoading(true);
|
|
@@ -434,7 +765,7 @@ function useServices(options = {}) {
|
|
|
434
765
|
setIsLoading(false);
|
|
435
766
|
}
|
|
436
767
|
};
|
|
437
|
-
(0,
|
|
768
|
+
(0, import_react8.useEffect)(() => {
|
|
438
769
|
fetchServices();
|
|
439
770
|
}, [options.category, options.active]);
|
|
440
771
|
return {
|
|
@@ -446,11 +777,11 @@ function useServices(options = {}) {
|
|
|
446
777
|
}
|
|
447
778
|
|
|
448
779
|
// src/hooks/useLeadCapture.ts
|
|
449
|
-
var
|
|
780
|
+
var import_react9 = require("react");
|
|
450
781
|
function useLeadCapture() {
|
|
451
782
|
const { client } = useFoxPixelContext();
|
|
452
|
-
const [isLoading, setIsLoading] = (0,
|
|
453
|
-
const [error, setError] = (0,
|
|
783
|
+
const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
|
|
784
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
454
785
|
const captureLead = async (data) => {
|
|
455
786
|
try {
|
|
456
787
|
setIsLoading(true);
|
|
@@ -473,11 +804,11 @@ function useLeadCapture() {
|
|
|
473
804
|
}
|
|
474
805
|
|
|
475
806
|
// src/hooks/useContactCapture.ts
|
|
476
|
-
var
|
|
807
|
+
var import_react10 = require("react");
|
|
477
808
|
function useContactCapture() {
|
|
478
809
|
const { client } = useFoxPixelContext();
|
|
479
|
-
const [isLoading, setIsLoading] = (0,
|
|
480
|
-
const [error, setError] = (0,
|
|
810
|
+
const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
|
|
811
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
481
812
|
const captureContact = async (data) => {
|
|
482
813
|
try {
|
|
483
814
|
setIsLoading(true);
|
|
@@ -499,13 +830,144 @@ function useContactCapture() {
|
|
|
499
830
|
};
|
|
500
831
|
}
|
|
501
832
|
|
|
833
|
+
// src/hooks/useSiteContent.ts
|
|
834
|
+
var import_react11 = require("react");
|
|
835
|
+
function useSiteContent(contentKey, options = {}) {
|
|
836
|
+
const { defaultValue = "", fetchOnMount = true } = options;
|
|
837
|
+
const { client } = useFoxPixelContext();
|
|
838
|
+
const { user, hasPermission } = useAuth();
|
|
839
|
+
const [data, setData] = (0, import_react11.useState)(null);
|
|
840
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(fetchOnMount);
|
|
841
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
842
|
+
const canEdit = user !== null && hasPermission("site:content:update");
|
|
843
|
+
const fetchContent = (0, import_react11.useCallback)(async () => {
|
|
844
|
+
try {
|
|
845
|
+
setIsLoading(true);
|
|
846
|
+
setError(null);
|
|
847
|
+
const content = await client.get(
|
|
848
|
+
`/api/site/content/${encodeURIComponent(contentKey)}`
|
|
849
|
+
);
|
|
850
|
+
setData(content);
|
|
851
|
+
} catch (err) {
|
|
852
|
+
if (err?.status === 404) {
|
|
853
|
+
setData(null);
|
|
854
|
+
} else {
|
|
855
|
+
setError(err);
|
|
856
|
+
}
|
|
857
|
+
} finally {
|
|
858
|
+
setIsLoading(false);
|
|
859
|
+
}
|
|
860
|
+
}, [client, contentKey]);
|
|
861
|
+
const updateContent = (0, import_react11.useCallback)(async (newValue) => {
|
|
862
|
+
try {
|
|
863
|
+
setError(null);
|
|
864
|
+
const updated = await client.put(
|
|
865
|
+
`/api/site/content/${encodeURIComponent(contentKey)}`,
|
|
866
|
+
{ value: newValue }
|
|
867
|
+
);
|
|
868
|
+
setData(updated);
|
|
869
|
+
} catch (err) {
|
|
870
|
+
setError(err);
|
|
871
|
+
throw err;
|
|
872
|
+
}
|
|
873
|
+
}, [client, contentKey]);
|
|
874
|
+
(0, import_react11.useEffect)(() => {
|
|
875
|
+
if (fetchOnMount) {
|
|
876
|
+
fetchContent();
|
|
877
|
+
}
|
|
878
|
+
}, [contentKey, fetchOnMount]);
|
|
879
|
+
const value = data?.value ?? defaultValue;
|
|
880
|
+
return {
|
|
881
|
+
data,
|
|
882
|
+
value,
|
|
883
|
+
isLoading,
|
|
884
|
+
error,
|
|
885
|
+
canEdit,
|
|
886
|
+
update: updateContent,
|
|
887
|
+
refetch: fetchContent
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
function useSiteContents(contentKeys, options = {}) {
|
|
891
|
+
const { defaults = {} } = options;
|
|
892
|
+
const { client } = useFoxPixelContext();
|
|
893
|
+
const [data, setData] = (0, import_react11.useState)({});
|
|
894
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(true);
|
|
895
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
896
|
+
const fetchContents = (0, import_react11.useCallback)(async () => {
|
|
897
|
+
if (contentKeys.length === 0) {
|
|
898
|
+
setData({});
|
|
899
|
+
setIsLoading(false);
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
try {
|
|
903
|
+
setIsLoading(true);
|
|
904
|
+
setError(null);
|
|
905
|
+
const contents = await client.post(
|
|
906
|
+
"/api/site/content/batch",
|
|
907
|
+
contentKeys
|
|
908
|
+
);
|
|
909
|
+
setData(contents);
|
|
910
|
+
} catch (err) {
|
|
911
|
+
setError(err);
|
|
912
|
+
} finally {
|
|
913
|
+
setIsLoading(false);
|
|
914
|
+
}
|
|
915
|
+
}, [client, contentKeys.join(",")]);
|
|
916
|
+
(0, import_react11.useEffect)(() => {
|
|
917
|
+
fetchContents();
|
|
918
|
+
}, [fetchContents]);
|
|
919
|
+
const getValue = (0, import_react11.useCallback)((key, defaultValue) => {
|
|
920
|
+
const content = data[key];
|
|
921
|
+
if (content?.value) {
|
|
922
|
+
return content.value;
|
|
923
|
+
}
|
|
924
|
+
return defaultValue ?? defaults[key] ?? "";
|
|
925
|
+
}, [data, defaults]);
|
|
926
|
+
return {
|
|
927
|
+
data,
|
|
928
|
+
getValue,
|
|
929
|
+
isLoading,
|
|
930
|
+
error,
|
|
931
|
+
refetch: fetchContents
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
function useSiteContentSection(section) {
|
|
935
|
+
const { client } = useFoxPixelContext();
|
|
936
|
+
const [contents, setContents] = (0, import_react11.useState)([]);
|
|
937
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(true);
|
|
938
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
939
|
+
const fetchContents = (0, import_react11.useCallback)(async () => {
|
|
940
|
+
try {
|
|
941
|
+
setIsLoading(true);
|
|
942
|
+
setError(null);
|
|
943
|
+
const data = await client.get(
|
|
944
|
+
`/api/site/content/section/${encodeURIComponent(section)}`
|
|
945
|
+
);
|
|
946
|
+
setContents(data);
|
|
947
|
+
} catch (err) {
|
|
948
|
+
setError(err);
|
|
949
|
+
} finally {
|
|
950
|
+
setIsLoading(false);
|
|
951
|
+
}
|
|
952
|
+
}, [client, section]);
|
|
953
|
+
(0, import_react11.useEffect)(() => {
|
|
954
|
+
fetchContents();
|
|
955
|
+
}, [fetchContents]);
|
|
956
|
+
return {
|
|
957
|
+
contents,
|
|
958
|
+
isLoading,
|
|
959
|
+
error,
|
|
960
|
+
refetch: fetchContents
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
502
964
|
// src/blog/hooks.ts
|
|
503
|
-
var
|
|
965
|
+
var import_react12 = require("react");
|
|
504
966
|
function useBlogPosts(options = {}) {
|
|
505
967
|
const { client } = useFoxPixelContext();
|
|
506
|
-
const [data, setData] = (0,
|
|
507
|
-
const [isLoading, setIsLoading] = (0,
|
|
508
|
-
const [error, setError] = (0,
|
|
968
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
969
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
970
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
509
971
|
const page = options.page ?? 0;
|
|
510
972
|
const limit = options.limit ?? 10;
|
|
511
973
|
const fetchPosts = async () => {
|
|
@@ -525,7 +987,7 @@ function useBlogPosts(options = {}) {
|
|
|
525
987
|
setIsLoading(false);
|
|
526
988
|
}
|
|
527
989
|
};
|
|
528
|
-
(0,
|
|
990
|
+
(0, import_react12.useEffect)(() => {
|
|
529
991
|
fetchPosts();
|
|
530
992
|
}, [page, limit]);
|
|
531
993
|
return {
|
|
@@ -537,9 +999,9 @@ function useBlogPosts(options = {}) {
|
|
|
537
999
|
}
|
|
538
1000
|
function useBlogPost(slug) {
|
|
539
1001
|
const { client } = useFoxPixelContext();
|
|
540
|
-
const [data, setData] = (0,
|
|
541
|
-
const [isLoading, setIsLoading] = (0,
|
|
542
|
-
const [error, setError] = (0,
|
|
1002
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
1003
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(!!slug);
|
|
1004
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
543
1005
|
const fetchPost = async () => {
|
|
544
1006
|
if (!slug) {
|
|
545
1007
|
setData(null);
|
|
@@ -558,7 +1020,7 @@ function useBlogPost(slug) {
|
|
|
558
1020
|
setIsLoading(false);
|
|
559
1021
|
}
|
|
560
1022
|
};
|
|
561
|
-
(0,
|
|
1023
|
+
(0, import_react12.useEffect)(() => {
|
|
562
1024
|
fetchPost();
|
|
563
1025
|
}, [slug]);
|
|
564
1026
|
return {
|
|
@@ -570,9 +1032,9 @@ function useBlogPost(slug) {
|
|
|
570
1032
|
}
|
|
571
1033
|
function useBlogCategories() {
|
|
572
1034
|
const { client } = useFoxPixelContext();
|
|
573
|
-
const [data, setData] = (0,
|
|
574
|
-
const [isLoading, setIsLoading] = (0,
|
|
575
|
-
const [error, setError] = (0,
|
|
1035
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
1036
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
1037
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
576
1038
|
const fetchCategories = async () => {
|
|
577
1039
|
try {
|
|
578
1040
|
setIsLoading(true);
|
|
@@ -586,7 +1048,7 @@ function useBlogCategories() {
|
|
|
586
1048
|
setIsLoading(false);
|
|
587
1049
|
}
|
|
588
1050
|
};
|
|
589
|
-
(0,
|
|
1051
|
+
(0, import_react12.useEffect)(() => {
|
|
590
1052
|
fetchCategories();
|
|
591
1053
|
}, []);
|
|
592
1054
|
return {
|
|
@@ -598,9 +1060,9 @@ function useBlogCategories() {
|
|
|
598
1060
|
}
|
|
599
1061
|
function useBlogTags() {
|
|
600
1062
|
const { client } = useFoxPixelContext();
|
|
601
|
-
const [data, setData] = (0,
|
|
602
|
-
const [isLoading, setIsLoading] = (0,
|
|
603
|
-
const [error, setError] = (0,
|
|
1063
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
1064
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
1065
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
604
1066
|
const fetchTags = async () => {
|
|
605
1067
|
try {
|
|
606
1068
|
setIsLoading(true);
|
|
@@ -614,7 +1076,7 @@ function useBlogTags() {
|
|
|
614
1076
|
setIsLoading(false);
|
|
615
1077
|
}
|
|
616
1078
|
};
|
|
617
|
-
(0,
|
|
1079
|
+
(0, import_react12.useEffect)(() => {
|
|
618
1080
|
fetchTags();
|
|
619
1081
|
}, []);
|
|
620
1082
|
return {
|
|
@@ -626,9 +1088,9 @@ function useBlogTags() {
|
|
|
626
1088
|
}
|
|
627
1089
|
function useBlogComments(slug) {
|
|
628
1090
|
const { client } = useFoxPixelContext();
|
|
629
|
-
const [data, setData] = (0,
|
|
630
|
-
const [isLoading, setIsLoading] = (0,
|
|
631
|
-
const [error, setError] = (0,
|
|
1091
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
1092
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(!!slug);
|
|
1093
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
632
1094
|
const fetchComments = async () => {
|
|
633
1095
|
if (!slug) {
|
|
634
1096
|
setData(null);
|
|
@@ -649,7 +1111,7 @@ function useBlogComments(slug) {
|
|
|
649
1111
|
setIsLoading(false);
|
|
650
1112
|
}
|
|
651
1113
|
};
|
|
652
|
-
(0,
|
|
1114
|
+
(0, import_react12.useEffect)(() => {
|
|
653
1115
|
fetchComments();
|
|
654
1116
|
}, [slug]);
|
|
655
1117
|
return {
|
|
@@ -661,8 +1123,8 @@ function useBlogComments(slug) {
|
|
|
661
1123
|
}
|
|
662
1124
|
function useBlogCommentSubmit(slug) {
|
|
663
1125
|
const { client } = useFoxPixelContext();
|
|
664
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
665
|
-
const [error, setError] = (0,
|
|
1126
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react12.useState)(false);
|
|
1127
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
666
1128
|
const submit = async (payload) => {
|
|
667
1129
|
if (!slug) return null;
|
|
668
1130
|
try {
|
|
@@ -690,9 +1152,9 @@ function useBlogCommentSubmit(slug) {
|
|
|
690
1152
|
}
|
|
691
1153
|
function useBlogFeaturedPosts(limit = 6) {
|
|
692
1154
|
const { client } = useFoxPixelContext();
|
|
693
|
-
const [data, setData] = (0,
|
|
694
|
-
const [isLoading, setIsLoading] = (0,
|
|
695
|
-
const [error, setError] = (0,
|
|
1155
|
+
const [data, setData] = (0, import_react12.useState)(null);
|
|
1156
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
1157
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
696
1158
|
const fetchFeatured = async () => {
|
|
697
1159
|
try {
|
|
698
1160
|
setIsLoading(true);
|
|
@@ -710,7 +1172,7 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
710
1172
|
setIsLoading(false);
|
|
711
1173
|
}
|
|
712
1174
|
};
|
|
713
|
-
(0,
|
|
1175
|
+
(0, import_react12.useEffect)(() => {
|
|
714
1176
|
fetchFeatured();
|
|
715
1177
|
}, [limit]);
|
|
716
1178
|
return {
|
|
@@ -722,9 +1184,9 @@ function useBlogFeaturedPosts(limit = 6) {
|
|
|
722
1184
|
}
|
|
723
1185
|
function useNewsletterSubscribe() {
|
|
724
1186
|
const { client } = useFoxPixelContext();
|
|
725
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
726
|
-
const [error, setError] = (0,
|
|
727
|
-
const [success, setSuccess] = (0,
|
|
1187
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react12.useState)(false);
|
|
1188
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1189
|
+
const [success, setSuccess] = (0, import_react12.useState)(false);
|
|
728
1190
|
const subscribe = async (payload) => {
|
|
729
1191
|
try {
|
|
730
1192
|
setIsSubmitting(true);
|
|
@@ -757,9 +1219,9 @@ function useNewsletterSubscribe() {
|
|
|
757
1219
|
}
|
|
758
1220
|
function useNewsletterUnsubscribe() {
|
|
759
1221
|
const { client } = useFoxPixelContext();
|
|
760
|
-
const [isSubmitting, setIsSubmitting] = (0,
|
|
761
|
-
const [error, setError] = (0,
|
|
762
|
-
const [success, setSuccess] = (0,
|
|
1222
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react12.useState)(false);
|
|
1223
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1224
|
+
const [success, setSuccess] = (0, import_react12.useState)(false);
|
|
763
1225
|
const unsubscribe = async (email) => {
|
|
764
1226
|
try {
|
|
765
1227
|
setIsSubmitting(true);
|
|
@@ -777,8 +1239,26 @@ function useNewsletterUnsubscribe() {
|
|
|
777
1239
|
setIsSubmitting(false);
|
|
778
1240
|
}
|
|
779
1241
|
};
|
|
1242
|
+
const unsubscribeByToken = async (token) => {
|
|
1243
|
+
try {
|
|
1244
|
+
setIsSubmitting(true);
|
|
1245
|
+
setError(null);
|
|
1246
|
+
setSuccess(false);
|
|
1247
|
+
await client.get("/api/v1/blog/newsletter/unsubscribe", {
|
|
1248
|
+
params: { token }
|
|
1249
|
+
});
|
|
1250
|
+
setSuccess(true);
|
|
1251
|
+
return true;
|
|
1252
|
+
} catch (err) {
|
|
1253
|
+
setError(err);
|
|
1254
|
+
return false;
|
|
1255
|
+
} finally {
|
|
1256
|
+
setIsSubmitting(false);
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
780
1259
|
return {
|
|
781
1260
|
unsubscribe,
|
|
1261
|
+
unsubscribeByToken,
|
|
782
1262
|
isSubmitting,
|
|
783
1263
|
error,
|
|
784
1264
|
success
|
|
@@ -786,15 +1266,15 @@ function useNewsletterUnsubscribe() {
|
|
|
786
1266
|
}
|
|
787
1267
|
|
|
788
1268
|
// src/blog/admin-hooks.ts
|
|
789
|
-
var
|
|
1269
|
+
var import_react13 = require("react");
|
|
790
1270
|
function useAdminBlogPosts(options = {}) {
|
|
791
1271
|
const { client } = useFoxPixelContext();
|
|
792
|
-
const [data, setData] = (0,
|
|
793
|
-
const [isLoading, setIsLoading] = (0,
|
|
794
|
-
const [error, setError] = (0,
|
|
1272
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1273
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1274
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
795
1275
|
const page = options.page ?? 0;
|
|
796
1276
|
const size = options.size ?? 20;
|
|
797
|
-
const fetchPosts = (0,
|
|
1277
|
+
const fetchPosts = (0, import_react13.useCallback)(async () => {
|
|
798
1278
|
try {
|
|
799
1279
|
setIsLoading(true);
|
|
800
1280
|
setError(null);
|
|
@@ -809,17 +1289,17 @@ function useAdminBlogPosts(options = {}) {
|
|
|
809
1289
|
setIsLoading(false);
|
|
810
1290
|
}
|
|
811
1291
|
}, [client, page, size]);
|
|
812
|
-
(0,
|
|
1292
|
+
(0, import_react13.useEffect)(() => {
|
|
813
1293
|
fetchPosts();
|
|
814
1294
|
}, [fetchPosts]);
|
|
815
1295
|
return { data, isLoading, error, refetch: fetchPosts };
|
|
816
1296
|
}
|
|
817
1297
|
function useAdminBlogPost(id) {
|
|
818
1298
|
const { client } = useFoxPixelContext();
|
|
819
|
-
const [data, setData] = (0,
|
|
820
|
-
const [isLoading, setIsLoading] = (0,
|
|
821
|
-
const [error, setError] = (0,
|
|
822
|
-
const fetchPost = (0,
|
|
1299
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1300
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(!!id);
|
|
1301
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1302
|
+
const fetchPost = (0, import_react13.useCallback)(async () => {
|
|
823
1303
|
if (!id) {
|
|
824
1304
|
setData(null);
|
|
825
1305
|
setIsLoading(false);
|
|
@@ -836,15 +1316,15 @@ function useAdminBlogPost(id) {
|
|
|
836
1316
|
setIsLoading(false);
|
|
837
1317
|
}
|
|
838
1318
|
}, [client, id]);
|
|
839
|
-
(0,
|
|
1319
|
+
(0, import_react13.useEffect)(() => {
|
|
840
1320
|
fetchPost();
|
|
841
1321
|
}, [fetchPost]);
|
|
842
1322
|
return { data, isLoading, error, refetch: fetchPost };
|
|
843
1323
|
}
|
|
844
1324
|
function useAdminBlogPostMutations() {
|
|
845
1325
|
const { client } = useFoxPixelContext();
|
|
846
|
-
const [isLoading, setIsLoading] = (0,
|
|
847
|
-
const [error, setError] = (0,
|
|
1326
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
|
|
1327
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
848
1328
|
const create = async (payload) => {
|
|
849
1329
|
try {
|
|
850
1330
|
setIsLoading(true);
|
|
@@ -888,10 +1368,10 @@ function useAdminBlogPostMutations() {
|
|
|
888
1368
|
}
|
|
889
1369
|
function useAdminBlogCategories() {
|
|
890
1370
|
const { client } = useFoxPixelContext();
|
|
891
|
-
const [data, setData] = (0,
|
|
892
|
-
const [isLoading, setIsLoading] = (0,
|
|
893
|
-
const [error, setError] = (0,
|
|
894
|
-
const fetchCategories = (0,
|
|
1371
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1372
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1373
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1374
|
+
const fetchCategories = (0, import_react13.useCallback)(async () => {
|
|
895
1375
|
try {
|
|
896
1376
|
setIsLoading(true);
|
|
897
1377
|
setError(null);
|
|
@@ -903,7 +1383,7 @@ function useAdminBlogCategories() {
|
|
|
903
1383
|
setIsLoading(false);
|
|
904
1384
|
}
|
|
905
1385
|
}, [client]);
|
|
906
|
-
(0,
|
|
1386
|
+
(0, import_react13.useEffect)(() => {
|
|
907
1387
|
fetchCategories();
|
|
908
1388
|
}, [fetchCategories]);
|
|
909
1389
|
const create = async (payload) => {
|
|
@@ -940,10 +1420,10 @@ function useAdminBlogCategories() {
|
|
|
940
1420
|
}
|
|
941
1421
|
function useAdminBlogTags() {
|
|
942
1422
|
const { client } = useFoxPixelContext();
|
|
943
|
-
const [data, setData] = (0,
|
|
944
|
-
const [isLoading, setIsLoading] = (0,
|
|
945
|
-
const [error, setError] = (0,
|
|
946
|
-
const fetchTags = (0,
|
|
1423
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1424
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1425
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1426
|
+
const fetchTags = (0, import_react13.useCallback)(async () => {
|
|
947
1427
|
try {
|
|
948
1428
|
setIsLoading(true);
|
|
949
1429
|
setError(null);
|
|
@@ -955,7 +1435,7 @@ function useAdminBlogTags() {
|
|
|
955
1435
|
setIsLoading(false);
|
|
956
1436
|
}
|
|
957
1437
|
}, [client]);
|
|
958
|
-
(0,
|
|
1438
|
+
(0, import_react13.useEffect)(() => {
|
|
959
1439
|
fetchTags();
|
|
960
1440
|
}, [fetchTags]);
|
|
961
1441
|
const create = async (payload) => {
|
|
@@ -992,11 +1472,11 @@ function useAdminBlogTags() {
|
|
|
992
1472
|
}
|
|
993
1473
|
function useAdminBlogComments(options = {}) {
|
|
994
1474
|
const { client } = useFoxPixelContext();
|
|
995
|
-
const [data, setData] = (0,
|
|
996
|
-
const [isLoading, setIsLoading] = (0,
|
|
997
|
-
const [error, setError] = (0,
|
|
1475
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1476
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1477
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
998
1478
|
const { status, postId, page = 0, size = 20 } = options;
|
|
999
|
-
const fetchComments = (0,
|
|
1479
|
+
const fetchComments = (0, import_react13.useCallback)(async () => {
|
|
1000
1480
|
try {
|
|
1001
1481
|
setIsLoading(true);
|
|
1002
1482
|
setError(null);
|
|
@@ -1013,7 +1493,7 @@ function useAdminBlogComments(options = {}) {
|
|
|
1013
1493
|
setIsLoading(false);
|
|
1014
1494
|
}
|
|
1015
1495
|
}, [client, status, postId, page, size]);
|
|
1016
|
-
(0,
|
|
1496
|
+
(0, import_react13.useEffect)(() => {
|
|
1017
1497
|
fetchComments();
|
|
1018
1498
|
}, [fetchComments]);
|
|
1019
1499
|
const updateStatus = async (id, newStatus) => {
|
|
@@ -1040,11 +1520,11 @@ function useAdminBlogComments(options = {}) {
|
|
|
1040
1520
|
}
|
|
1041
1521
|
function useAdminNewsletterSubscribers(options = {}) {
|
|
1042
1522
|
const { client } = useFoxPixelContext();
|
|
1043
|
-
const [data, setData] = (0,
|
|
1044
|
-
const [isLoading, setIsLoading] = (0,
|
|
1045
|
-
const [error, setError] = (0,
|
|
1523
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1524
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1525
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1046
1526
|
const { status, page = 0, size = 20 } = options;
|
|
1047
|
-
const fetchSubscribers = (0,
|
|
1527
|
+
const fetchSubscribers = (0, import_react13.useCallback)(async () => {
|
|
1048
1528
|
try {
|
|
1049
1529
|
setIsLoading(true);
|
|
1050
1530
|
setError(null);
|
|
@@ -1060,7 +1540,7 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1060
1540
|
setIsLoading(false);
|
|
1061
1541
|
}
|
|
1062
1542
|
}, [client, status, page, size]);
|
|
1063
|
-
(0,
|
|
1543
|
+
(0, import_react13.useEffect)(() => {
|
|
1064
1544
|
fetchSubscribers();
|
|
1065
1545
|
}, [fetchSubscribers]);
|
|
1066
1546
|
const remove = async (id) => {
|
|
@@ -1077,10 +1557,10 @@ function useAdminNewsletterSubscribers(options = {}) {
|
|
|
1077
1557
|
}
|
|
1078
1558
|
function useAdminNewsletterStats() {
|
|
1079
1559
|
const { client } = useFoxPixelContext();
|
|
1080
|
-
const [data, setData] = (0,
|
|
1081
|
-
const [isLoading, setIsLoading] = (0,
|
|
1082
|
-
const [error, setError] = (0,
|
|
1083
|
-
const fetchStats = (0,
|
|
1560
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1561
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1562
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1563
|
+
const fetchStats = (0, import_react13.useCallback)(async () => {
|
|
1084
1564
|
try {
|
|
1085
1565
|
setIsLoading(true);
|
|
1086
1566
|
setError(null);
|
|
@@ -1092,17 +1572,17 @@ function useAdminNewsletterStats() {
|
|
|
1092
1572
|
setIsLoading(false);
|
|
1093
1573
|
}
|
|
1094
1574
|
}, [client]);
|
|
1095
|
-
(0,
|
|
1575
|
+
(0, import_react13.useEffect)(() => {
|
|
1096
1576
|
fetchStats();
|
|
1097
1577
|
}, [fetchStats]);
|
|
1098
1578
|
return { data, isLoading, error, refetch: fetchStats };
|
|
1099
1579
|
}
|
|
1100
1580
|
function useAdminBlogSettings() {
|
|
1101
1581
|
const { client } = useFoxPixelContext();
|
|
1102
|
-
const [data, setData] = (0,
|
|
1103
|
-
const [isLoading, setIsLoading] = (0,
|
|
1104
|
-
const [error, setError] = (0,
|
|
1105
|
-
const fetchSettings = (0,
|
|
1582
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1583
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1584
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1585
|
+
const fetchSettings = (0, import_react13.useCallback)(async () => {
|
|
1106
1586
|
try {
|
|
1107
1587
|
setIsLoading(true);
|
|
1108
1588
|
setError(null);
|
|
@@ -1114,7 +1594,7 @@ function useAdminBlogSettings() {
|
|
|
1114
1594
|
setIsLoading(false);
|
|
1115
1595
|
}
|
|
1116
1596
|
}, [client]);
|
|
1117
|
-
(0,
|
|
1597
|
+
(0, import_react13.useEffect)(() => {
|
|
1118
1598
|
fetchSettings();
|
|
1119
1599
|
}, [fetchSettings]);
|
|
1120
1600
|
const update = async (settings) => {
|
|
@@ -1131,10 +1611,10 @@ function useAdminBlogSettings() {
|
|
|
1131
1611
|
}
|
|
1132
1612
|
function useAdminBlogAnalytics() {
|
|
1133
1613
|
const { client } = useFoxPixelContext();
|
|
1134
|
-
const [data, setData] = (0,
|
|
1135
|
-
const [isLoading, setIsLoading] = (0,
|
|
1136
|
-
const [error, setError] = (0,
|
|
1137
|
-
const fetchAnalytics = (0,
|
|
1614
|
+
const [data, setData] = (0, import_react13.useState)(null);
|
|
1615
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(true);
|
|
1616
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1617
|
+
const fetchAnalytics = (0, import_react13.useCallback)(async () => {
|
|
1138
1618
|
try {
|
|
1139
1619
|
setIsLoading(true);
|
|
1140
1620
|
setError(null);
|
|
@@ -1146,7 +1626,7 @@ function useAdminBlogAnalytics() {
|
|
|
1146
1626
|
setIsLoading(false);
|
|
1147
1627
|
}
|
|
1148
1628
|
}, [client]);
|
|
1149
|
-
(0,
|
|
1629
|
+
(0, import_react13.useEffect)(() => {
|
|
1150
1630
|
fetchAnalytics();
|
|
1151
1631
|
}, [fetchAnalytics]);
|
|
1152
1632
|
return { data, isLoading, error, refetch: fetchAnalytics };
|
|
@@ -1186,10 +1666,14 @@ function getBlogPostSchemaLd(post, options) {
|
|
|
1186
1666
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1187
1667
|
0 && (module.exports = {
|
|
1188
1668
|
AuthProvider,
|
|
1669
|
+
Editable,
|
|
1670
|
+
EditableHTML,
|
|
1671
|
+
EditableImage,
|
|
1189
1672
|
FoxPixelHttpClient,
|
|
1190
1673
|
FoxPixelProvider,
|
|
1191
1674
|
GuestOnlyRoute,
|
|
1192
1675
|
ProtectedRoute,
|
|
1676
|
+
SITE_CONTENT_QUERY_KEY,
|
|
1193
1677
|
getBlogPostSchemaLd,
|
|
1194
1678
|
useAdminBlogAnalytics,
|
|
1195
1679
|
useAdminBlogCategories,
|
|
@@ -1210,11 +1694,18 @@ function getBlogPostSchemaLd(post, options) {
|
|
|
1210
1694
|
useBlogPosts,
|
|
1211
1695
|
useBlogTags,
|
|
1212
1696
|
useContactCapture,
|
|
1697
|
+
useEditMode,
|
|
1698
|
+
useEditModeMessaging,
|
|
1213
1699
|
useFoxPixelContext,
|
|
1214
1700
|
useLeadCapture,
|
|
1215
1701
|
useNewsletterSubscribe,
|
|
1216
1702
|
useNewsletterUnsubscribe,
|
|
1703
|
+
useSendEditRequest,
|
|
1217
1704
|
useServices,
|
|
1705
|
+
useSiteContent,
|
|
1706
|
+
useSiteContentQuery,
|
|
1707
|
+
useSiteContentSection,
|
|
1708
|
+
useSiteContents,
|
|
1218
1709
|
withAuth
|
|
1219
1710
|
});
|
|
1220
1711
|
//# sourceMappingURL=index.js.map
|