Add Help page with markdown support and routing
This commit is contained in:
@@ -7,6 +7,7 @@ import { AdminTerms } from './pages/AdminTerms';
|
||||
import Dictionary from './pages/Dictionary';
|
||||
import Znakopis from './pages/Znakopis';
|
||||
import VideoSentence from './pages/VideoSentence';
|
||||
import Help from './pages/Help';
|
||||
import { ProtectedRoute } from './components/ProtectedRoute';
|
||||
import { useAuthStore } from './stores/authStore';
|
||||
import { Toaster } from 'sonner';
|
||||
@@ -56,7 +57,7 @@ function App() {
|
||||
<Route path="/video-sentence" element={<ProtectedRoute><VideoSentence /></ProtectedRoute>} />
|
||||
{/* Placeholder routes for other pages */}
|
||||
<Route path="/cloud" element={<ProtectedRoute><div>Cloud (Coming Soon)</div></ProtectedRoute>} />
|
||||
<Route path="/help" element={<ProtectedRoute><div>Help (Coming Soon)</div></ProtectedRoute>} />
|
||||
<Route path="/help" element={<ProtectedRoute><Help /></ProtectedRoute>} />
|
||||
<Route path="/community" element={<ProtectedRoute><div>Community (Coming Soon)</div></ProtectedRoute>} />
|
||||
<Route path="/comments" element={<ProtectedRoute><div>Comments (Coming Soon)</div></ProtectedRoute>} />
|
||||
<Route path="/bug-report" element={<ProtectedRoute><div>Bug Report (Coming Soon)</div></ProtectedRoute>} />
|
||||
|
||||
142
packages/frontend/src/pages/Help.tsx
Normal file
142
packages/frontend/src/pages/Help.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Layout } from '../components/layout/Layout';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
|
||||
function Help() {
|
||||
const [content, setContent] = useState<string>('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchHelpContent = async () => {
|
||||
try {
|
||||
const response = await fetch('/help.md');
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load help documentation');
|
||||
}
|
||||
const text = await response.text();
|
||||
setContent(text);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'An error occurred');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchHelpContent();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-600">Učitavanje priručnika...</p>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<p className="text-red-600 mb-2">Greška pri učitavanju priručnika</p>
|
||||
<p className="text-gray-600">{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="bg-white rounded-lg shadow-sm p-8">
|
||||
<article className="prose prose-indigo max-w-none">
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
h1: ({ children }) => (
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4 pb-4 border-b-2 border-indigo-200">
|
||||
{children}
|
||||
</h1>
|
||||
),
|
||||
h2: ({ children }) => (
|
||||
<h2 className="text-3xl font-bold text-gray-900 mt-8 mb-4 pb-2 border-b border-gray-200">
|
||||
{children}
|
||||
</h2>
|
||||
),
|
||||
h3: ({ children }) => (
|
||||
<h3 className="text-2xl font-semibold text-gray-800 mt-6 mb-3">
|
||||
{children}
|
||||
</h3>
|
||||
),
|
||||
h4: ({ children }) => (
|
||||
<h4 className="text-xl font-semibold text-gray-800 mt-4 mb-2">
|
||||
{children}
|
||||
</h4>
|
||||
),
|
||||
p: ({ children }) => (
|
||||
<p className="text-gray-700 leading-relaxed mb-4">
|
||||
{children}
|
||||
</p>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="list-disc list-inside space-y-2 mb-4 text-gray-700">
|
||||
{children}
|
||||
</ul>
|
||||
),
|
||||
ol: ({ children }) => (
|
||||
<ol className="list-decimal list-inside space-y-2 mb-4 text-gray-700">
|
||||
{children}
|
||||
</ol>
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="ml-4">
|
||||
{children}
|
||||
</li>
|
||||
),
|
||||
a: ({ href, children }) => (
|
||||
<a
|
||||
href={href}
|
||||
className="text-indigo-600 hover:text-indigo-800 underline"
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
strong: ({ children }) => (
|
||||
<strong className="font-semibold text-gray-900">
|
||||
{children}
|
||||
</strong>
|
||||
),
|
||||
code: ({ children }) => (
|
||||
<code className="bg-gray-100 text-indigo-600 px-1.5 py-0.5 rounded text-sm font-mono">
|
||||
{children}
|
||||
</code>
|
||||
),
|
||||
hr: () => (
|
||||
<hr className="my-8 border-t-2 border-gray-200" />
|
||||
),
|
||||
blockquote: ({ children }) => (
|
||||
<blockquote className="border-l-4 border-indigo-500 pl-4 italic text-gray-700 my-4">
|
||||
{children}
|
||||
</blockquote>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</ReactMarkdown>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Help;
|
||||
|
||||
Reference in New Issue
Block a user