Skip to content

Commit

Permalink
admin/users add username/email search (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
lefnire committed Mar 23, 2022
1 parent 323b079 commit e76fd13
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 13 deletions.
12 changes: 6 additions & 6 deletions apps/api/src/modules/accounts/accounts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ export default class AccountsService {
async getUsers({
page = 1,
pageSize = 10,
username,
email,
search = '',
sortBy = UserSortField.CreatedAt,
sortDirection = SortDirection.Ascending,
}: UsersQuerystring): Promise<UserAccounts> {
Expand All @@ -199,10 +198,11 @@ export default class AccountsService {
const query = UserAccountModel.query()

// Find payer
const userIdentifier = username || email
const field = username ? 'username' : 'email'
if (userIdentifier) {
query.where(field, 'ilike', userIdentifier)
if (search?.length > 0) {
const ilikeSearch = `%${search}%`
query
.where('email', 'ilike', ilikeSearch)
.orWhere('username', 'ilike', ilikeSearch)
}

const { results: users, total } = await query
Expand Down
34 changes: 33 additions & 1 deletion apps/web/src/pages/admin/users/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
UserSortField,
} from '@algomart/schemas'
import { RefreshIcon } from '@heroicons/react/outline'
import debounce from 'lodash.debounce'
import { GetServerSideProps } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { useCallback, useMemo, useState } from 'react'
Expand All @@ -15,6 +16,7 @@ import Pagination from '@/components/pagination/pagination'
import Panel from '@/components/panel'
import Table from '@/components/table'
import { ColumnDefinitionType } from '@/components/table'
import TextInput from '@/components/text-input/text-input'
import usePagination from '@/hooks/use-pagination'
import AdminLayout from '@/layouts/admin-layout'
import adminService from '@/services/admin-service'
Expand Down Expand Up @@ -63,6 +65,8 @@ function CheckRole({ user, role }: CheckRoleProps) {

export default function AdminUsersPage() {
const { t, lang } = useTranslation('admin')
const [search, setSearch] = useState('')
const [searchDebounced, setSearchDebounced] = useState('')

const { page, setPage, handleTableHeaderClick, sortBy, sortDirection } =
usePagination<UserSortField>(1, UserSortField.CreatedAt)
Expand All @@ -81,6 +85,7 @@ export default function AdminUsersPage() {
sortBy,
sortDirection,
pageSize: USERS_PER_PAGE,
search: searchDebounced,
})
const { data, isValidating } = useAuthApi<UserAccounts>(
`${urls.api.v1.admin.getUsers}?${qp}`
Expand All @@ -91,11 +96,27 @@ export default function AdminUsersPage() {
const renderClaims = useCallback(
({ item }: RendererProps) =>
rolesArray.map((role) => (
<CheckRole key={role.id} user={item} role={role} />
<CheckRole
key={`${item.externalId}-${role.id}`}
user={item}
role={role}
/>
)),
[]
)

const submitSearch = useCallback(
debounce((value) => {
setSearchDebounced(value)
}, 200),
[]
)

const handleSearchChange = useCallback((value) => {
setSearch(value)
submitSearch(value)
}, [])

const columns: ColumnDefinitionType<UserAccount>[] = [
{
key: 'username',
Expand All @@ -121,6 +142,16 @@ export default function AdminUsersPage() {
},
]

const searchBox = (
<div className={'m-5'}>
<TextInput
handleChange={handleSearchChange}
placeholder={'Search by email or username'}
value={search}
/>
</div>
)

const footer = (
<>
<div>
Expand Down Expand Up @@ -151,6 +182,7 @@ export default function AdminUsersPage() {
}
footer={footer}
>
{searchBox}
<div className="overflow-x-auto">
<Table<UserAccount>
columns={columns}
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/services/admin-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AdminPermissions,
FirebaseClaim,
Payment,
UpdatePayment,
WirePayment,
Expand All @@ -18,7 +19,7 @@ export interface AdminAPI {
updatePayment(paymentId: string, json: UpdatePayment): Promise<Payment | null>
updateClaims(
userExternalId: string,
key: any,
key: FirebaseClaim,
value: boolean
): Promise<AdminPermissions>
}
Expand Down Expand Up @@ -97,7 +98,7 @@ export class AdminService implements AdminAPI {

async updateClaims(
userExternalId: string,
key: string,
key: FirebaseClaim,
value: boolean
): Promise<AdminPermissions> {
return await this.http
Expand Down
4 changes: 3 additions & 1 deletion apps/web/src/utils/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PaymentsQuerystring,
PublishedPacksQuery,
SortOptions,
UsersQuerystring,
} from '@algomart/schemas'
import { Translate } from 'next-translate'
import { stringify } from 'query-string'
Expand Down Expand Up @@ -128,11 +129,12 @@ export const getSelectSortingOptions = (t: Translate) => {
/**
* Build a search parameter string to filter payments
*/
export const getUsersFilterQuery = (query: any) => {
export const getUsersFilterQuery = (query: UsersQuerystring) => {
return stringify({
page: query.page,
pageSize: query.pageSize || PAGE_SIZE,
sortBy: query.sortBy,
sortDirection: query.sortDirection,
search: query.search,
})
}
1 change: 0 additions & 1 deletion apps/web/src/utils/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export const urls = {
transactions: '/admin/transactions',
transaction: '/admin/transactions/:transactionId',
users: '/admin/users',
user: '/admin/users/:userId',
},

api: {
Expand Down
3 changes: 1 addition & 2 deletions libs/schemas/src/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ export enum UserSortField {
export const UsersQuerystringSchema = Type.Intersect([
PaginationSchema,
Type.Object({
username: Type.Optional(Type.String()),
email: Type.Optional(Type.String()),
search: Type.Optional(Type.String()),
sortBy: Type.Optional(
Type.Enum(UserSortField, { default: UserSortField.CreatedAt })
),
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"knex": "1.0.4",
"ky": "0.30.0",
"leva": "0.9.23",
"lodash.debounce": "^4.0.8",
"lodash.get": "4.4.2",
"markdown-to-jsx": "7.1.7",
"next": "12.1.0",
Expand Down

0 comments on commit e76fd13

Please sign in to comment.