"use client"; import { useEffect, useState } from 'react'; import { useSearchParams, usePathname } from 'next/navigation'; import Header from "@/components/shared/layout/header/Header"; import Footer from "@/components/shared/layout/footer/Footer"; import { usePolicy } from '@/lib/hooks/usePolicy'; import { sanitizeHTML } from "@/lib/security/sanitize"; // Component that reads type from URL using Next.js hooks (safe in client components) const PolicyContentClient = () => { const searchParams = useSearchParams(); const pathname = usePathname(); const [type, setType] = useState<'privacy' | 'terms' | 'support'>('privacy'); const [mounted, setMounted] = useState(false); useEffect(() => { // Only run on client side if (typeof window === 'undefined') return; setMounted(true); // Get type from URL search params try { const urlType = searchParams?.get('type'); if (urlType && ['privacy', 'terms', 'support'].includes(urlType)) { setType(urlType as 'privacy' | 'terms' | 'support'); } else { setType('privacy'); // Default fallback } } catch (error) { console.error('Error reading URL type:', error); setType('privacy'); // Fallback to default } }, [searchParams, pathname]); // If not mounted yet, show loading state if (!mounted) { return (

Loading policy...

); } return ; }; // Inner component that doesn't use useSearchParams const PolicyContentInner = ({ type }: { type: 'privacy' | 'terms' | 'support' }) => { const { data: policy, isLoading, error } = usePolicy(type); // Update metadata based on policy type useEffect(() => { // Only run on client side if (typeof window === 'undefined' || typeof document === 'undefined') return; const policyTitles = { privacy: 'Privacy Policy - Data Protection & Privacy', terms: 'Terms of Use - Terms & Conditions', support: 'Support Policy - Support Terms & Guidelines', }; const policyDescriptions = { privacy: 'Read GNX Soft\'s Privacy Policy to understand how we collect, use, and protect your personal information and data.', terms: 'Review GNX Soft\'s Terms of Use and Conditions for using our software services and platforms.', support: 'Learn about GNX Soft\'s Support Policy, including support terms, response times, and service level agreements.', }; try { // Dynamically import metadata function to avoid SSR issues import("@/lib/seo/metadata").then(({ generateMetadata: createMetadata }) => { const metadata = createMetadata({ title: policyTitles[type], description: policyDescriptions[type], keywords: [ type === 'privacy' ? 'Privacy Policy' : type === 'terms' ? 'Terms of Use' : 'Support Policy', 'Legal Documents', 'Company Policies', 'Data Protection', 'Terms and Conditions', ], url: `/policy?type=${type}`, }); const titleString = typeof metadata.title === 'string' ? metadata.title : `${policyTitles[type]} | GNX Soft`; document.title = titleString; let metaDescription = document.querySelector('meta[name="description"]'); if (!metaDescription) { metaDescription = document.createElement('meta'); metaDescription.setAttribute('name', 'description'); document.head.appendChild(metaDescription); } const descriptionString = typeof metadata.description === 'string' ? metadata.description : policyDescriptions[type]; metaDescription.setAttribute('content', descriptionString); }).catch((error) => { // Fallback to simple title/description update if metadata import fails console.warn('Error loading metadata function:', error); document.title = `${policyTitles[type]} | GNX Soft`; let metaDescription = document.querySelector('meta[name="description"]'); if (!metaDescription) { metaDescription = document.createElement('meta'); metaDescription.setAttribute('name', 'description'); document.head.appendChild(metaDescription); } metaDescription.setAttribute('content', policyDescriptions[type]); }); } catch (error) { // Silently handle metadata errors console.error('Error setting metadata:', error); } }, [type]); if (isLoading) { return (

Loading policy...

); } if (error || !policy) { return (

Unable to Load Policy

{error?.message || 'The requested policy could not be found.'}

Return to Support Center
); } return (
{/* Policy Header */}

{policy.title || 'Policy'}

{policy.last_updated && (

Last Updated: {(() => { try { return new Date(policy.last_updated).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } catch { return new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } })()}

)} {policy.version && (

Version {policy.version}

)} {policy.effective_date && (

Effective Date: {(() => { try { return new Date(policy.effective_date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } catch { return new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); } })()}

)}
{policy.description && (

{policy.description}

)}
{/* Policy Content */}
{policy.sections && Array.isArray(policy.sections) && policy.sections.length > 0 ? ( policy.sections.map((section) => (

{section.heading || ''}


(a)') .replace(/\(b\)/g, '

(b)') .replace(/\(c\)/g, '

(c)') .replace(/\(d\)/g, '

(d)') .replace(/\(e\)/g, '

(e)') .replace(/\(f\)/g, '

(f)') .replace(/\(g\)/g, '

(g)') .replace(/\(h\)/g, '

(h)') .replace(/\(i\)/g, '

(i)') .replace(/\(j\)/g, '

(j)') .replace(/\(k\)/g, '

(k)') .replace(/\(l\)/g, '

(l)') // Handle pipe separators for contact information .replace(/ \| /g, '
') .replace(/: /g, ': ') // Handle semicolon with parenthesis .replace(/; \(/g, ';

(') // Add spacing after periods in long sentences .replace(/\. ([A-Z])/g, '.

$1') ) }} />
)) ) : (

No content available.

)}
{/* Contact Section */}

Questions?

If you have any questions about this policy, please don't hesitate to contact us.

Contact Us
); }; // Wrapper component (no longer needs Suspense since we're not using useSearchParams) const PolicyContentWrapper = () => { return ; }; const PolicyPage = () => { return (
); }; export default PolicyPage;