import { useState } from 'react'
import useSWR from 'swr'
import {
Badge,
Container,
Group,
Stack,
Text,
Title,
Paper,
Button,
ActionIcon,
TextInput,
Table,
Avatar,
Box,
Pagination,
ThemeIcon,
ScrollArea,
Tooltip,
} from '@mantine/core'
import { useMediaQuery } from '@mantine/hooks'
import { createFileRoute, useParams } from '@tanstack/react-router'
import {
TbPlus,
TbSearch,
TbUsers,
TbX,
TbMail,
TbPhone,
TbId,
TbBriefcase,
TbHome2,
TbCircleCheck,
TbCircleX,
} from 'react-icons/tb'
import { API_URLS } from '../config/api'
export const Route = createFileRoute('/apps/$appId/users/')({
component: UsersIndexPage,
})
interface APIUser {
id: string
name: string
nik: string
phone: string
email: string
isWithoutOTP: boolean
isActive: boolean
role: string
village: string
group: string
position?: string
}
const fetcher = (url: string) => fetch(url).then((res) => res.json())
function UsersIndexPage() {
const { appId } = useParams({ from: '/apps/$appId/users/' })
const [page, setPage] = useState(1)
const [search, setSearch] = useState('')
const [searchQuery, setSearchQuery] = useState('')
const isDesaPlus = appId === 'desa-plus'
const apiUrl = isDesaPlus ? API_URLS.getUsers(page, searchQuery) : null
const { data: response, error, isLoading } = useSWR(apiUrl, fetcher)
const users: APIUser[] = response?.data?.user || []
const handleSearchChange = (val: string) => {
setSearch(val)
if (val.length >= 3 || val.length === 0) {
setSearchQuery(val)
setPage(1)
}
}
const handleClearSearch = () => {
setSearch('')
setSearchQuery('')
setPage(1)
}
const getRoleColor = (role: string) => {
const r = role.toLowerCase()
if (r.includes('super')) return 'red'
if (r.includes('admin')) return 'brand-blue'
if (r.includes('developer')) return 'violet'
return 'gray'
}
const isMobile = useMediaQuery('(max-width: 768px)')
if (!isDesaPlus) {
return (
User Management
This feature is currently customized for Desa+. Other apps coming soon.
)
}
return (
User Management
{isLoading ? 'Loading users...' : `${response?.data?.total || 0} users registered in the Desa+ system`}
}
radius="md"
size="md"
>
Add User
}
size="md"
rightSection={
search ? (
) : null
}
value={search}
onChange={(e) => handleSearchChange(e.currentTarget.value)}
radius="md"
style={{ maxWidth: 500 }}
ml={40}
/>
{isLoading ? (
Loading user data...
) : error ? (
Failed to load data from API.
) : users.length === 0 ? (
No users match your criteria.
) : (
User & ID
Contact Detail
Organization
Role
Status
{users.map((user) => (
{user.name.charAt(0)}
{user.name}
{user.nik}
{user.email}
{user.phone}
{user.village}
{user.group} ยท {user.position || 'Staff'}
{user.role}
{user.isActive ? (
) : (
)}
{user.isActive ? 'ACTIVE' : 'INACTIVE'}
{user.isWithoutOTP && (
NO OTP
)}
))}
)}
{!isLoading && !error && response?.data?.totalPage > 0 && (
)}
)
}