first commit
This commit is contained in:
191
frontend/src/components/layout/LegalPageLayout.tsx
Normal file
191
frontend/src/components/layout/LegalPageLayout.tsx
Normal file
@@ -0,0 +1,191 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user