beautify: modal registered user component
This commit is contained in:
parent
6fa4f02fb2
commit
9f5da2c43d
@ -4,7 +4,7 @@ import React, { useMemo, useState } from 'react'
|
|||||||
import { UsersIcon } from '@heroicons/react/24/outline'
|
import { UsersIcon } from '@heroicons/react/24/outline'
|
||||||
|
|
||||||
type UserType = 'personal' | 'company'
|
type UserType = 'personal' | 'company'
|
||||||
type UserStatus = 'active' | 'pending' | 'blocked'
|
type UserStatus = 'active' | 'inactive' | 'pending' | 'blocked' // CHANGED: add inactive
|
||||||
|
|
||||||
export interface RegisteredUser {
|
export interface RegisteredUser {
|
||||||
id: string | number
|
id: string | number
|
||||||
@ -64,6 +64,7 @@ const allDummyUsers = buildDummyAll()
|
|||||||
function statusBadgeClass(s: UserStatus) {
|
function statusBadgeClass(s: UserStatus) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case 'active': return 'bg-green-100 text-green-800'
|
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 'pending': return 'bg-amber-100 text-amber-800'
|
||||||
case 'blocked': return 'bg-rose-100 text-rose-800'
|
case 'blocked': return 'bg-rose-100 text-rose-800'
|
||||||
default: return 'bg-slate-100 text-slate-800'
|
default: return 'bg-slate-100 text-slate-800'
|
||||||
@ -98,17 +99,28 @@ function exportCsv(rows: RegisteredUser[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function RegisteredUserList({ users, loading }: Props) {
|
export default function RegisteredUserList({ users, loading }: Props) {
|
||||||
// Main widget rows (latest 5)
|
// Normalize backend shape to local RegisteredUser shape (type/status/registeredAt)
|
||||||
const sorted = useMemo(() => {
|
const normalizedUsers = useMemo<RegisteredUser[]>(() => {
|
||||||
const data = (users && users.length > 0 ? users : baseUsers).slice()
|
if (!users || users.length === 0) return []
|
||||||
return data.sort((a, b) => new Date(b.registeredAt).getTime() - new Date(a.registeredAt).getTime())
|
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])
|
}, [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)
|
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(() => {
|
const totalRegistered = useMemo(() => {
|
||||||
return users && users.length ? users.length : allDummyUsers.length
|
return normalizedUsers.length ? normalizedUsers.length : allDummyUsers.length
|
||||||
}, [users])
|
}, [normalizedUsers])
|
||||||
|
|
||||||
// Modal state
|
// Modal state
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
@ -118,11 +130,11 @@ export default function RegisteredUserList({ users, loading }: Props) {
|
|||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const pageSize = 10
|
const pageSize = 10
|
||||||
|
|
||||||
// Full dataset for modal (dummy for now)
|
// Full dataset for modal
|
||||||
const allRows = useMemo(() => {
|
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())
|
return data.sort((a, b) => new Date(b.registeredAt).getTime() - new Date(a.registeredAt).getTime())
|
||||||
}, [users])
|
}, [normalizedUsers])
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
return allRows.filter(r => {
|
return allRows.filter(r => {
|
||||||
@ -130,11 +142,7 @@ export default function RegisteredUserList({ users, loading }: Props) {
|
|||||||
if (statusFilter !== 'all' && r.status !== statusFilter) return false
|
if (statusFilter !== 'all' && r.status !== statusFilter) return false
|
||||||
if (!query.trim()) return true
|
if (!query.trim()) return true
|
||||||
const q = query.toLowerCase()
|
const q = query.toLowerCase()
|
||||||
return (
|
return r.name.toLowerCase().includes(q) || r.email.toLowerCase().includes(q)
|
||||||
r.name.toLowerCase().includes(q) ||
|
|
||||||
r.email.toLowerCase().includes(q)
|
|
||||||
// CHANGED: remove refCode match (not provided by backend)
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}, [allRows, query, typeFilter, statusFilter])
|
}, [allRows, query, typeFilter, statusFilter])
|
||||||
|
|
||||||
@ -297,6 +305,7 @@ export default function RegisteredUserList({ users, loading }: Props) {
|
|||||||
>
|
>
|
||||||
<option value="all">All Status</option>
|
<option value="all">All Status</option>
|
||||||
<option value="active">Active</option>
|
<option value="active">Active</option>
|
||||||
|
<option value="inactive">Inactive</option> {/* NEW */}
|
||||||
<option value="pending">Pending</option>
|
<option value="pending">Pending</option>
|
||||||
<option value="blocked">Blocked</option>
|
<option value="blocked">Blocked</option>
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user