@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, ComponentType } from 'react';
2
+ import React, { ReactNode, ComponentType } from 'react';
3
3
  import { AxiosInstance, AxiosRequestConfig } from 'axios';
4
4
 
5
5
  /**
@@ -188,6 +188,8 @@ interface AuthContextValue {
188
188
  phone?: string;
189
189
  }) => Promise<void>;
190
190
  refetch: () => Promise<void>;
191
+ /** Stub: returns true when user is logged in and permission is site:content:update. */
192
+ hasPermission: (permission: string) => boolean;
191
193
  }
192
194
  interface AuthProviderProps {
193
195
  children: ReactNode;
@@ -261,6 +263,54 @@ interface WithAuthOptions {
261
263
  }
262
264
  declare function withAuth<P extends object>(Component: ComponentType<P>, options?: WithAuthOptions): (props: P) => string | number | true | Iterable<ReactNode> | react_jsx_runtime.JSX.Element | null;
263
265
 
266
+ interface EditableProps {
267
+ contentKey: string;
268
+ defaultValue: string;
269
+ as?: keyof JSX.IntrinsicElements;
270
+ multiline?: boolean;
271
+ className?: string;
272
+ }
273
+ declare function Editable({ contentKey, defaultValue, as, multiline, className, }: EditableProps): React.ReactElement<{
274
+ className: string;
275
+ 'aria-busy': boolean;
276
+ 'aria-label': string;
277
+ }, string | React.JSXElementConstructor<any>> | React.DOMElement<{
278
+ className: string;
279
+ 'data-content-key': string;
280
+ 'data-editable': string | undefined;
281
+ onClick: ((e: React.MouseEvent) => void) | undefined;
282
+ title: string | undefined;
283
+ }, Element>;
284
+ /**
285
+ * Renders rich HTML content from the CMS. Content is sanitized before rendering.
286
+ */
287
+ declare function EditableHTML({ contentKey, defaultValue, as, className, }: Omit<EditableProps, 'multiline'>): React.ReactElement<{
288
+ className: string;
289
+ 'aria-busy': boolean;
290
+ }, string | React.JSXElementConstructor<any>> | React.DOMElement<{
291
+ className: string;
292
+ 'data-content-key': string;
293
+ 'data-editable': string | undefined;
294
+ onClick: ((e: React.MouseEvent) => void) | undefined;
295
+ title: string | undefined;
296
+ dangerouslySetInnerHTML: {
297
+ __html: string;
298
+ };
299
+ }, Element>;
300
+ interface EditableImageProps {
301
+ contentKey: string;
302
+ defaultValue: string;
303
+ alt: string;
304
+ className?: string;
305
+ width?: number;
306
+ height?: number;
307
+ priority?: boolean;
308
+ }
309
+ /**
310
+ * Renders an image from a CMS-managed URL. Uses native img (no Next.js Image in SDK).
311
+ */
312
+ declare function EditableImage({ contentKey, defaultValue, alt, className, width, height, priority, }: EditableImageProps): react_jsx_runtime.JSX.Element;
313
+
264
314
  /**
265
315
  * Hook to fetch and manage services (Projects module)
266
316
  */
@@ -405,6 +455,237 @@ interface UseContactCaptureReturn {
405
455
  */
406
456
  declare function useContactCapture(): UseContactCaptureReturn;
407
457
 
458
+ /**
459
+ * Hook for managing editable site content (CMS Visual)
460
+ *
461
+ * Allows non-developers to edit text content directly on the site.
462
+ */
463
+
464
+ interface SiteContent {
465
+ id: string;
466
+ contentKey: string;
467
+ value: string | null;
468
+ contentType: string;
469
+ defaultValue: string | null;
470
+ description: string | null;
471
+ section: string | null;
472
+ sortOrder: number;
473
+ isActive: boolean;
474
+ updatedAt: string | null;
475
+ }
476
+ interface UseSiteContentOptions {
477
+ /**
478
+ * Default value to use if content is not found
479
+ */
480
+ defaultValue?: string;
481
+ /**
482
+ * Whether to fetch on mount (default: true)
483
+ */
484
+ fetchOnMount?: boolean;
485
+ }
486
+ interface UseSiteContentReturn {
487
+ /**
488
+ * The content object (null if not found or loading)
489
+ */
490
+ data: SiteContent | null;
491
+ /**
492
+ * The content value (or defaultValue if not found)
493
+ */
494
+ value: string;
495
+ /**
496
+ * Whether content is being loaded
497
+ */
498
+ isLoading: boolean;
499
+ /**
500
+ * Error if request failed
501
+ */
502
+ error: ApiError$1 | null;
503
+ /**
504
+ * Whether the current user can edit this content
505
+ */
506
+ canEdit: boolean;
507
+ /**
508
+ * Update the content value
509
+ */
510
+ update: (newValue: string) => Promise<void>;
511
+ /**
512
+ * Refetch the content
513
+ */
514
+ refetch: () => Promise<void>;
515
+ }
516
+ /**
517
+ * Hook for managing a single site content key.
518
+ *
519
+ * @example
520
+ * ```tsx
521
+ * function HeroSection() {
522
+ * const { value, canEdit, update } = useSiteContent('hero.title', {
523
+ * defaultValue: 'Welcome to our site'
524
+ * });
525
+ *
526
+ * const [isEditing, setIsEditing] = useState(false);
527
+ * const [editValue, setEditValue] = useState(value);
528
+ *
529
+ * const handleSave = async () => {
530
+ * await update(editValue);
531
+ * setIsEditing(false);
532
+ * };
533
+ *
534
+ * if (canEdit && isEditing) {
535
+ * return (
536
+ * <input
537
+ * value={editValue}
538
+ * onChange={(e) => setEditValue(e.target.value)}
539
+ * onBlur={handleSave}
540
+ * />
541
+ * );
542
+ * }
543
+ *
544
+ * return (
545
+ * <h1 onClick={() => canEdit && setIsEditing(true)}>
546
+ * {value}
547
+ * </h1>
548
+ * );
549
+ * }
550
+ * ```
551
+ */
552
+ declare function useSiteContent(contentKey: string, options?: UseSiteContentOptions): UseSiteContentReturn;
553
+ interface UseSiteContentsOptions {
554
+ /**
555
+ * Default values map
556
+ */
557
+ defaults?: Record<string, string>;
558
+ }
559
+ interface UseSiteContentsReturn {
560
+ /**
561
+ * Map of content key to content object
562
+ */
563
+ data: Record<string, SiteContent>;
564
+ /**
565
+ * Get value by key (with default fallback)
566
+ */
567
+ getValue: (key: string, defaultValue?: string) => string;
568
+ /**
569
+ * Whether contents are being loaded
570
+ */
571
+ isLoading: boolean;
572
+ /**
573
+ * Error if request failed
574
+ */
575
+ error: ApiError$1 | null;
576
+ /**
577
+ * Refetch all contents
578
+ */
579
+ refetch: () => Promise<void>;
580
+ }
581
+ /**
582
+ * Hook for fetching multiple site content keys at once.
583
+ * More efficient than calling useSiteContent multiple times.
584
+ *
585
+ * @example
586
+ * ```tsx
587
+ * function Footer() {
588
+ * const { getValue, isLoading } = useSiteContents(
589
+ * ['footer.copyright', 'footer.address', 'footer.phone'],
590
+ * { defaults: { 'footer.copyright': '© 2024' } }
591
+ * );
592
+ *
593
+ * if (isLoading) return null;
594
+ *
595
+ * return (
596
+ * <footer>
597
+ * <p>{getValue('footer.copyright')}</p>
598
+ * <p>{getValue('footer.address')}</p>
599
+ * <p>{getValue('footer.phone')}</p>
600
+ * </footer>
601
+ * );
602
+ * }
603
+ * ```
604
+ */
605
+ declare function useSiteContents(contentKeys: string[], options?: UseSiteContentsOptions): UseSiteContentsReturn;
606
+ interface UseSiteContentSectionReturn {
607
+ /**
608
+ * List of contents in the section
609
+ */
610
+ contents: SiteContent[];
611
+ /**
612
+ * Whether contents are being loaded
613
+ */
614
+ isLoading: boolean;
615
+ /**
616
+ * Error if request failed
617
+ */
618
+ error: ApiError$1 | null;
619
+ /**
620
+ * Refetch section contents
621
+ */
622
+ refetch: () => Promise<void>;
623
+ }
624
+ /**
625
+ * Hook for fetching all content in a section.
626
+ *
627
+ * @example
628
+ * ```tsx
629
+ * function HeroSection() {
630
+ * const { contents, isLoading } = useSiteContentSection('hero');
631
+ *
632
+ * if (isLoading) return <div>Loading...</div>;
633
+ *
634
+ * return (
635
+ * <div>
636
+ * {contents.map(content => (
637
+ * <div key={content.contentKey}>{content.value}</div>
638
+ * ))}
639
+ * </div>
640
+ * );
641
+ * }
642
+ * ```
643
+ */
644
+ declare function useSiteContentSection(section: string): UseSiteContentSectionReturn;
645
+
646
+ /**
647
+ * Edit-mode hooks for CMS Visual (iframe communication with Tenant Admin).
648
+ * When edit-mode=true is in the URL, the site enters edit mode and communicates
649
+ * with the parent iframe via postMessage.
650
+ */
651
+ /** Query key used for site content; must match useSiteContentQuery. */
652
+ declare const SITE_CONTENT_QUERY_KEY: "siteContent";
653
+ /**
654
+ * Returns true when the page is in edit mode (URL has edit-mode=true).
655
+ * Used to show edit affordances and enable postMessage communication.
656
+ */
657
+ declare function useEditMode(): boolean;
658
+ /**
659
+ * Sets up edit-mode messaging: notifies parent when ready and listens for
660
+ * FOXPIXEL_CONTENT_UPDATED to invalidate the corresponding site content query.
661
+ * App must be wrapped in QueryClientProvider when using edit mode.
662
+ */
663
+ declare function useEditModeMessaging(): boolean;
664
+ /**
665
+ * Returns a callback to send an edit request to the parent iframe.
666
+ * Only has effect when in edit mode.
667
+ */
668
+ declare function useSendEditRequest(): (contentKey: string, currentValue: string, contentType?: string, section?: string, description?: string) => void;
669
+
670
+ /**
671
+ * React Query-based hook for site content used by Editable components.
672
+ * Uses queryKey ['siteContent', key] so that useEditModeMessaging can invalidate
673
+ * on FOXPIXEL_CONTENT_UPDATED. Requires QueryClientProvider.
674
+ */
675
+ interface UseSiteContentQueryOptions {
676
+ defaultValue: string;
677
+ }
678
+ interface UseSiteContentQueryReturn {
679
+ value: string;
680
+ isLoading: boolean;
681
+ contentType: string;
682
+ }
683
+ /**
684
+ * Fetches a single site content by key using React Query. Used by Editable, EditableHTML, EditableImage.
685
+ * Invalidation is triggered by useEditModeMessaging when the parent sends FOXPIXEL_CONTENT_UPDATED.
686
+ */
687
+ declare function useSiteContentQuery(contentKey: string, options: UseSiteContentQueryOptions): UseSiteContentQueryReturn;
688
+
408
689
  /**
409
690
  * Blog module types for FoxPixel SDK
410
691
  * Aligned with backend BlogPostResponse, BlogCategoryResponse, BlogTagResponse
@@ -675,6 +956,8 @@ interface UseNewsletterSubscribeReturn {
675
956
  declare function useNewsletterSubscribe(): UseNewsletterSubscribeReturn;
676
957
  interface UseNewsletterUnsubscribeReturn {
677
958
  unsubscribe: (email: string) => Promise<boolean>;
959
+ /** Cancelar inscrição pelo token (link no email de confirmação). */
960
+ unsubscribeByToken: (token: string) => Promise<boolean>;
678
961
  isSubmitting: boolean;
679
962
  error: ApiError$1 | null;
680
963
  success: boolean;
@@ -861,4 +1144,4 @@ interface BlogPostSchemaLdOptions {
861
1144
  */
862
1145
  declare function getBlogPostSchemaLd(post: BlogPost, options: BlogPostSchemaLdOptions): Record<string, unknown>;
863
1146
 
864
- export { type ApiError$1 as ApiError, AuthProvider, type BlogAnalyticsSummary, type BlogAuthor, type BlogCategory, type BlogComment, type BlogCommentAdmin, type BlogCommentPage, type BlogPost, type BlogPostPage, type BlogPostSchemaLdOptions, type BlogPostStatus, type BlogSettings, type BlogTag, type CreateBlogCommentPayload, type CreateBlogPostPayload, type CreateCategoryPayload, type CreateLeadRequest, type CreateTagPayload, type EndUser, type EndUserLoginRequest, type FoxPixelConfig, FoxPixelHttpClient, FoxPixelProvider, GuestOnlyRoute, type Lead, type NewsletterFrequency, type NewsletterStats, type NewsletterStatus, type NewsletterSubscriber, type NewsletterSubscriberPage, type PostAnalyticsRow, ProtectedRoute, type Service, type ServiceCatalogResponse, type SubscribeNewsletterPayload, type UpdateBlogPostPayload, type UseAdminBlogAnalyticsReturn, type UseAdminBlogCategoriesReturn, type UseAdminBlogCommentsOptions, type UseAdminBlogCommentsReturn, type UseAdminBlogPostMutationsReturn, type UseAdminBlogPostReturn, type UseAdminBlogPostsOptions, type UseAdminBlogPostsReturn, type UseAdminBlogSettingsReturn, type UseAdminBlogTagsReturn, type UseAdminNewsletterStatsReturn, type UseAdminNewsletterSubscribersOptions, type UseAdminNewsletterSubscribersReturn, type UseBlogCategoriesReturn, type UseBlogCommentSubmitReturn, type UseBlogCommentsReturn, type UseBlogFeaturedPostsReturn, type UseBlogPostReturn, type UseBlogPostsOptions, type UseBlogPostsReturn, type UseBlogTagsReturn, type UseNewsletterSubscribeReturn, type UseNewsletterUnsubscribeReturn, getBlogPostSchemaLd, useAdminBlogAnalytics, useAdminBlogCategories, useAdminBlogComments, useAdminBlogPost, useAdminBlogPostMutations, useAdminBlogPosts, useAdminBlogSettings, useAdminBlogTags, useAdminNewsletterStats, useAdminNewsletterSubscribers, useAuth, useBlogCategories, useBlogCommentSubmit, useBlogComments, useBlogFeaturedPosts, useBlogPost, useBlogPosts, useBlogTags, useContactCapture, useFoxPixelContext, useLeadCapture, useNewsletterSubscribe, useNewsletterUnsubscribe, useServices, withAuth };
1147
+ export { type ApiError$1 as ApiError, AuthProvider, type BlogAnalyticsSummary, type BlogAuthor, type BlogCategory, type BlogComment, type BlogCommentAdmin, type BlogCommentPage, type BlogPost, type BlogPostPage, type BlogPostSchemaLdOptions, type BlogPostStatus, type BlogSettings, type BlogTag, type CreateBlogCommentPayload, type CreateBlogPostPayload, type CreateCategoryPayload, type CreateLeadRequest, type CreateTagPayload, Editable, EditableHTML, EditableImage, type EditableImageProps, type EditableProps, type EndUser, type EndUserLoginRequest, type FoxPixelConfig, FoxPixelHttpClient, FoxPixelProvider, GuestOnlyRoute, type Lead, type NewsletterFrequency, type NewsletterStats, type NewsletterStatus, type NewsletterSubscriber, type NewsletterSubscriberPage, type PostAnalyticsRow, ProtectedRoute, SITE_CONTENT_QUERY_KEY, type Service, type ServiceCatalogResponse, type SiteContent, type SubscribeNewsletterPayload, type UpdateBlogPostPayload, type UseAdminBlogAnalyticsReturn, type UseAdminBlogCategoriesReturn, type UseAdminBlogCommentsOptions, type UseAdminBlogCommentsReturn, type UseAdminBlogPostMutationsReturn, type UseAdminBlogPostReturn, type UseAdminBlogPostsOptions, type UseAdminBlogPostsReturn, type UseAdminBlogSettingsReturn, type UseAdminBlogTagsReturn, type UseAdminNewsletterStatsReturn, type UseAdminNewsletterSubscribersOptions, type UseAdminNewsletterSubscribersReturn, type UseBlogCategoriesReturn, type UseBlogCommentSubmitReturn, type UseBlogCommentsReturn, type UseBlogFeaturedPostsReturn, type UseBlogPostReturn, type UseBlogPostsOptions, type UseBlogPostsReturn, type UseBlogTagsReturn, type UseNewsletterSubscribeReturn, type UseNewsletterUnsubscribeReturn, type UseSiteContentOptions, type UseSiteContentQueryOptions, type UseSiteContentQueryReturn, type UseSiteContentReturn, type UseSiteContentSectionReturn, type UseSiteContentsOptions, type UseSiteContentsReturn, getBlogPostSchemaLd, useAdminBlogAnalytics, useAdminBlogCategories, useAdminBlogComments, useAdminBlogPost, useAdminBlogPostMutations, useAdminBlogPosts, useAdminBlogSettings, useAdminBlogTags, useAdminNewsletterStats, useAdminNewsletterSubscribers, useAuth, useBlogCategories, useBlogCommentSubmit, useBlogComments, useBlogFeaturedPosts, useBlogPost, useBlogPosts, useBlogTags, useContactCapture, useEditMode, useEditModeMessaging, useFoxPixelContext, useLeadCapture, useNewsletterSubscribe, useNewsletterUnsubscribe, useSendEditRequest, useServices, useSiteContent, useSiteContentQuery, useSiteContentSection, useSiteContents, withAuth };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, ComponentType } from 'react';
2
+ import React, { ReactNode, ComponentType } from 'react';
3
3
  import { AxiosInstance, AxiosRequestConfig } from 'axios';
4
4
 
5
5
  /**
@@ -188,6 +188,8 @@ interface AuthContextValue {
188
188
  phone?: string;
189
189
  }) => Promise<void>;
190
190
  refetch: () => Promise<void>;
191
+ /** Stub: returns true when user is logged in and permission is site:content:update. */
192
+ hasPermission: (permission: string) => boolean;
191
193
  }
192
194
  interface AuthProviderProps {
193
195
  children: ReactNode;
@@ -261,6 +263,54 @@ interface WithAuthOptions {
261
263
  }
262
264
  declare function withAuth<P extends object>(Component: ComponentType<P>, options?: WithAuthOptions): (props: P) => string | number | true | Iterable<ReactNode> | react_jsx_runtime.JSX.Element | null;
263
265
 
266
+ interface EditableProps {
267
+ contentKey: string;
268
+ defaultValue: string;
269
+ as?: keyof JSX.IntrinsicElements;
270
+ multiline?: boolean;
271
+ className?: string;
272
+ }
273
+ declare function Editable({ contentKey, defaultValue, as, multiline, className, }: EditableProps): React.ReactElement<{
274
+ className: string;
275
+ 'aria-busy': boolean;
276
+ 'aria-label': string;
277
+ }, string | React.JSXElementConstructor<any>> | React.DOMElement<{
278
+ className: string;
279
+ 'data-content-key': string;
280
+ 'data-editable': string | undefined;
281
+ onClick: ((e: React.MouseEvent) => void) | undefined;
282
+ title: string | undefined;
283
+ }, Element>;
284
+ /**
285
+ * Renders rich HTML content from the CMS. Content is sanitized before rendering.
286
+ */
287
+ declare function EditableHTML({ contentKey, defaultValue, as, className, }: Omit<EditableProps, 'multiline'>): React.ReactElement<{
288
+ className: string;
289
+ 'aria-busy': boolean;
290
+ }, string | React.JSXElementConstructor<any>> | React.DOMElement<{
291
+ className: string;
292
+ 'data-content-key': string;
293
+ 'data-editable': string | undefined;
294
+ onClick: ((e: React.MouseEvent) => void) | undefined;
295
+ title: string | undefined;
296
+ dangerouslySetInnerHTML: {
297
+ __html: string;
298
+ };
299
+ }, Element>;
300
+ interface EditableImageProps {
301
+ contentKey: string;
302
+ defaultValue: string;
303
+ alt: string;
304
+ className?: string;
305
+ width?: number;
306
+ height?: number;
307
+ priority?: boolean;
308
+ }
309
+ /**
310
+ * Renders an image from a CMS-managed URL. Uses native img (no Next.js Image in SDK).
311
+ */
312
+ declare function EditableImage({ contentKey, defaultValue, alt, className, width, height, priority, }: EditableImageProps): react_jsx_runtime.JSX.Element;
313
+
264
314
  /**
265
315
  * Hook to fetch and manage services (Projects module)
266
316
  */
@@ -405,6 +455,237 @@ interface UseContactCaptureReturn {
405
455
  */
406
456
  declare function useContactCapture(): UseContactCaptureReturn;
407
457
 
458
+ /**
459
+ * Hook for managing editable site content (CMS Visual)
460
+ *
461
+ * Allows non-developers to edit text content directly on the site.
462
+ */
463
+
464
+ interface SiteContent {
465
+ id: string;
466
+ contentKey: string;
467
+ value: string | null;
468
+ contentType: string;
469
+ defaultValue: string | null;
470
+ description: string | null;
471
+ section: string | null;
472
+ sortOrder: number;
473
+ isActive: boolean;
474
+ updatedAt: string | null;
475
+ }
476
+ interface UseSiteContentOptions {
477
+ /**
478
+ * Default value to use if content is not found
479
+ */
480
+ defaultValue?: string;
481
+ /**
482
+ * Whether to fetch on mount (default: true)
483
+ */
484
+ fetchOnMount?: boolean;
485
+ }
486
+ interface UseSiteContentReturn {
487
+ /**
488
+ * The content object (null if not found or loading)
489
+ */
490
+ data: SiteContent | null;
491
+ /**
492
+ * The content value (or defaultValue if not found)
493
+ */
494
+ value: string;
495
+ /**
496
+ * Whether content is being loaded
497
+ */
498
+ isLoading: boolean;
499
+ /**
500
+ * Error if request failed
501
+ */
502
+ error: ApiError$1 | null;
503
+ /**
504
+ * Whether the current user can edit this content
505
+ */
506
+ canEdit: boolean;
507
+ /**
508
+ * Update the content value
509
+ */
510
+ update: (newValue: string) => Promise<void>;
511
+ /**
512
+ * Refetch the content
513
+ */
514
+ refetch: () => Promise<void>;
515
+ }
516
+ /**
517
+ * Hook for managing a single site content key.
518
+ *
519
+ * @example
520
+ * ```tsx
521
+ * function HeroSection() {
522
+ * const { value, canEdit, update } = useSiteContent('hero.title', {
523
+ * defaultValue: 'Welcome to our site'
524
+ * });
525
+ *
526
+ * const [isEditing, setIsEditing] = useState(false);
527
+ * const [editValue, setEditValue] = useState(value);
528
+ *
529
+ * const handleSave = async () => {
530
+ * await update(editValue);
531
+ * setIsEditing(false);
532
+ * };
533
+ *
534
+ * if (canEdit && isEditing) {
535
+ * return (
536
+ * <input
537
+ * value={editValue}
538
+ * onChange={(e) => setEditValue(e.target.value)}
539
+ * onBlur={handleSave}
540
+ * />
541
+ * );
542
+ * }
543
+ *
544
+ * return (
545
+ * <h1 onClick={() => canEdit && setIsEditing(true)}>
546
+ * {value}
547
+ * </h1>
548
+ * );
549
+ * }
550
+ * ```
551
+ */
552
+ declare function useSiteContent(contentKey: string, options?: UseSiteContentOptions): UseSiteContentReturn;
553
+ interface UseSiteContentsOptions {
554
+ /**
555
+ * Default values map
556
+ */
557
+ defaults?: Record<string, string>;
558
+ }
559
+ interface UseSiteContentsReturn {
560
+ /**
561
+ * Map of content key to content object
562
+ */
563
+ data: Record<string, SiteContent>;
564
+ /**
565
+ * Get value by key (with default fallback)
566
+ */
567
+ getValue: (key: string, defaultValue?: string) => string;
568
+ /**
569
+ * Whether contents are being loaded
570
+ */
571
+ isLoading: boolean;
572
+ /**
573
+ * Error if request failed
574
+ */
575
+ error: ApiError$1 | null;
576
+ /**
577
+ * Refetch all contents
578
+ */
579
+ refetch: () => Promise<void>;
580
+ }
581
+ /**
582
+ * Hook for fetching multiple site content keys at once.
583
+ * More efficient than calling useSiteContent multiple times.
584
+ *
585
+ * @example
586
+ * ```tsx
587
+ * function Footer() {
588
+ * const { getValue, isLoading } = useSiteContents(
589
+ * ['footer.copyright', 'footer.address', 'footer.phone'],
590
+ * { defaults: { 'footer.copyright': '© 2024' } }
591
+ * );
592
+ *
593
+ * if (isLoading) return null;
594
+ *
595
+ * return (
596
+ * <footer>
597
+ * <p>{getValue('footer.copyright')}</p>
598
+ * <p>{getValue('footer.address')}</p>
599
+ * <p>{getValue('footer.phone')}</p>
600
+ * </footer>
601
+ * );
602
+ * }
603
+ * ```
604
+ */
605
+ declare function useSiteContents(contentKeys: string[], options?: UseSiteContentsOptions): UseSiteContentsReturn;
606
+ interface UseSiteContentSectionReturn {
607
+ /**
608
+ * List of contents in the section
609
+ */
610
+ contents: SiteContent[];
611
+ /**
612
+ * Whether contents are being loaded
613
+ */
614
+ isLoading: boolean;
615
+ /**
616
+ * Error if request failed
617
+ */
618
+ error: ApiError$1 | null;
619
+ /**
620
+ * Refetch section contents
621
+ */
622
+ refetch: () => Promise<void>;
623
+ }
624
+ /**
625
+ * Hook for fetching all content in a section.
626
+ *
627
+ * @example
628
+ * ```tsx
629
+ * function HeroSection() {
630
+ * const { contents, isLoading } = useSiteContentSection('hero');
631
+ *
632
+ * if (isLoading) return <div>Loading...</div>;
633
+ *
634
+ * return (
635
+ * <div>
636
+ * {contents.map(content => (
637
+ * <div key={content.contentKey}>{content.value}</div>
638
+ * ))}
639
+ * </div>
640
+ * );
641
+ * }
642
+ * ```
643
+ */
644
+ declare function useSiteContentSection(section: string): UseSiteContentSectionReturn;
645
+
646
+ /**
647
+ * Edit-mode hooks for CMS Visual (iframe communication with Tenant Admin).
648
+ * When edit-mode=true is in the URL, the site enters edit mode and communicates
649
+ * with the parent iframe via postMessage.
650
+ */
651
+ /** Query key used for site content; must match useSiteContentQuery. */
652
+ declare const SITE_CONTENT_QUERY_KEY: "siteContent";
653
+ /**
654
+ * Returns true when the page is in edit mode (URL has edit-mode=true).
655
+ * Used to show edit affordances and enable postMessage communication.
656
+ */
657
+ declare function useEditMode(): boolean;
658
+ /**
659
+ * Sets up edit-mode messaging: notifies parent when ready and listens for
660
+ * FOXPIXEL_CONTENT_UPDATED to invalidate the corresponding site content query.
661
+ * App must be wrapped in QueryClientProvider when using edit mode.
662
+ */
663
+ declare function useEditModeMessaging(): boolean;
664
+ /**
665
+ * Returns a callback to send an edit request to the parent iframe.
666
+ * Only has effect when in edit mode.
667
+ */
668
+ declare function useSendEditRequest(): (contentKey: string, currentValue: string, contentType?: string, section?: string, description?: string) => void;
669
+
670
+ /**
671
+ * React Query-based hook for site content used by Editable components.
672
+ * Uses queryKey ['siteContent', key] so that useEditModeMessaging can invalidate
673
+ * on FOXPIXEL_CONTENT_UPDATED. Requires QueryClientProvider.
674
+ */
675
+ interface UseSiteContentQueryOptions {
676
+ defaultValue: string;
677
+ }
678
+ interface UseSiteContentQueryReturn {
679
+ value: string;
680
+ isLoading: boolean;
681
+ contentType: string;
682
+ }
683
+ /**
684
+ * Fetches a single site content by key using React Query. Used by Editable, EditableHTML, EditableImage.
685
+ * Invalidation is triggered by useEditModeMessaging when the parent sends FOXPIXEL_CONTENT_UPDATED.
686
+ */
687
+ declare function useSiteContentQuery(contentKey: string, options: UseSiteContentQueryOptions): UseSiteContentQueryReturn;
688
+
408
689
  /**
409
690
  * Blog module types for FoxPixel SDK
410
691
  * Aligned with backend BlogPostResponse, BlogCategoryResponse, BlogTagResponse
@@ -675,6 +956,8 @@ interface UseNewsletterSubscribeReturn {
675
956
  declare function useNewsletterSubscribe(): UseNewsletterSubscribeReturn;
676
957
  interface UseNewsletterUnsubscribeReturn {
677
958
  unsubscribe: (email: string) => Promise<boolean>;
959
+ /** Cancelar inscrição pelo token (link no email de confirmação). */
960
+ unsubscribeByToken: (token: string) => Promise<boolean>;
678
961
  isSubmitting: boolean;
679
962
  error: ApiError$1 | null;
680
963
  success: boolean;
@@ -861,4 +1144,4 @@ interface BlogPostSchemaLdOptions {
861
1144
  */
862
1145
  declare function getBlogPostSchemaLd(post: BlogPost, options: BlogPostSchemaLdOptions): Record<string, unknown>;
863
1146
 
864
- export { type ApiError$1 as ApiError, AuthProvider, type BlogAnalyticsSummary, type BlogAuthor, type BlogCategory, type BlogComment, type BlogCommentAdmin, type BlogCommentPage, type BlogPost, type BlogPostPage, type BlogPostSchemaLdOptions, type BlogPostStatus, type BlogSettings, type BlogTag, type CreateBlogCommentPayload, type CreateBlogPostPayload, type CreateCategoryPayload, type CreateLeadRequest, type CreateTagPayload, type EndUser, type EndUserLoginRequest, type FoxPixelConfig, FoxPixelHttpClient, FoxPixelProvider, GuestOnlyRoute, type Lead, type NewsletterFrequency, type NewsletterStats, type NewsletterStatus, type NewsletterSubscriber, type NewsletterSubscriberPage, type PostAnalyticsRow, ProtectedRoute, type Service, type ServiceCatalogResponse, type SubscribeNewsletterPayload, type UpdateBlogPostPayload, type UseAdminBlogAnalyticsReturn, type UseAdminBlogCategoriesReturn, type UseAdminBlogCommentsOptions, type UseAdminBlogCommentsReturn, type UseAdminBlogPostMutationsReturn, type UseAdminBlogPostReturn, type UseAdminBlogPostsOptions, type UseAdminBlogPostsReturn, type UseAdminBlogSettingsReturn, type UseAdminBlogTagsReturn, type UseAdminNewsletterStatsReturn, type UseAdminNewsletterSubscribersOptions, type UseAdminNewsletterSubscribersReturn, type UseBlogCategoriesReturn, type UseBlogCommentSubmitReturn, type UseBlogCommentsReturn, type UseBlogFeaturedPostsReturn, type UseBlogPostReturn, type UseBlogPostsOptions, type UseBlogPostsReturn, type UseBlogTagsReturn, type UseNewsletterSubscribeReturn, type UseNewsletterUnsubscribeReturn, getBlogPostSchemaLd, useAdminBlogAnalytics, useAdminBlogCategories, useAdminBlogComments, useAdminBlogPost, useAdminBlogPostMutations, useAdminBlogPosts, useAdminBlogSettings, useAdminBlogTags, useAdminNewsletterStats, useAdminNewsletterSubscribers, useAuth, useBlogCategories, useBlogCommentSubmit, useBlogComments, useBlogFeaturedPosts, useBlogPost, useBlogPosts, useBlogTags, useContactCapture, useFoxPixelContext, useLeadCapture, useNewsletterSubscribe, useNewsletterUnsubscribe, useServices, withAuth };
1147
+ export { type ApiError$1 as ApiError, AuthProvider, type BlogAnalyticsSummary, type BlogAuthor, type BlogCategory, type BlogComment, type BlogCommentAdmin, type BlogCommentPage, type BlogPost, type BlogPostPage, type BlogPostSchemaLdOptions, type BlogPostStatus, type BlogSettings, type BlogTag, type CreateBlogCommentPayload, type CreateBlogPostPayload, type CreateCategoryPayload, type CreateLeadRequest, type CreateTagPayload, Editable, EditableHTML, EditableImage, type EditableImageProps, type EditableProps, type EndUser, type EndUserLoginRequest, type FoxPixelConfig, FoxPixelHttpClient, FoxPixelProvider, GuestOnlyRoute, type Lead, type NewsletterFrequency, type NewsletterStats, type NewsletterStatus, type NewsletterSubscriber, type NewsletterSubscriberPage, type PostAnalyticsRow, ProtectedRoute, SITE_CONTENT_QUERY_KEY, type Service, type ServiceCatalogResponse, type SiteContent, type SubscribeNewsletterPayload, type UpdateBlogPostPayload, type UseAdminBlogAnalyticsReturn, type UseAdminBlogCategoriesReturn, type UseAdminBlogCommentsOptions, type UseAdminBlogCommentsReturn, type UseAdminBlogPostMutationsReturn, type UseAdminBlogPostReturn, type UseAdminBlogPostsOptions, type UseAdminBlogPostsReturn, type UseAdminBlogSettingsReturn, type UseAdminBlogTagsReturn, type UseAdminNewsletterStatsReturn, type UseAdminNewsletterSubscribersOptions, type UseAdminNewsletterSubscribersReturn, type UseBlogCategoriesReturn, type UseBlogCommentSubmitReturn, type UseBlogCommentsReturn, type UseBlogFeaturedPostsReturn, type UseBlogPostReturn, type UseBlogPostsOptions, type UseBlogPostsReturn, type UseBlogTagsReturn, type UseNewsletterSubscribeReturn, type UseNewsletterUnsubscribeReturn, type UseSiteContentOptions, type UseSiteContentQueryOptions, type UseSiteContentQueryReturn, type UseSiteContentReturn, type UseSiteContentSectionReturn, type UseSiteContentsOptions, type UseSiteContentsReturn, getBlogPostSchemaLd, useAdminBlogAnalytics, useAdminBlogCategories, useAdminBlogComments, useAdminBlogPost, useAdminBlogPostMutations, useAdminBlogPosts, useAdminBlogSettings, useAdminBlogTags, useAdminNewsletterStats, useAdminNewsletterSubscribers, useAuth, useBlogCategories, useBlogCommentSubmit, useBlogComments, useBlogFeaturedPosts, useBlogPost, useBlogPosts, useBlogTags, useContactCapture, useEditMode, useEditModeMessaging, useFoxPixelContext, useLeadCapture, useNewsletterSubscribe, useNewsletterUnsubscribe, useSendEditRequest, useServices, useSiteContent, useSiteContentQuery, useSiteContentSection, useSiteContents, withAuth };