feat: integrate API calls for forum, bug, and event pages; replace mock data with dynamic data fetching

This commit is contained in:
Thibault Pouch
2026-03-03 09:48:07 +01:00
parent 4768bd5184
commit f54f237dd9
7 changed files with 363 additions and 241 deletions

View File

@@ -1,6 +1,6 @@
import { useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { MOCK_CATEGORIES, MOCK_THREADS } from '../../data/mockData';
import { forumApi } from '../../utils/api';
import { timeAgo } from '../../utils/format';
import type { ForumCategory, ForumThread } from '../../types';
@@ -128,15 +128,43 @@ function CategoryCard({ category, threads }: { category: ForumCategory; threads:
export default function ForumPage() {
const [search, setSearch] = useState('');
const [categories, setCategories] = useState<ForumCategory[]>([]);
const [threads, setThreads] = useState<ForumThread[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
let cancelled = false;
setLoading(true);
Promise.all([
forumApi.getCategories(),
forumApi.getThreads({ limit: 200 }),
])
.then(([cats, threadRes]) => {
if (cancelled) return;
setCategories(cats);
setThreads(threadRes.data);
})
.catch(() => {
if (cancelled) return;
setError('Failed to load forum. Please try again.');
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => { cancelled = true; };
}, []);
const filteredCategories = useMemo(() => {
if (!search.trim()) return MOCK_CATEGORIES;
if (!search.trim()) return categories;
const q = search.toLowerCase();
return MOCK_CATEGORIES.filter((cat) =>
return categories.filter((cat) =>
cat.name.toLowerCase().includes(q) ||
MOCK_THREADS.some((t) => t.categoryId === cat.id && t.title.toLowerCase().includes(q))
threads.some((t) => t.categoryId === cat.id && t.title.toLowerCase().includes(q))
);
}, [search]);
}, [search, categories, threads]);
return (
<div style={{ maxWidth: '960px', margin: '0 auto', padding: '4rem 1.5rem' }}>
@@ -173,15 +201,29 @@ export default function ForumPage() {
</div>
</div>
{/* Categories */}
{filteredCategories.length === 0 ? (
{loading && (
<div className="crt-box" style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)' }}>
No results found for "{search}"
Loading forum...
</div>
) : (
filteredCategories.map((cat) => (
<CategoryCard key={cat.id} category={cat} threads={MOCK_THREADS} />
))
)}
{error && !loading && (
<div className="crt-box" style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-red)', fontFamily: 'var(--font-mono)' }}>
{error}
</div>
)}
{/* Categories */}
{!loading && !error && (
filteredCategories.length === 0 ? (
<div className="crt-box" style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)' }}>
No results found for "{search}"
</div>
) : (
filteredCategories.map((cat) => (
<CategoryCard key={cat.id} category={cat} threads={threads} />
))
)
)}
</div>
);