-
-
Plugins
-
- {plugins.filter((p) => p.enabled).length} of {plugins.length} enabled
+
Plugins
+
+
+
+
Coming in P3
+
+ Plugin management (install, enable/disable, configure) is planned for the P3.2
+ milestone. The plugin API endpoints are not yet available.
-
- {loadError && (
-
void fetchPlugins()} />
- )}
-
- {actionError && setActionError(null)} />}
-
- {loading && Loading plugins...
}
-
- {!loading && plugins.length === 0 && (
- No plugins installed.
- )}
-
- {!loading && plugins.length > 0 && (
-
- {plugins.map((plugin) => (
-
void handleToggle(p)}
- onUninstall={(p) => void handleUninstall(p)}
- />
- ))}
-
- )}
-
- {dependencyWarning && (
- void confirmDisable()}
- onCancel={() => setDependencyWarning(null)}
- />
- )}
-
- {settingsPlugin && (
- setSettingsPlugin(null)}
- onSave={(settings) => void handleSaveSettings(settings)}
- />
- )}
)
diff --git a/src/app/admin/users/page.test.tsx b/src/app/admin/users/page.test.tsx
index 0bb4060..6904682 100644
--- a/src/app/admin/users/page.test.tsx
+++ b/src/app/admin/users/page.test.tsx
@@ -1,9 +1,9 @@
/**
- * Tests for admin user management page.
+ * Tests for admin user management page (P3 placeholder).
*/
import { describe, it, expect, vi } from 'vitest'
-import { render, screen, waitFor } from '@testing-library/react'
+import { render, screen } from '@testing-library/react'
import { axe } from 'vitest-axe'
import AdminUsersPage from './page'
@@ -50,61 +50,20 @@ vi.mock('@/hooks/use-auth', () => {
return { useAuth: () => mockAuth }
})
-vi.mock('@/hooks/use-toast', () => ({
- useToast: () => ({ toast: vi.fn(), dismiss: vi.fn() }),
-}))
-
describe('AdminUsersPage', () => {
it('renders user management heading', () => {
render(
)
expect(screen.getByRole('heading', { name: /user management/i })).toBeInTheDocument()
})
- it('renders user list from API', async () => {
- render(
)
- await waitFor(() => {
- expect(screen.getByText('Jay Admin')).toBeInTheDocument()
- })
- expect(screen.getByText('Alex Moderator')).toBeInTheDocument()
- expect(screen.getByText('Sam Member')).toBeInTheDocument()
- })
-
- it('shows user roles', async () => {
- render(
)
- await waitFor(() => {
- expect(screen.getByText('admin')).toBeInTheDocument()
- })
- expect(screen.getByText('moderator')).toBeInTheDocument()
- })
-
- it('shows banned status', async () => {
- render(
)
- await waitFor(() => {
- expect(screen.getByText('Morgan Banned')).toBeInTheDocument()
- })
- // Morgan should show as banned
- expect(screen.getByText('Banned')).toBeInTheDocument()
- })
-
- it('shows cross-community ban warning', async () => {
- render(
)
- await waitFor(() => {
- expect(screen.getByText(/banned from 2 other communities/i)).toBeInTheDocument()
- })
- })
-
- it('shows ban/unban buttons', async () => {
+ it('shows coming in P3 message', () => {
render(
)
- await waitFor(() => {
- expect(screen.getAllByRole('button', { name: /ban/i }).length).toBeGreaterThan(0)
- })
+ expect(screen.getByRole('heading', { name: /coming in p3/i })).toBeInTheDocument()
+ expect(screen.getByText(/planned for the p3\.2 milestone/i)).toBeInTheDocument()
})
it('passes axe accessibility check', async () => {
const { container } = render(
)
- await waitFor(() => {
- expect(screen.getByText('Jay Admin')).toBeInTheDocument()
- })
const results = await axe(container)
expect(results).toHaveNoViolations()
})
diff --git a/src/app/admin/users/page.tsx b/src/app/admin/users/page.tsx
index d38288c..326c526 100644
--- a/src/app/admin/users/page.tsx
+++ b/src/app/admin/users/page.tsx
@@ -2,110 +2,27 @@
* Admin user management page.
* URL: /admin/users
* User list with ban controls and cross-community ban warnings.
+ * Backend endpoint not yet implemented (planned for P3.2).
* @see specs/prd-web.md Section M11
*/
-'use client'
-
-import { useState, useEffect, useCallback } from 'react'
+import { Users } from '@phosphor-icons/react/dist/ssr'
import { AdminLayout } from '@/components/admin/admin-layout'
-import { ErrorAlert } from '@/components/error-alert'
-import { UserCard } from '@/components/admin/users/user-card'
-import { getAdminUsers, banUser, unbanUser } from '@/lib/api/client'
-import type { AdminUser } from '@/lib/api/types'
-import { useAuth } from '@/hooks/use-auth'
-import { useToast } from '@/hooks/use-toast'
export default function AdminUsersPage() {
- const { getAccessToken } = useAuth()
- const { toast } = useToast()
- const [users, setUsers] = useState
([])
- const [loading, setLoading] = useState(true)
- const [loadError, setLoadError] = useState(null)
- const [actionError, setActionError] = useState(null)
-
- const fetchUsers = useCallback(async () => {
- setLoadError(null)
- try {
- const response = await getAdminUsers(getAccessToken() ?? '')
- setUsers(response.users)
- } catch {
- setLoadError('Failed to load users. The API may be unreachable.')
- } finally {
- setLoading(false)
- }
- }, [getAccessToken])
-
- useEffect(() => {
- void fetchUsers()
- }, [fetchUsers])
-
- const handleBan = async (did: string) => {
- setActionError(null)
- try {
- await banUser(did, 'Banned by admin', getAccessToken() ?? '')
- setUsers((prev) =>
- prev.map((u) =>
- u.did === did
- ? {
- ...u,
- isBanned: true,
- bannedAt: new Date().toISOString(),
- banReason: 'Banned by admin',
- }
- : u
- )
- )
- toast({ title: 'User banned' })
- } catch {
- setActionError('Failed to ban user. Please try again.')
- }
- }
-
- const handleUnban = async (did: string) => {
- setActionError(null)
- try {
- await unbanUser(did, getAccessToken() ?? '')
- setUsers((prev) =>
- prev.map((u) =>
- u.did === did ? { ...u, isBanned: false, bannedAt: null, banReason: null } : u
- )
- )
- toast({ title: 'User unbanned' })
- } catch {
- setActionError('Failed to unban user. Please try again.')
- }
- }
-
return (
User management
- {loadError && (
-
void fetchUsers()} />
- )}
-
- {actionError && setActionError(null)} />}
-
- {loading && Loading users...
}
-
- {!loading && users.length === 0 && (
- No users found.
- )}
-
- {!loading && users.length > 0 && (
-
- {users.map((user) => (
- void handleBan(did)}
- onUnban={(did) => void handleUnban(did)}
- />
- ))}
-
- )}
+
+
+
Coming in P3
+
+ User management (search, role assignment, ban controls) is planned for the P3.2
+ milestone. The admin API endpoint is not yet available.
+
+
)