beautify: modal registered user component

This commit is contained in:
DeathKaioken 2025-10-22 20:28:02 +02:00
parent 6fa4f02fb2
commit 9f5da2c43d

View File

@ -4,7 +4,7 @@ import React, { useMemo, useState } from 'react'
import { UsersIcon } from '@heroicons/react/24/outline'
type UserType = 'personal' | 'company'
type UserStatus = 'active' | 'pending' | 'blocked'
type UserStatus = 'active' | 'inactive' | 'pending' | 'blocked' // CHANGED: add inactive
export interface RegisteredUser {
id: string | number
@ -64,6 +64,7 @@ const allDummyUsers = buildDummyAll()
function statusBadgeClass(s: UserStatus) {
switch (s) {
case 'active': return 'bg-green-100 text-green-800'
case 'inactive': return 'bg-gray-100 text-gray-800' // NEW
case 'pending': return 'bg-amber-100 text-amber-800'
case 'blocked': return 'bg-rose-100 text-rose-800'
default: return 'bg-slate-100 text-slate-800'
@ -98,17 +99,28 @@ function exportCsv(rows: RegisteredUser[]) {
}
export default function RegisteredUserList({ users, loading }: Props) {
// Main widget rows (latest 5)
const sorted = useMemo(() => {
const data = (users && users.length > 0 ? users : baseUsers).slice()
return data.sort((a, b) => new Date(b.registeredAt).getTime() - new Date(a.registeredAt).getTime())
// Normalize backend shape to local RegisteredUser shape (type/status/registeredAt)
const normalizedUsers = useMemo<RegisteredUser[]>(() => {
if (!users || users.length === 0) return []
return users.map((u: any) => ({
...u,
userType: u.userType ?? u.type ?? 'personal',
status: (u.status ?? 'inactive') as UserStatus, // treat null/undefined as inactive
registeredAt: u.registeredAt ?? u.createdAt ?? new Date().toISOString(),
}))
}, [users])
// Main widget rows (latest 5) - use normalized when provided, else dummy
const sorted = useMemo(() => {
const data = (normalizedUsers.length > 0 ? normalizedUsers : baseUsers).slice()
return data.sort((a, b) => new Date(b.registeredAt).getTime() - new Date(a.registeredAt).getTime())
}, [normalizedUsers])
const rows = sorted.slice(0, 5)
// NEW: total registered count for badge (from provided users or dummy full list)
// Total badge: prefer normalized list length, else dummy all
const totalRegistered = useMemo(() => {
return users && users.length ? users.length : allDummyUsers.length
}, [users])
return normalizedUsers.length ? normalizedUsers.length : allDummyUsers.length
}, [normalizedUsers])
// Modal state
const [open, setOpen] = useState(false)
@ -118,11 +130,11 @@ export default function RegisteredUserList({ users, loading }: Props) {
const [page, setPage] = useState(1)
const pageSize = 10
// Full dataset for modal (dummy for now)
// Full dataset for modal
const allRows = useMemo(() => {
const data = users && users.length ? users : allDummyUsers
const data = normalizedUsers.length ? normalizedUsers : allDummyUsers
return data.sort((a, b) => new Date(b.registeredAt).getTime() - new Date(a.registeredAt).getTime())
}, [users])
}, [normalizedUsers])
const filtered = useMemo(() => {
return allRows.filter(r => {
@ -130,11 +142,7 @@ export default function RegisteredUserList({ users, loading }: Props) {
if (statusFilter !== 'all' && r.status !== statusFilter) return false
if (!query.trim()) return true
const q = query.toLowerCase()
return (
r.name.toLowerCase().includes(q) ||
r.email.toLowerCase().includes(q)
// CHANGED: remove refCode match (not provided by backend)
)
return r.name.toLowerCase().includes(q) || r.email.toLowerCase().includes(q)
})
}, [allRows, query, typeFilter, statusFilter])
@ -297,6 +305,7 @@ export default function RegisteredUserList({ users, loading }: Props) {
>
<option value="all">All Status</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option> {/* NEW */}
<option value="pending">Pending</option>
<option value="blocked">Blocked</option>
</select>