mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-06 02:48:28 +00:00
feat(web): lazy-load review tabs and adjust profile review pagination
- Skill review tabs only fetch data when activated (not all 3 on mount) - Tabs component now supports controlled mode via value prop - Profile review page size reduced from 20 to 10 - Profile review pagination bar always visible regardless of page count
This commit is contained in:
parent
f6c72030b6
commit
9cdd200bc2
4 changed files with 18 additions and 16 deletions
|
|
@ -17,10 +17,10 @@ async function getReviewList(status: string, namespaceId?: number, page = 0, siz
|
|||
/**
|
||||
* Exposes the review list query used by dashboard moderation views.
|
||||
*/
|
||||
export function useReviewList(status: string, namespaceId?: number, page = 0, size = 20) {
|
||||
export function useReviewList(status: string, namespaceId?: number, page = 0, size = 20, enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: ['reviews', status, namespaceId, page, size],
|
||||
queryFn: () => getReviewList(status, namespaceId, page, size),
|
||||
enabled: namespaceId === undefined || namespaceId > 0,
|
||||
enabled: enabled && (namespaceId === undefined || namespaceId > 0),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ type ReviewItem = {
|
|||
reviewedAt: string | null
|
||||
}
|
||||
|
||||
const PAGE_SIZE = 20
|
||||
const PAGE_SIZE = 10
|
||||
|
||||
export function ProfileReviewTable() {
|
||||
const { t, i18n } = useTranslation()
|
||||
|
|
@ -163,10 +163,6 @@ export function ProfileReviewTable() {
|
|||
}
|
||||
|
||||
function renderPagination(status: ReviewStatus, totalElements: number, totalPages: number) {
|
||||
if (totalPages <= 1) {
|
||||
return null
|
||||
}
|
||||
|
||||
const currentPage = pages[status]
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export function ReviewsPage() {
|
|||
APPROVED: 0,
|
||||
REJECTED: 0,
|
||||
})
|
||||
const [activeStatus, setActiveStatus] = useState<ReviewStatus>('PENDING')
|
||||
|
||||
const isSkillAdmin = hasRole('SKILL_ADMIN') || hasRole('SUPER_ADMIN')
|
||||
const isUserAdmin = hasRole('USER_ADMIN') || hasRole('SUPER_ADMIN')
|
||||
|
|
@ -44,9 +45,9 @@ export function ReviewsPage() {
|
|||
// Determine default top-level tab
|
||||
const defaultType = isSkillAdmin ? 'skill' : 'profile'
|
||||
|
||||
const pendingQuery = useReviewList('PENDING', undefined, pages.PENDING, PAGE_SIZE)
|
||||
const approvedQuery = useReviewList('APPROVED', undefined, pages.APPROVED, PAGE_SIZE)
|
||||
const rejectedQuery = useReviewList('REJECTED', undefined, pages.REJECTED, PAGE_SIZE)
|
||||
const pendingQuery = useReviewList('PENDING', undefined, pages.PENDING, PAGE_SIZE, activeStatus === 'PENDING')
|
||||
const approvedQuery = useReviewList('APPROVED', undefined, pages.APPROVED, PAGE_SIZE, activeStatus === 'APPROVED')
|
||||
const rejectedQuery = useReviewList('REJECTED', undefined, pages.REJECTED, PAGE_SIZE, activeStatus === 'REJECTED')
|
||||
|
||||
const formatDate = (dateString: string) => formatLocalDateTime(dateString, i18n.language)
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ export function ReviewsPage() {
|
|||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
<Tabs defaultValue="PENDING">
|
||||
<Tabs value={activeStatus} onValueChange={(v) => setActiveStatus(v as ReviewStatus)}>
|
||||
<TabsList className="gap-4 rounded-xl border-b-0 bg-muted/70 p-1 shadow-none">
|
||||
<TabsTrigger
|
||||
value="PENDING"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import * as React from 'react'
|
|||
import { cn } from '@/shared/lib/utils'
|
||||
|
||||
interface TabsProps {
|
||||
defaultValue: string
|
||||
defaultValue?: string
|
||||
value?: string
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
onValueChange?: (value: string) => void
|
||||
|
|
@ -15,13 +16,17 @@ interface TabsContextValue {
|
|||
|
||||
const TabsContext = React.createContext<TabsContextValue | undefined>(undefined)
|
||||
|
||||
export function Tabs({ defaultValue, children, className, onValueChange }: TabsProps) {
|
||||
const [value, setValue] = React.useState(defaultValue)
|
||||
export function Tabs({ defaultValue, value: controlledValue, children, className, onValueChange }: TabsProps) {
|
||||
const [internalValue, setInternalValue] = React.useState(defaultValue ?? '')
|
||||
const isControlled = controlledValue !== undefined
|
||||
const value = isControlled ? controlledValue : internalValue
|
||||
|
||||
const handleValueChange = React.useCallback((nextValue: string) => {
|
||||
setValue(nextValue)
|
||||
if (!isControlled) {
|
||||
setInternalValue(nextValue)
|
||||
}
|
||||
onValueChange?.(nextValue)
|
||||
}, [onValueChange])
|
||||
}, [isControlled, onValueChange])
|
||||
|
||||
return (
|
||||
<TabsContext.Provider value={{ value, setValue: handleValueChange }}>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue