Files
shopify-react-editor-template/components/shopify/policy-body.tsx
T
2026-08-09 16:00:10 -04:00

87 lines
2.3 KiB
TypeScript

'use client';
import React, { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { getShopPolicy, type ShopPolicy } from '@/hooks/use-shopify-policies';
export interface PolicyBodyProps {
/**
* Pins the block to one policy. Left empty, it reads the `[handle]` segment,
* which is what the `/policies/[handle]` template does.
*/
handle?: string;
/** Overrides the policy's own title. Empty falls back to Shopify's. */
title?: string;
notFoundMessage?: string;
}
/**
* Policy copy is authored in the Shopify admin, not here — the editor only
* chooses which policy to show and can override the heading.
*/
const PolicyBody: React.FC<PolicyBodyProps> = ({
handle: handleProp,
title: titleProp,
notFoundMessage = 'This policy has not been published yet.',
}) => {
const params = useParams();
const handle = handleProp || (params?.handle as string | undefined);
const [policy, setPolicy] = useState<ShopPolicy | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!handle) {
setLoading(false);
return;
}
let cancelled = false;
setLoading(true);
getShopPolicy(handle)
.then((result) => {
if (!cancelled) setPolicy(result);
})
.catch(() => {
if (!cancelled) setPolicy(null);
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => {
cancelled = true;
};
}, [handle]);
return (
<main className="max-w-screen-2xl mx-auto w-full px-5 lg:px-10 py-16">
<div className="max-w-2xl mx-auto">
<h1 className="text-3xl md:text-4xl font-normal text-foreground">
{titleProp || policy?.title || 'Policy'}
</h1>
{loading ? (
<div className="mt-8 animate-pulse space-y-3">
{Array.from({ length: 6 }).map((_, index) => (
<div key={index} className="h-4 bg-zinc-100" />
))}
</div>
) : policy ? (
<div
className="policy-body mt-8 text-[15px] leading-7 text-foreground"
dangerouslySetInnerHTML={{ __html: policy.body }}
/>
) : (
<p className="mt-8 text-sm text-muted-foreground">
{notFoundMessage}
</p>
)}
</div>
</main>
);
};
export default PolicyBody;