Files
Spanglish/frontend/src/components/layout/LegalPageLayout.tsx
2026-01-29 14:13:11 -03:00

192 lines
6.4 KiB
TypeScript

'use client';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import Link from 'next/link';
import { ArrowLeftIcon } from '@heroicons/react/24/outline';
interface LegalPageLayoutProps {
title: string;
content: string;
lastUpdated?: string;
}
export default function LegalPageLayout({ title, content, lastUpdated }: LegalPageLayoutProps) {
return (
<div className="section-padding">
<div className="container-page max-w-4xl">
{/* Back link */}
<Link
href="/"
className="inline-flex items-center text-gray-600 hover:text-primary-dark transition-colors mb-8"
>
<ArrowLeftIcon className="w-4 h-4 mr-2" />
Back to Home
</Link>
{/* Title */}
<div className="mb-8 pb-6 border-b border-gray-200">
<h1 className="text-3xl md:text-4xl font-bold text-primary-dark mb-2">
{title}
</h1>
{lastUpdated && lastUpdated !== '[Insert Date]' && (
<p className="text-sm text-gray-500">
Last updated: {lastUpdated}
</p>
)}
</div>
{/* Markdown content */}
<article className="prose prose-gray max-w-none legal-content">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
// Style headings
h1: ({ children }) => (
<h1 className="text-3xl font-bold text-primary-dark mt-8 mb-4 first:mt-0">
{children}
</h1>
),
h2: ({ children }) => (
<h2 className="text-2xl font-semibold text-primary-dark mt-8 mb-4 pb-2 border-b border-gray-200">
{children}
</h2>
),
h3: ({ children }) => (
<h3 className="text-xl font-semibold text-primary-dark mt-6 mb-3">
{children}
</h3>
),
h4: ({ children }) => (
<h4 className="text-lg font-semibold text-primary-dark mt-4 mb-2">
{children}
</h4>
),
// Style paragraphs
p: ({ children }) => (
<p className="text-gray-700 leading-relaxed mb-4">
{children}
</p>
),
// Style lists
ul: ({ children }) => (
<ul className="list-disc list-inside space-y-2 mb-4 text-gray-700 ml-4">
{children}
</ul>
),
ol: ({ children }) => (
<ol className="list-decimal list-inside space-y-2 mb-4 text-gray-700 ml-4">
{children}
</ol>
),
li: ({ children }) => (
<li className="text-gray-700">
{children}
</li>
),
// Style links
a: ({ href, children }) => (
<a
href={href}
className="text-primary-dark underline hover:text-primary-yellow transition-colors"
target={href?.startsWith('http') ? '_blank' : undefined}
rel={href?.startsWith('http') ? 'noopener noreferrer' : undefined}
>
{children}
</a>
),
// Style horizontal rules
hr: () => (
<hr className="my-8 border-gray-200" />
),
// Style blockquotes
blockquote: ({ children }) => (
<blockquote className="border-l-4 border-primary-yellow pl-4 my-4 italic text-gray-600">
{children}
</blockquote>
),
// Style tables
table: ({ children }) => (
<div className="overflow-x-auto my-6">
<table className="min-w-full divide-y divide-gray-200 border border-gray-200 rounded-lg">
{children}
</table>
</div>
),
thead: ({ children }) => (
<thead className="bg-gray-50">
{children}
</thead>
),
tbody: ({ children }) => (
<tbody className="bg-white divide-y divide-gray-200">
{children}
</tbody>
),
tr: ({ children }) => (
<tr>
{children}
</tr>
),
th: ({ children }) => (
<th className="px-4 py-3 text-left text-sm font-semibold text-primary-dark">
{children}
</th>
),
td: ({ children }) => (
<td className="px-4 py-3 text-sm text-gray-700">
{children}
</td>
),
// Style code blocks
code: ({ className, children }) => {
const isInline = !className;
if (isInline) {
return (
<code className="bg-gray-100 px-1.5 py-0.5 rounded text-sm text-gray-800">
{children}
</code>
);
}
return (
<code className={className}>
{children}
</code>
);
},
pre: ({ children }) => (
<pre className="bg-gray-100 rounded-lg p-4 overflow-x-auto my-4">
{children}
</pre>
),
// Style strong and emphasis
strong: ({ children }) => (
<strong className="font-semibold text-primary-dark">
{children}
</strong>
),
em: ({ children }) => (
<em className="italic">
{children}
</em>
),
}}
>
{content}
</ReactMarkdown>
</article>
{/* Back to top link */}
<div className="mt-12 pt-6 border-t border-gray-200">
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className="text-gray-500 hover:text-primary-dark transition-colors text-sm"
>
Back to top
</button>
</div>
</div>
</div>
);
}