fix teacher, parent and admin pages

This commit is contained in:
root
2026-04-25 00:00:10 -04:00
parent 7fe34dde0d
commit 3e77fc92c7
275 changed files with 46412 additions and 3325 deletions
+261
View File
@@ -0,0 +1,261 @@
/**
* Roles & permissions admin (legacy CI rolepermission/*).
* Expected under `/api/v1/role-permission`.
*/
import { apiFetch } from './http'
const BASE = '/api/v1/role-permission'
function unwrapData<T>(body: T): T {
if (!body || typeof body !== 'object') return body
const maybeEnvelope = body as { data?: unknown }
return (maybeEnvelope.data as T | undefined) ?? body
}
export type RoleRow = {
id?: number | string
name?: string
slug?: string
description?: string
dashboard_route?: string
priority?: number
is_active?: number | string | boolean
user_count?: number
}
export type PermissionRow = {
id?: number | string
name?: string
description?: string
created_at?: string
updated_at?: string
}
export async function fetchRolesList(): Promise<{ roles?: RoleRow[] }> {
const body = await apiFetch<{ roles?: RoleRow[] } | { data?: { roles?: RoleRow[] } }>(`${BASE}/roles`)
return unwrapData(body)
}
export async function fetchPermissionsList(): Promise<{ permissions?: PermissionRow[] }> {
const body = await apiFetch<
{ permissions?: PermissionRow[] } | { data?: { permissions?: PermissionRow[] } }
>(`${BASE}/permissions`)
return unwrapData(body)
}
export type AssignUserRow = {
id?: number | string
account_id?: string
firstname?: string
lastname?: string
email?: string
roles?: string[]
}
export async function fetchUsersForAssign(params?: {
school_year?: string
semester?: string
page?: number
per_page?: number
}): Promise<{ users?: AssignUserRow[]; meta?: { current_page?: number; last_page?: number; total?: number; per_page?: number } }> {
const qs = new URLSearchParams()
if (params?.school_year) qs.set('school_year', params.school_year)
if (params?.semester) qs.set('semester', params.semester)
qs.set('per_page', String(params?.per_page ?? 200))
if (params?.page) qs.set('page', String(params.page))
qs.set('sort_by', 'lastname')
qs.set('sort_dir', 'asc')
const suffix = qs.toString() ? `?${qs}` : ''
const body = await apiFetch<
| {
users?: AssignUserRow[]
meta?: { current_page?: number; last_page?: number; total?: number; per_page?: number }
}
| {
data?: {
users?: AssignUserRow[]
meta?: { current_page?: number; last_page?: number; total?: number; per_page?: number }
}
}
>(
`${BASE}/users${suffix}`,
)
return unwrapData(body)
}
export async function fetchAllUsersForAssign(params?: {
school_year?: string
semester?: string
}): Promise<{ users: AssignUserRow[] }> {
const usersById = new Map<string, AssignUserRow>()
let page = 1
let lastPage = 1
do {
const response = await fetchUsersForAssign({
school_year: params?.school_year,
semester: params?.semester,
page,
per_page: 200,
})
for (const user of response.users ?? []) {
const key = String(user.id ?? '').trim()
if (key === '') {
continue
}
if (!usersById.has(key)) {
usersById.set(key, user)
}
}
lastPage = Number(response.meta?.last_page ?? page)
page += 1
} while (page <= lastPage)
return { users: [...usersById.values()] }
}
export async function saveUserRoles(payload: {
user_id: number | string
role_ids: (number | string)[]
}): Promise<{ ok?: boolean; message?: string }> {
const userId = encodeURIComponent(String(payload.user_id))
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/users/${userId}/roles`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ role_ids: payload.role_ids }),
},
)
return unwrapData(body)
}
export async function createRole(payload: Record<string, unknown>): Promise<{ ok?: boolean; message?: string }> {
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/roles`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
},
)
return unwrapData(body)
}
export async function updateRole(
roleId: number | string,
payload: Record<string, unknown>,
): Promise<{ ok?: boolean; message?: string }> {
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/roles/${encodeURIComponent(String(roleId))}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
},
)
return unwrapData(body)
}
export async function deleteRole(roleId: number | string): Promise<{ ok?: boolean }> {
const body = await apiFetch<{ ok?: boolean } | { data?: { ok?: boolean } }>(
`${BASE}/roles/${encodeURIComponent(String(roleId))}`,
{ method: 'DELETE' },
)
return unwrapData(body)
}
export async function fetchRole(roleId: number | string): Promise<{ role?: RoleRow }> {
const body = await apiFetch<{ role?: RoleRow } | { data?: { role?: RoleRow } }>(
`${BASE}/roles/${encodeURIComponent(String(roleId))}`,
)
return unwrapData(body)
}
export async function createPermission(payload: {
name: string
description?: string
}): Promise<{ ok?: boolean; message?: string }> {
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/permissions`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
},
)
return unwrapData(body)
}
export async function fetchPermission(
permissionId: number | string,
): Promise<{ permission?: PermissionRow }> {
const body = await apiFetch<{ permission?: PermissionRow } | { data?: { permission?: PermissionRow } }>(
`${BASE}/permissions/${encodeURIComponent(String(permissionId))}`,
)
return unwrapData(body)
}
export async function updatePermission(
permissionId: number | string,
payload: { name: string; description?: string },
): Promise<{ ok?: boolean; message?: string }> {
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/permissions/${encodeURIComponent(String(permissionId))}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
},
)
return unwrapData(body)
}
export type PermissionMatrixRow = {
id?: number | string
name?: string
}
export type ExistingPermissionFlags = {
can_create?: boolean
can_read?: boolean
can_update?: boolean
can_delete?: boolean
}
export async function fetchRolePermissionMatrix(roleId: number | string): Promise<{
roleId?: number | string
permissions?: PermissionMatrixRow[]
existing?: Record<string, ExistingPermissionFlags>
}> {
const body = await apiFetch<
| {
roleId?: number | string
permissions?: PermissionMatrixRow[]
existing?: Record<string, ExistingPermissionFlags>
}
| {
data?: {
roleId?: number | string
permissions?: PermissionMatrixRow[]
existing?: Record<string, ExistingPermissionFlags>
}
}
>(`${BASE}/roles/${encodeURIComponent(String(roleId))}/permissions`)
return unwrapData(body)
}
export async function saveRolePermissionMatrix(
roleId: number | string,
payload: Record<string, { create?: boolean; read?: boolean; update?: boolean; delete?: boolean }>,
): Promise<{ ok?: boolean; message?: string }> {
const body = await apiFetch<{ ok?: boolean; message?: string } | { data?: { ok?: boolean; message?: string } }>(
`${BASE}/roles/${encodeURIComponent(String(roleId))}/permissions`,
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ permissions: payload }),
},
)
return unwrapData(body)
}