@@ -5,7 +5,7 @@ import type { ImageType, AlbumType } from '~/types'
55import type { ImageListDataProps , ImageServerHandleProps } from '~/types/props'
66import { useSwrInfiniteServerHook } from '~/hooks/use-swr-infinite-server-hook'
77import { useSwrPageTotalServerHook } from '~/hooks/use-swr-page-total-server-hook'
8- import { ArrowDown10 , ScanSearch , Replace } from 'lucide-react'
8+ import { ArrowDown10 , Images , Replace , ScanSearch } from 'lucide-react'
99import { toast } from 'sonner'
1010import { useButtonStore } from '~/app/providers/button-store-providers'
1111import ImageEditSheet from '~/components/admin/list/image-edit-sheet'
@@ -48,6 +48,7 @@ import {
4848 PopoverContent ,
4949 PopoverTrigger ,
5050} from '~/components/ui/popover'
51+ import AdminEmptyState from '~/components/admin/empty-state'
5152import { RefreshCWIcon } from '~/components/icons/refresh-cw.tsx'
5253import { CircleChevronDownIcon } from '~/components/icons/circle-chevron-down.tsx'
5354import { AnimatedIconTrigger , mergeAnimatedTriggerProps } from '~/components/icons/animated-trigger'
@@ -106,6 +107,17 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
106107 }
107108 } , [ adminConfig ] )
108109
110+ useEffect ( ( ) => {
111+ setPageNum ( ( current ) => current === 1 ? current : 1 )
112+ } , [ album , showStatus , selectedCamera , selectedLens ] )
113+
114+ useEffect ( ( ) => {
115+ const totalPages = Math . max ( 1 , Math . ceil ( ( total ?? 0 ) / pageSize ) )
116+ if ( ! isLoading && ( total ?? 0 ) > 0 && pageNum > totalPages ) {
117+ setPageNum ( totalPages )
118+ }
119+ } , [ isLoading , pageNum , pageSize , total ] )
120+
109121 const updateImageShow = useCallback ( async ( id : string , show : number ) => {
110122 try {
111123 setUpdateShowLoading ( true )
@@ -166,6 +178,14 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
166178 }
167179 }
168180
181+ const hasActiveFilters = [ album , showStatus , selectedCamera , selectedLens ] . some (
182+ ( value ) => value !== '' && value !== 'all'
183+ )
184+ const imageCount = Array . isArray ( data ) ? data . length : 0
185+ const isCollectionEmpty = ! isLoading && imageCount === 0 && ( total ?? 0 ) === 0
186+ const isEmptyDatabase = isCollectionEmpty && ! hasActiveFilters
187+ const isFilteredEmpty = isCollectionEmpty && hasActiveFilters
188+
169189 return (
170190 < div className = "flex flex-col space-y-2 h-full flex-1" >
171191 < div className = "flex justify-between space-x-1" >
@@ -270,6 +290,7 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
270290 variant = "outline"
271291 size = "icon"
272292 aria-label = { t ( 'Button.batchDelete' ) }
293+ disabled = { isLoading || ( total ?? 0 ) === 0 }
273294 { ...mergeAnimatedTriggerProps ( {
274295 onClick : ( ) => setImageBatchDelete ( true )
275296 } , triggerProps ) }
@@ -386,7 +407,21 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
386407 </ div >
387408 </ div >
388409 < div className = "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" >
389- { Array . isArray ( data ) && data ?. map ( ( image : ImageType ) => (
410+ { isEmptyDatabase ? (
411+ < AdminEmptyState
412+ className = "col-span-full min-h-[22rem]"
413+ icon = { Images }
414+ title = { t ( 'List.emptyTitle' ) }
415+ description = { t ( 'List.emptyDescription' ) }
416+ />
417+ ) : isFilteredEmpty ? (
418+ < AdminEmptyState
419+ className = "col-span-full min-h-[22rem]"
420+ icon = { Images }
421+ title = { t ( 'List.filteredEmptyTitle' ) }
422+ description = { t ( 'List.filteredEmptyDescription' ) }
423+ />
424+ ) : Array . isArray ( data ) && data ?. map ( ( image : ImageType ) => (
390425 < Card key = { image . id } className = "flex flex-col h-72 show-up-motion items-center gap-0 py-0" >
391426 < div className = "flex h-12 justify-between w-full p-2 space-x-2" >
392427 < Badge variant = "secondary" aria-label = { t ( 'Words.album' ) } > { image . album_name } </ Badge >
0 commit comments