feat(content): add How It Works page with markdown support
- Create HowItWorksPage component with markdown rendering - Add how-it-works.md with Lorem Ipsum placeholder content - Add /how-it-works route in App.jsx - Add How It Works link to homepage footer (Product section)
This commit is contained in:
91
frontend/src/pages/HowItWorksPage.jsx
Normal file
91
frontend/src/pages/HowItWorksPage.jsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import Layout from '../components/layout/Layout';
|
||||
|
||||
export default function HowItWorksPage() {
|
||||
const [content, setContent] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch markdown content
|
||||
fetch('/content/how-it-works.md')
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load content');
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
setContent(text);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Error loading how-it-works content:', err);
|
||||
setError('Failed to load page content');
|
||||
setLoading(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="w-12 h-12 border-4 border-primary-600 border-t-transparent rounded-full animate-spin mx-auto mb-4"></div>
|
||||
<p className="text-gray-600">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<p className="text-red-600">{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="min-h-screen bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<article className="bg-white rounded-lg shadow-sm p-8 md:p-12 prose prose-lg max-w-none">
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
// Customize link rendering to use React Router for internal links
|
||||
a: ({ node, href, children, ...props }) => {
|
||||
const isInternal = href && href.startsWith('/');
|
||||
if (isInternal) {
|
||||
return (
|
||||
<a href={href} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<a href={href} target="_blank" rel="noopener noreferrer" {...props}>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
// Ensure images are responsive
|
||||
img: ({ node, ...props }) => (
|
||||
<img className="rounded-lg shadow-md" {...props} alt={props.alt || ''} />
|
||||
),
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</ReactMarkdown>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user