From 59d353453c73f85e9f8ac9ea5e62253c515973e2 Mon Sep 17 00:00:00 2001 From: dat Date: Mon, 17 Mar 2025 14:58:20 +0700 Subject: [PATCH 1/2] Topcoder Admin App - Misc Bug Fix --- src/apps/admin/src/config/index.config.ts | 2 +- .../ChallengeFilters/ChallengeFilters.tsx | 2 +- .../ChallengeUserFilters.tsx | 2 +- .../common/Pagination/Pagination.tsx | 111 ++++-------------- .../services/challenge-management.service.ts | 4 + .../admin/src/lib/services/user.service.ts | 4 + src/apps/admin/src/lib/utils/api.ts | 2 + 7 files changed, 39 insertions(+), 88 deletions(-) diff --git a/src/apps/admin/src/config/index.config.ts b/src/apps/admin/src/config/index.config.ts index deca60768..702400aac 100644 --- a/src/apps/admin/src/config/index.config.ts +++ b/src/apps/admin/src/config/index.config.ts @@ -4,7 +4,7 @@ import { InputSelectOption } from '~/libs/ui/lib/components/form/form-groups/for /** * Common config for ui. */ -const EMPTY_OPTION: InputSelectOption = { label: '', value: '' } +const EMPTY_OPTION: InputSelectOption = { label: 'all', value: '' } export const USER_STATUS_SELECT_OPTIONS: InputSelectOption[] = [ EMPTY_OPTION, { label: 'active', value: 'active' }, diff --git a/src/apps/admin/src/lib/components/ChallengeFilters/ChallengeFilters.tsx b/src/apps/admin/src/lib/components/ChallengeFilters/ChallengeFilters.tsx index 49378b70d..ef4b27ed7 100644 --- a/src/apps/admin/src/lib/components/ChallengeFilters/ChallengeFilters.tsx +++ b/src/apps/admin/src/lib/components/ChallengeFilters/ChallengeFilters.tsx @@ -54,7 +54,7 @@ const ChallengeFilters: FC = props => { label: item, value: item, }) - const emptyOption: InputSelectOption = { label: '', value: '' } + const emptyOption: InputSelectOption = { label: 'All', value: '' } return { challengeStatusOptions: [ diff --git a/src/apps/admin/src/lib/components/ChallengeUserFilters/ChallengeUserFilters.tsx b/src/apps/admin/src/lib/components/ChallengeUserFilters/ChallengeUserFilters.tsx index fd22499ca..ca3affa43 100644 --- a/src/apps/admin/src/lib/components/ChallengeUserFilters/ChallengeUserFilters.tsx +++ b/src/apps/admin/src/lib/components/ChallengeUserFilters/ChallengeUserFilters.tsx @@ -39,7 +39,7 @@ const ChallengeUserFilters: FC = props => { label: item.name, value: item.id, }) - const emptyOption: InputSelectOption = { label: '', value: '' } + const emptyOption: InputSelectOption = { label: 'All', value: '' } const o: InputSelectOption | undefined = _.filter(resourceRoles, { name: DEFAULT_ROLE_FILTER_NAME, }) diff --git a/src/apps/admin/src/lib/components/common/Pagination/Pagination.tsx b/src/apps/admin/src/lib/components/common/Pagination/Pagination.tsx index 90726857a..477b8e50d 100644 --- a/src/apps/admin/src/lib/components/common/Pagination/Pagination.tsx +++ b/src/apps/admin/src/lib/components/common/Pagination/Pagination.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useEffect, useMemo, useState } from 'react' +import { FC, useEffect, useMemo, useState } from 'react' import { useWindowSize, WindowSize } from '~/libs/shared' import { Button, IconOutline } from '~/libs/ui' @@ -19,98 +19,39 @@ const Pagination: FC = (props: PaginationProps) => { const MAX_PAGE_DISPLAY = 5 const MAX_PAGE_MOBILE_DISPLAY = 3 const { width: screenWidth }: WindowSize = useWindowSize() + const isMobile = useMemo(() => screenWidth < 767, [screenWidth]) const [displayPages, setDisplayPages] = useState([]) - const mobiledisplayPages = useMemo(() => { - if (displayPages.length <= MAX_PAGE_MOBILE_DISPLAY) { - return displayPages - } - - const LEFT = MAX_PAGE_MOBILE_DISPLAY % 2 === 0 ? MAX_PAGE_MOBILE_DISPLAY / 2 : (MAX_PAGE_MOBILE_DISPLAY + 1) / 2 - const RIGHT = MAX_PAGE_MOBILE_DISPLAY - LEFT - const index = displayPages.indexOf(props.page) - let start = Math.max(0, index - LEFT) - let end = Math.min(index + RIGHT, displayPages.length) - if (end - start < MAX_PAGE_MOBILE_DISPLAY) { - start = Math.min(Math.max(0, end - MAX_PAGE_MOBILE_DISPLAY), start) - } - - if (end - start < MAX_PAGE_MOBILE_DISPLAY) { - end = Math.min(Math.max(start + MAX_PAGE_MOBILE_DISPLAY, end), displayPages.length) - } - - return displayPages.slice(start, end) - }, [displayPages, props.page, screenWidth]) // eslint-disable-line react-hooks/exhaustive-deps, max-len -- unneccessary dependency: screenWidth - - const createDisplayPages = useCallback((reset: boolean) => { - // eslint-disable-next-line complexity - setDisplayPages(oldDisplayPages => { - let expectedDisplayPages = oldDisplayPages - if (expectedDisplayPages.includes(props.page) && !reset) { - return [...expectedDisplayPages] - } - - if (reset) { - expectedDisplayPages = [] - } - - // Initial - if (expectedDisplayPages.length === 0) { - const pages = [] - for ( - let i = props.page - MAX_PAGE_DISPLAY + 1; - i <= props.page + MAX_PAGE_DISPLAY; - i++ - ) { - if (i >= 1 && i <= totalPages && pages.length < MAX_PAGE_DISPLAY) { - pages.push(i) - } - } - - return pages - } - // Go next - if (props.page > expectedDisplayPages[expectedDisplayPages.length - 1]) { - const pages = [] - for ( - let i = props.page - MAX_PAGE_DISPLAY + 1; - i <= props.page; - i++ - ) { - if (i >= 1) { - pages.push(i) - } + useEffect(() => { + let pages: number[] = [] + if (props.page) { + pages = [props.page] + const maxDisplayPage = isMobile + ? MAX_PAGE_MOBILE_DISPLAY + : MAX_PAGE_DISPLAY + let haveAvailablePage = true + let i = 1 + while (haveAvailablePage && pages.length < maxDisplayPage) { + const prevPage = props.page - i + haveAvailablePage = false + if (prevPage > 0) { + pages = [prevPage, ...pages] + haveAvailablePage = true } - return pages - } - - // Go previous - if (props.page < expectedDisplayPages[0] && props.page >= 1) { - const pages = [] - for ( - let i = props.page; - i < props.page + MAX_PAGE_DISPLAY; - i++ - ) { - pages.push(i) + const nextPage = props.page + i + if (nextPage <= totalPages) { + pages = [...pages, nextPage] + haveAvailablePage = true } - return pages + i += 1 } + } - return [...expectedDisplayPages] - }) - }, [props.page, totalPages]) - - useEffect(() => { - createDisplayPages(true) - }, [totalPages]) // eslint-disable-line react-hooks/exhaustive-deps - - useEffect(() => { - createDisplayPages(false) - }, [props.page]) // eslint-disable-line react-hooks/exhaustive-deps + setDisplayPages(pages) + }, [totalPages, props.page, isMobile]) // eslint-disable-line react-hooks/exhaustive-deps const createHandlePageClick = (p: number) => () => { if (p === 0 || p > totalPages || p === props.page) { @@ -148,7 +89,7 @@ const Pagination: FC = (props: PaginationProps) => { className={styles.previous} />
- {(screenWidth < 767 ? mobiledisplayPages : displayPages).map(i => ( + {displayPages.map(i => (