import { useMemo, useState } from 'react'; import { EmbeddableShell } from '../components/shared/EmbeddableShell'; import { UserEntityListView } from '../components/shared/list/UserEntityListView'; import { InlineRowActions } from '../components/shared/list/InlineRowActions'; import { ButtonPrimary, LinkButtonPrimary } from '../components/shared/buttons'; import { Modal } from '../components/shared/Modal'; import { ApiErrorPanel } from '../components/shared/ApiErrorPanel'; import { getWpApi } from '../api'; import type { Column } from '../components/shared/DataTable'; import { formatPostDate } from '../lib/formatPostDate'; import type { SikshyaReactConfig, WpRestUser } from '../types'; import { term, termLower } from '../lib/terminology'; import { __ } from '../lib/i18n'; type Variant = 'students' | 'instructors'; export function WpUserListPage(props: { config: SikshyaReactConfig; title: string; subtitle: string; variant: Variant; embedded?: boolean; }) { const { config, title, subtitle, variant, embedded } = props; const adminBase = config.adminUrl.replace(/\/?$/, '/'); const roleSlug = variant === 'students' ? 'sikshya_student' : 'sikshya_instructor'; const termStudent = termLower(config, 'student'); const termInstructor = termLower(config, 'instructor'); const termStudents = term(config, 'students'); const termInstructors = term(config, 'instructors'); const newUrl = `${adminBase}user-new.php`; const [createOpen, setCreateOpen] = useState(false); const [creating, setCreating] = useState(false); const [createErr, setCreateErr] = useState(null); const [refreshSeq, setRefreshSeq] = useState(0); const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const [displayName, setDisplayName] = useState(''); const [password, setPassword] = useState(''); const columns: Column[] = useMemo( () => [ { id: 'id', header: 'ID', sortKey: 'id', alwaysVisible: true, cellClassName: 'whitespace-nowrap tabular-nums text-slate-600 dark:text-slate-400', render: (u) => u.id, }, { id: 'name', header: 'Name', sortKey: 'name', render: (u) => { const editUrl = `${adminBase}user-edit.php?user_id=${u.id}`; return (
{u.name}
{u.slug}
); }, }, { id: 'email', header: 'Email', sortKey: 'email', cellClassName: 'text-slate-600 dark:text-slate-400', render: (u) => u.email || '—', }, { id: 'registered', header: 'Registered', sortKey: 'registered_date', cellClassName: 'whitespace-nowrap text-slate-600 dark:text-slate-400', render: (u) => formatPostDate(u.registered_date), }, ], [adminBase] ); async function createUser() { setCreateErr(null); setCreating(true); try { const uname = username.trim(); const em = email.trim(); const nm = displayName.trim(); const pw = password.trim(); // WordPress requires username, email and password for `/wp/v2/users` create. if (!uname || !em || !pw) { throw new Error(__('Username, email, and password are required.', 'sikshya')); } const created = await getWpApi().post<{ id: number }>('/users', { username: uname, email: em, password: pw, name: nm || undefined, roles: [roleSlug], }); // Some WP installs apply a default role on creation; enforce the exact intended role. if (created && typeof created.id === 'number' && created.id > 0) { await getWpApi().put(`/users/${created.id}`, { roles: [roleSlug] }); } setCreateOpen(false); setUsername(''); setEmail(''); setDisplayName(''); setPassword(''); setRefreshSeq((n) => n + 1); } catch (e) { setCreateErr(e); } finally { setCreating(false); } } return ( setCreateOpen(true)}> + Add {variant === 'students' ? termStudent : termInstructor} Add in WordPress } > (creating ? null : setCreateOpen(false))} size="md" footer={
void createUser()} disabled={creating}> {creating ? __('Creating…', 'sikshya') : __('Create', 'sikshya')}
} > {createErr ? : null}

Requires the current admin user to have permission to create WordPress users.

setCreateOpen(true)}> + Add {variant === 'students' ? termStudent : termInstructor} } skeletonHeaders={['ID', 'Name', 'Email', 'Registered']} />
); }