chore: remove mock data usage and initialize state in various components for cleaner setup
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import { DEMO_CREDENTIALS } from '../data/mockData';
|
|
||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
const { login, isAuthenticated } = useAuth();
|
const { login, isAuthenticated } = useAuth();
|
||||||
@@ -44,22 +43,6 @@ export default function LoginPage() {
|
|||||||
[email, password, login, navigate, from]
|
[email, password, login, navigate, from]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleQuickLogin = useCallback(
|
|
||||||
async (credEmail: string) => {
|
|
||||||
setEmail(credEmail);
|
|
||||||
setError('');
|
|
||||||
setLoading(true);
|
|
||||||
const result = await login(credEmail, 'demo');
|
|
||||||
setLoading(false);
|
|
||||||
if (result.success) {
|
|
||||||
navigate(from, { replace: true });
|
|
||||||
} else {
|
|
||||||
setError(result.error || 'Login failed.');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[login, navigate, from]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -185,39 +168,6 @@ export default function LoginPage() {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Quick login */}
|
|
||||||
<div style={{ marginTop: '1.5rem' }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontFamily: 'var(--font-mono)',
|
|
||||||
color: 'var(--color-text-muted)',
|
|
||||||
fontSize: '0.65rem',
|
|
||||||
letterSpacing: '0.1em',
|
|
||||||
textAlign: 'center',
|
|
||||||
marginBottom: '0.75rem',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
QUICK LOGIN (DEMO)
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex', gap: '0.5rem', justifyContent: 'center' }}>
|
|
||||||
<button
|
|
||||||
className="btn-terminal"
|
|
||||||
style={{ padding: '0.35rem 0.8rem', fontSize: '0.7rem' }}
|
|
||||||
onClick={() => handleQuickLogin(DEMO_CREDENTIALS.admin)}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
Admin (Kestrel)
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btn-terminal"
|
|
||||||
style={{ padding: '0.35rem 0.8rem', fontSize: '0.7rem' }}
|
|
||||||
onClick={() => handleQuickLogin(DEMO_CREDENTIALS.staff)}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
Staff (Vesper)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useState, useMemo, useCallback } from 'react';
|
import { useState, useMemo, useCallback } from 'react';
|
||||||
import { MOCK_BUGS, MOCK_USERS } from '../../data/mockData';
|
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { formatDate, formatDateTime } from '../../utils/format';
|
import { formatDate, formatDateTime } from '../../utils/format';
|
||||||
import type { BugReport, BugSeverity, BugStatus, BugReportNote } from '../../types';
|
import type { BugReport, BugSeverity, BugStatus, BugReportNote } from '../../types';
|
||||||
@@ -16,12 +15,12 @@ function SeverityBadge({ severity }: { severity: BugSeverity }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const STATUSES: BugStatus[] = ['open', 'in_progress', 'resolved', 'closed'];
|
const STATUSES: BugStatus[] = ['open', 'in_progress', 'resolved', 'closed'];
|
||||||
const STAFF_MEMBERS = MOCK_USERS.filter((u) => u.role === 'dev' || u.role === 'com');
|
const STAFF_MEMBERS: { id: string; username: string; role: string }[] = [];
|
||||||
|
|
||||||
export default function IntranetBugs() {
|
export default function IntranetBugs() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const [bugs, setBugs] = useState<BugReport[]>(MOCK_BUGS);
|
const [bugs, setBugs] = useState<BugReport[]>([]);
|
||||||
const [selected, setSelected] = useState<BugReport | null>(null);
|
const [selected, setSelected] = useState<BugReport | null>(null);
|
||||||
const [statusFilter, setStatusFilter] = useState<BugStatus | 'all'>('all');
|
const [statusFilter, setStatusFilter] = useState<BugStatus | 'all'>('all');
|
||||||
const [severityFilter, setSeverityFilter] = useState<BugSeverity | 'all'>('all');
|
const [severityFilter, setSeverityFilter] = useState<BugSeverity | 'all'>('all');
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { MOCK_BUGS, MOCK_STAFF_POSTS, MOCK_USERS, MOCK_THREADS } from '../../data/mockData';
|
|
||||||
|
|
||||||
interface StatCardProps {
|
interface StatCardProps {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -81,10 +80,10 @@ function NavTile({ to, label, description, icon }: NavTileProps) {
|
|||||||
export default function IntranetDashboard() {
|
export default function IntranetDashboard() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const openBugs = MOCK_BUGS.filter((b) => b.status === 'open').length;
|
const openBugs = 0;
|
||||||
const criticalBugs = MOCK_BUGS.filter((b) => b.severity === 'critical').length;
|
const criticalBugs = 0;
|
||||||
const assignedToMe = MOCK_BUGS.filter((b) => b.assignedToId === user?.id).length;
|
const assignedToMe = 0;
|
||||||
const totalUsers = MOCK_USERS.filter((u) => !u.isAdmin).length;
|
const totalUsers = 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -111,8 +110,8 @@ export default function IntranetDashboard() {
|
|||||||
<StatCard label="Critical" value={criticalBugs} accent="red" />
|
<StatCard label="Critical" value={criticalBugs} accent="red" />
|
||||||
<StatCard label="Assigned to Me" value={assignedToMe} accent="amber" />
|
<StatCard label="Assigned to Me" value={assignedToMe} accent="amber" />
|
||||||
<StatCard label="Total Users" value={totalUsers} accent="green" />
|
<StatCard label="Total Users" value={totalUsers} accent="green" />
|
||||||
<StatCard label="Forum Threads" value={MOCK_THREADS.length} accent="green" />
|
<StatCard label="Forum Threads" value={0} accent="green" />
|
||||||
<StatCard label="Staff Posts Today" value={MOCK_STAFF_POSTS.filter((p) => p.createdAt.startsWith('2026-02-18')).length} accent="amber" />
|
<StatCard label="Staff Posts Today" value={0} accent="amber" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -134,29 +133,8 @@ export default function IntranetDashboard() {
|
|||||||
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.7rem', letterSpacing: '0.15em', marginBottom: '1rem' }}>
|
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.7rem', letterSpacing: '0.15em', marginBottom: '1rem' }}>
|
||||||
RECENT TEAM ACTIVITY
|
RECENT TEAM ACTIVITY
|
||||||
</div>
|
</div>
|
||||||
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}>
|
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '2rem', textAlign: 'center', fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.8rem' }}>
|
||||||
{MOCK_STAFF_POSTS.slice(0, 4).map((post, idx) => (
|
No recent activity.
|
||||||
<div
|
|
||||||
key={post.id}
|
|
||||||
style={{
|
|
||||||
padding: '0.85rem 1.25rem',
|
|
||||||
borderBottom: idx < 3 ? '1px solid var(--color-border)' : 'none',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: '1rem', marginBottom: '0.3rem', flexWrap: 'wrap' }}>
|
|
||||||
<span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.78rem' }}>
|
|
||||||
{post.authorName}
|
|
||||||
<span style={{ color: 'var(--color-text-muted)', marginLeft: '0.4rem', fontSize: '0.65rem' }}>[{post.authorRole}]</span>
|
|
||||||
</span>
|
|
||||||
<span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.7rem' }}>
|
|
||||||
{new Date(post.createdAt).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.82rem', lineHeight: 1.7 }}>
|
|
||||||
{post.content}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { MOCK_EVENTS, MOCK_POLLS } from '../../data/mockData';
|
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { formatDateTime } from '../../utils/format';
|
import { formatDateTime } from '../../utils/format';
|
||||||
import type { EventPost, EventType, Poll, UserRole } from '../../types';
|
import type { EventPost, EventType, Poll, UserRole } from '../../types';
|
||||||
@@ -247,8 +246,8 @@ function EventCard({
|
|||||||
|
|
||||||
export default function IntranetEvents() {
|
export default function IntranetEvents() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [events, setEvents] = useState<EventPost[]>(MOCK_EVENTS);
|
const [events, setEvents] = useState<EventPost[]>([]);
|
||||||
const [polls, setPolls] = useState<Poll[]>(MOCK_POLLS);
|
const [polls, setPolls] = useState<Poll[]>([]);
|
||||||
const [showCreateForm, setShowCreateForm] = useState(false);
|
const [showCreateForm, setShowCreateForm] = useState(false);
|
||||||
|
|
||||||
// Form state
|
// Form state
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { MOCK_STAFF_POSTS } from '../../data/mockData';
|
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { formatDateTime } from '../../utils/format';
|
import { formatDateTime } from '../../utils/format';
|
||||||
import type { StaffPost, UserRole } from '../../types';
|
import type { StaffPost, UserRole } from '../../types';
|
||||||
@@ -68,7 +67,7 @@ function FeedPost({ post }: { post: StaffPost }) {
|
|||||||
|
|
||||||
export default function IntranetFeed() {
|
export default function IntranetFeed() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [posts, setPosts] = useState<StaffPost[]>(MOCK_STAFF_POSTS);
|
const [posts, setPosts] = useState<StaffPost[]>([]);
|
||||||
const [content, setContent] = useState('');
|
const [content, setContent] = useState('');
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
const [posting, setPosting] = useState(false);
|
const [posting, setPosting] = useState(false);
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { useState, useMemo, useCallback } from 'react';
|
import { useState, useMemo, useCallback } from 'react';
|
||||||
import { MOCK_THREADS, MOCK_REPLIES } from '../../data/mockData';
|
|
||||||
import { formatDateTime } from '../../utils/format';
|
import { formatDateTime } from '../../utils/format';
|
||||||
import type { ForumThread, ForumReply } from '../../types';
|
import type { ForumThread, ForumReply } from '../../types';
|
||||||
|
|
||||||
export default function IntranetModeration() {
|
export default function IntranetModeration() {
|
||||||
const [threads, setThreads] = useState<ForumThread[]>(MOCK_THREADS);
|
const [threads, setThreads] = useState<ForumThread[]>([]);
|
||||||
const [replies, setReplies] = useState<ForumReply[]>(MOCK_REPLIES);
|
const [replies, setReplies] = useState<ForumReply[]>([]);
|
||||||
const [selectedThreadId, setSelectedThreadId] = useState<string | null>(null);
|
const [selectedThreadId, setSelectedThreadId] = useState<string | null>(null);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [activeTab, setActiveTab] = useState<'threads' | 'replies'>('threads');
|
const [activeTab, setActiveTab] = useState<'threads' | 'replies'>('threads');
|
||||||
|
|||||||
@@ -1,28 +1,15 @@
|
|||||||
import { useState, useMemo, useCallback } from 'react';
|
import { useState, useMemo, useCallback } from 'react';
|
||||||
import { MOCK_USERS, MOCK_THREADS, MOCK_BUGS } from '../../data/mockData';
|
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { formatDate } from '../../utils/format';
|
import { formatDate } from '../../utils/format';
|
||||||
import type { User, UserRole } from '../../types';
|
import type { User, UserRole } from '../../types';
|
||||||
|
|
||||||
export default function IntranetUsers() {
|
export default function IntranetUsers() {
|
||||||
const { user: currentUser } = useAuth();
|
const { user: currentUser } = useAuth();
|
||||||
const [users, setUsers] = useState<User[]>(MOCK_USERS);
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [roleFilter, setRoleFilter] = useState<UserRole | 'all'>('all');
|
const [roleFilter, setRoleFilter] = useState<UserRole | 'all'>('all');
|
||||||
const [confirmAction, setConfirmAction] = useState<{ userId: string; action: 'promote' | 'ban' | 'unban' } | null>(null);
|
const [confirmAction, setConfirmAction] = useState<{ userId: string; action: 'promote' | 'ban' | 'unban' } | null>(null);
|
||||||
|
|
||||||
const threadCounts = useMemo(() => {
|
|
||||||
const map: Record<string, number> = {};
|
|
||||||
MOCK_THREADS.forEach((t) => { map[t.authorId] = (map[t.authorId] ?? 0) + 1; });
|
|
||||||
return map;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const bugCounts = useMemo(() => {
|
|
||||||
const map: Record<string, number> = {};
|
|
||||||
MOCK_BUGS.forEach((b) => { map[b.submittedById] = (map[b.submittedById] ?? 0) + 1; });
|
|
||||||
return map;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
return users.filter((u) => {
|
return users.filter((u) => {
|
||||||
const matchSearch = !search.trim() || u.username.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase());
|
const matchSearch = !search.trim() || u.username.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase());
|
||||||
@@ -130,8 +117,8 @@ export default function IntranetUsers() {
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-text-muted)', whiteSpace: 'nowrap' }}>{formatDate(u.createdAt)}</td>
|
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-text-muted)', whiteSpace: 'nowrap' }}>{formatDate(u.createdAt)}</td>
|
||||||
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-green)', textAlign: 'center' }}>{threadCounts[u.id] ?? 0}</td>
|
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-green)', textAlign: 'center' }}>0</td>
|
||||||
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-green)', textAlign: 'center' }}>{bugCounts[u.id] ?? 0}</td>
|
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-green)', textAlign: 'center' }}>0</td>
|
||||||
<td style={{ padding: '0.7rem 0.75rem' }}>
|
<td style={{ padding: '0.7rem 0.75rem' }}>
|
||||||
{u.isBanned ? (
|
{u.isBanned ? (
|
||||||
<span className="badge badge-critical">Banned</span>
|
<span className="badge badge-critical">Banned</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user