feat: integrate settings API to manage forum and bug reporting availability

This commit is contained in:
Thibault Pouch
2026-03-17 11:44:05 +01:00
parent f481a6fc4e
commit f9012bd123
4 changed files with 49 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useMemo, useCallback, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { bugsApi } from '../../utils/api';
import { bugsApi, settingsApi } from '../../utils/api';
import { useAuth } from '../../contexts/AuthContext';
import { timeAgo } from '../../utils/format';
import type { BugReport, BugSeverity, BugStatus, BugReportFormData } from '../../types';
@@ -278,10 +278,15 @@ export default function BugReportPage() {
const { user, isAuthenticated } = useAuth();
const [bugs, setBugs] = useState<BugReport[]>([]);
const [loading, setLoading] = useState(true);
const [bugsEnabled, setBugsEnabled] = useState(true);
const [statusFilter, setStatusFilter] = useState<BugStatus | 'all'>('all');
const [severityFilter, setSeverityFilter] = useState<BugSeverity | 'all'>('all');
const [showForm, setShowForm] = useState(false);
useEffect(() => {
settingsApi.get().then((s) => setBugsEnabled(s.bugsEnabled)).catch(() => {});
}, []);
const fetchBugs = useCallback(() => {
setLoading(true);
bugsApi.getBugs({ status: statusFilter, severity: severityFilter, limit: 100 })
@@ -312,6 +317,20 @@ export default function BugReportPage() {
const inProgressCount = bugs.filter((b) => b.status === 'in_progress').length;
const resolvedCount = bugs.filter((b) => b.status === 'resolved').length;
if (!bugsEnabled) {
return (
<div style={{ maxWidth: '960px', margin: '0 auto', padding: '3rem 1.5rem', textAlign: 'center' }}>
<div className="section-label">Issue Tracker</div>
<h1 style={{ fontFamily: 'var(--font-heading)', color: 'var(--color-red)', fontSize: 'clamp(2rem, 6vw, 3.5rem)', marginTop: '0.25rem' }}>
BUG REPORTS UNAVAILABLE
</h1>
<p style={{ color: 'var(--color-text-muted)', fontSize: '0.78rem', marginTop: '1rem', fontFamily: 'var(--font-mono)' }}>
Bug reporting has been temporarily disabled by an administrator.
</p>
</div>
);
}
return (
<div style={{ maxWidth: '960px', margin: '0 auto', padding: '3rem 1.5rem' }}>
{/* Header */}

View File

@@ -1,6 +1,6 @@
import { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { forumApi } from '../../utils/api';
import { forumApi, settingsApi } from '../../utils/api';
import { timeAgo } from '../../utils/format';
import type { ForumCategory, ForumThread } from '../../types';
@@ -132,17 +132,20 @@ export default function ForumPage() {
const [threads, setThreads] = useState<ForumThread[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [forumEnabled, setForumEnabled] = useState(true);
useEffect(() => {
let cancelled = false;
setLoading(true);
Promise.all([
settingsApi.get(),
forumApi.getCategories(),
forumApi.getThreads({ limit: 200 }),
])
.then(([cats, threadRes]) => {
.then(([settings, cats, threadRes]) => {
if (cancelled) return;
setForumEnabled(settings.forumEnabled);
setCategories(cats);
setThreads(threadRes.data);
})
@@ -166,6 +169,20 @@ export default function ForumPage() {
);
}, [search, categories, threads]);
if (!loading && !forumEnabled) {
return (
<div style={{ maxWidth: '960px', margin: '0 auto', padding: '4rem 1.5rem', textAlign: 'center' }}>
<div className="section-label">Community</div>
<h1 style={{ fontFamily: 'var(--font-heading)', color: 'var(--color-red)', fontSize: 'clamp(2rem, 5vw, 3rem)', marginTop: '0.5rem' }}>
FORUM UNAVAILABLE
</h1>
<p style={{ color: 'var(--color-text-muted)', fontSize: '0.8rem', marginTop: '1rem', fontFamily: 'var(--font-mono)' }}>
The forum has been temporarily disabled by an administrator.
</p>
</div>
);
}
return (
<div style={{ maxWidth: '960px', margin: '0 auto', padding: '4rem 1.5rem' }}>
{/* Header */}

View File

@@ -78,9 +78,9 @@ export default function StudioPage() {
marginBottom: '1rem',
}}
>
CrowMate Studio is an independent game studio founded in 2023 by a team of six developers
CrowMate Studio is an independent game studio founded in 2026 by a team of six developers
who are all new to game development and learning by building together. We are headquartered
somewhere in Europe and operate fully remote.
somewhere in France and operate arround the globe.
</p>
<p
style={{
@@ -105,7 +105,6 @@ export default function StudioPage() {
{[
{ label: 'TEAM SIZE', value: '6 PEOPLE' },
{ label: 'FOUNDED', value: '2026' },
{ label: 'WORK MODE', value: 'REMOTE' },
{ label: 'CURRENT GAME', value: 'HEADLESS HAZARD' },
].map(({ label, value }) => (
<div key={label}>

View File

@@ -190,3 +190,11 @@ export const eventsApi = {
export const teamApi = {
getMembers: () => apiFetch<TeamMember[]>('/team'),
};
// ── Settings API ──────────────────────────────────────────────────────────────
export type SiteSettings = { forumEnabled: boolean; bugsEnabled: boolean };
export const settingsApi = {
get: () => apiFetch<SiteSettings>('/settings'),
};