@@ -15,7 +15,7 @@ import type { ServicesProjectsPage } from "@/lib/server/services-projects-cached
1515import { fetchApiJson } from "@/utils/api-fetch" ;
1616
1717import type { ServiceProject } from "../ui/ServicesServiceCard" ;
18- import { ServicesServiceCard } from "../ui" ;
18+ import { ServicesGridSkeleton , ServicesServiceCard , servicesProjectsGridClass } from "../ui" ;
1919
2020const pagePromises = new Map < string , Promise < ServicesProjectsPage > > ( ) ;
2121const pageMetaCache = new Map < string , ServicesProjectsPage [ "pagination" ] > ( ) ;
@@ -105,17 +105,17 @@ function loadPage(
105105 return promise ;
106106}
107107
108- function ServicesGridSkeleton ( ) {
109- return (
110- < div className = "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4" >
111- { Array . from ( { length : 4 } ) . map ( ( _ , index ) => (
112- < div
113- key = { index }
114- className = "aspect-square w-full animate-pulse rounded-xl bg-white/5"
115- />
116- ) ) }
117- </ div >
118- ) ;
108+ function resolveSkeletonCount (
109+ page : number ,
110+ pageSize : number ,
111+ total : number ,
112+ ) {
113+ if ( total <= 0 ) {
114+ return pageSize ;
115+ }
116+
117+ const remaining = total - ( page - 1 ) * pageSize ;
118+ return Math . min ( pageSize , Math . max ( 1 , remaining ) ) ;
119119}
120120
121121function ServicesProjectsGrid ( {
@@ -136,10 +136,7 @@ function ServicesProjectsGrid({
136136 }
137137
138138 return (
139- < div
140- key = { page }
141- className = "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"
142- >
139+ < div key = { page } className = { servicesProjectsGridClass } >
143140 { projects . map ( ( project , index ) => (
144141 < div
145142 key = { project . id }
@@ -227,13 +224,13 @@ function ServicesPaginationSlot({
227224 onPageChange : ( page : number ) => void ;
228225} ) {
229226 if ( totalPages <= 1 ) {
230- return null ;
227+ return < div className = "mt-6 min-h-[4.5rem]" aria-hidden = "true" /> ;
231228 }
232229
233230 const currentPage = Math . min ( page , totalPages ) ;
234231
235232 return (
236- < div id = "services-pagination" className = "text-white" >
233+ < div id = "services-pagination" className = "mt-6 min-h-[4.5rem] text-white" >
237234 < DefaultPagination
238235 currentPage = { currentPage }
239236 totalPages = { totalPages }
@@ -263,7 +260,7 @@ export const ServicesTab = ({
263260 onServiceSelect,
264261} : Props ) => {
265262 const [ page , setPage ] = useState ( initialData . pagination . page ) ;
266- const [ isPending , startTransition ] = useTransition ( ) ;
263+ const [ , startTransition ] = useTransition ( ) ;
267264
268265 rememberPagination (
269266 initialData . category as ServicesCategorySlug ,
@@ -279,6 +276,11 @@ export const ServicesTab = ({
279276 initialData ,
280277 ) ;
281278 const totalPages = Math . max ( 1 , activePagination . totalPages ) ;
279+ const skeletonCount = resolveSkeletonCount (
280+ page ,
281+ pageSize ,
282+ activePagination . total ,
283+ ) ;
282284
283285 useMarketingPageUrl ( page , ( nextPage ) => {
284286 startTransition ( ( ) => {
@@ -319,13 +321,11 @@ export const ServicesTab = ({
319321 } ) }
320322 </ div >
321323
322- < div
323- id = "services-grid"
324- className = { `transition-opacity duration-200 ${
325- isPending ? "opacity-60" : "opacity-100"
326- } `}
327- >
328- < Suspense key = { `${ category } :${ page } ` } fallback = { < ServicesGridSkeleton /> } >
324+ < div id = "services-grid" >
325+ < Suspense
326+ key = { `${ category } :${ page } ` }
327+ fallback = { < ServicesGridSkeleton count = { skeletonCount } /> }
328+ >
329329 < ServicesTabGrid
330330 category = { category }
331331 page = { page }
0 commit comments