diff --git a/src/app/privacy/page.jsx b/src/app/privacy/page.jsx new file mode 100644 index 0000000..48e0d7d --- /dev/null +++ b/src/app/privacy/page.jsx @@ -0,0 +1,154 @@ +import Header from '@/components/header'; +import Footer from '@/components/footer'; +import Link from 'next/link'; +import ReactMarkdown from 'react-markdown'; +import { readFileSync, statSync } from 'fs'; +import { join } from 'path'; +import { execSync } from 'child_process'; + +export const metadata = { + title: 'Privacy Policy | LiteNet', + description: 'Privacy Policy for LiteNet PBX services.', +}; + +function getFileLastModified(filePath) { + try { + // Try to get the last commit date for this specific file + const gitDate = execSync(`git log -1 --format=%ci -- "${filePath}"`, { + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'] // Suppress stderr to avoid build errors + }).trim(); + + const gitHashShort = execSync(`git log -1 --format=%h -- "${filePath}"`, { + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'] + }).trim(); + + const gitHashFull = execSync(`git log -1 --format=%H -- "${filePath}"`, { + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'] + }).trim(); + + if (gitDate && gitHashShort && gitHashFull) { + return { + date: new Date(gitDate).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }), + hash: gitHashShort, + fullHash: gitHashFull, + source: 'git' + }; + } + } catch { + // Fall back to file system timestamp if git fails (e.g., in build environment) + } + + try { + const stats = statSync(filePath); + return { + date: stats.mtime.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }), + hash: null, + fullHash: null, + source: 'filesystem' + }; + } catch { + // Final fallback + return { + date: 'Unknown', + hash: null, + fullHash: null, + source: 'fallback' + }; + } +} + +export default function PrivacyPage() { + // Read the markdown file at build time + const privacyPath = join(process.cwd(), 'src', 'data', 'privacy.md'); + const privacyContent = readFileSync(privacyPath, 'utf8'); + + // Remove the header section from markdown content + const cleanedContent = privacyContent.replace(/^# Privacy Policy[\s\S]*?(?=^## 1\. Information We Collect)/m, ''); + + const fileInfo = getFileLastModified(privacyPath); + + return ( + <> +
+
+
+
+
+ + ← Back to home + +
+ +
+

Privacy Policy

+

+ Last updated: {fileInfo.date} + {fileInfo.hash && fileInfo.fullHash && ( + + (commit + {fileInfo.hash} + ) + + )} +

+

+ LiteNet is committed to protecting your privacy. This Privacy Policy explains our practices regarding the collection, use, and disclosure of your information when you use our services. +

+
+ +
+

{children}

, + h2: ({ children }) => { + const text = typeof children === 'string' ? children : children?.join?.('') || ''; + if (text.includes('ACKNOWLEDGMENT')) { + return null; // Don't render the header separately, handle in the wrapper + } + return

{children}

; + }, + h3: ({ children }) =>

{children}

, + p: ({ children }) => { + const text = typeof children === 'string' ? children : children?.toString?.() || ''; + const isAcknowledgment = text.includes('By using LiteNet\'s services, you acknowledge'); + + if (isAcknowledgment) { + return ( +
+

ACKNOWLEDGMENT

+

{children}

+
+ ); + } + return

{children}

; + }, + ul: ({ children }) =>
    {children}
, + ol: ({ children }) =>
    {children}
, + li: ({ children }) =>
  • {children}
  • , + a: ({ href, children }) => ( + + {children} + + ), + strong: ({ children }) => {children}, + hr: () =>
    , + }} + > + {cleanedContent} +
    +
    +
    +
    +
    +