@@ -6,6 +6,7 @@ import Link from "next/link";
66import { defaultAvatar } from "@/public/assets/images" ;
77import type { ServicesProjectDetail } from "@/lib/server/services-projects-cached" ;
88import { fetchApiJson } from "@/utils/api-fetch" ;
9+ import { cn } from "@/lib/utils" ;
910import { motion } from "framer-motion" ;
1011import { Crown } from "lucide-react" ;
1112
@@ -16,6 +17,7 @@ import {
1617 DialogTitle ,
1718} from "@/components/ui/dialog" ;
1819import DefaultAvatar from "@/components/DefaultAvatar" ;
20+ import { VisuallyHidden } from "@/components/ui/visuallyHidden" ;
1921import {
2022 Tooltip ,
2123 TooltipContent ,
@@ -90,12 +92,135 @@ function getImageUrl(mainImage?: string) {
9092 return defaultAvatar ;
9193}
9294
95+ function SkeletonBone ( { className } : { className ?: string } ) {
96+ return (
97+ < div
98+ className = { cn (
99+ "animate-pulse rounded bg-gray-200 dark:bg-gray-700" ,
100+ className ,
101+ ) }
102+ />
103+ ) ;
104+ }
105+
93106function ServiceDetailSkeleton ( ) {
94107 return (
95- < div className = "animate-pulse space-y-6 px-4 sm:px-6 pb-6" >
96- < div className = "h-[200px] sm:h-[300px] w-full rounded-xl bg-gray-200 dark:bg-gray-800" />
97- < div className = "h-40 rounded-lg bg-gray-200 dark:bg-gray-800" />
98- </ div >
108+ < >
109+ < DialogHeader
110+ id = "service-detail-header"
111+ className = "flex-shrink-0 px-4 sm:px-6 pt-4 pb-2"
112+ >
113+ < DialogTitle >
114+ < VisuallyHidden > Loading project</ VisuallyHidden >
115+ </ DialogTitle >
116+ < div className = "flex justify-center" >
117+ < SkeletonBone className = "h-7 w-48 sm:h-8 sm:w-64" />
118+ </ div >
119+ </ DialogHeader >
120+
121+ < div className = "flex-1 overflow-y-auto px-4 sm:px-6 pb-6" >
122+ < div className = "relative mb-6 h-[200px] sm:h-[300px] w-full overflow-hidden rounded-xl bg-gray-200 shadow-lg dark:bg-gray-800" >
123+ < div className = "absolute left-3 top-3" >
124+ < SkeletonBone className = "h-7 w-24 rounded-full bg-gray-300/80 dark:bg-gray-600/80" />
125+ </ div >
126+ < div className = "absolute inset-0 flex flex-col justify-end p-4 sm:p-6" >
127+ < SkeletonBone className = "mb-2 h-7 w-3/5 max-w-md bg-gray-300/90 dark:bg-gray-600/90 sm:h-9" />
128+ < SkeletonBone className = "h-4 w-4/5 max-w-lg bg-gray-300/70 dark:bg-gray-600/70 sm:h-5" />
129+ </ div >
130+ </ div >
131+
132+ < section id = "service-detail-info" className = "space-y-6" >
133+ < div className = "rounded-lg bg-gray-50 p-4 dark:bg-gray-800/50 sm:p-6" >
134+ < div className = "mb-4 flex items-center gap-3" >
135+ < SkeletonBone className = "h-6 w-6 shrink-0 rounded-full sm:h-8 sm:w-8" />
136+ < SkeletonBone className = "h-6 w-44 sm:h-7 sm:w-52" />
137+ </ div >
138+
139+ < div className = "grid gap-6 lg:grid-cols-2" >
140+ < div className = "space-y-4" >
141+ < div >
142+ < SkeletonBone className = "mb-2 h-5 w-48" />
143+ < div className = "space-y-2" >
144+ < SkeletonBone className = "h-4 w-full" />
145+ < SkeletonBone className = "h-4 w-full" />
146+ < SkeletonBone className = "h-4 w-5/6" />
147+ < SkeletonBone className = "h-4 w-4/5" />
148+ </ div >
149+ </ div >
150+
151+ < div >
152+ < SkeletonBone className = "mb-2 h-5 w-28" />
153+ < div className = "space-y-2" >
154+ < div className = "flex items-start gap-2" >
155+ < SkeletonBone className = "mt-1.5 h-2 w-2 shrink-0 rounded-full" />
156+ < SkeletonBone className = "h-4 w-3/4" />
157+ </ div >
158+ < div className = "flex items-start gap-2" >
159+ < SkeletonBone className = "mt-1.5 h-2 w-2 shrink-0 rounded-full" />
160+ < SkeletonBone className = "h-4 w-2/3" />
161+ </ div >
162+ < div className = "flex items-start gap-2" >
163+ < SkeletonBone className = "mt-1.5 h-2 w-2 shrink-0 rounded-full" />
164+ < SkeletonBone className = "h-4 w-4/5" />
165+ </ div >
166+ </ div >
167+ </ div >
168+
169+ < div >
170+ < SkeletonBone className = "mb-3 h-5 w-32" />
171+ < div className = "flex flex-wrap gap-2 sm:gap-3" >
172+ < SkeletonBone className = "h-9 w-24 rounded-lg" />
173+ < SkeletonBone className = "h-9 w-28 rounded-lg" />
174+ < SkeletonBone className = "h-9 w-20 rounded-lg" />
175+ </ div >
176+ </ div >
177+ </ div >
178+
179+ < div className = "space-y-4" >
180+ < div >
181+ < SkeletonBone className = "mb-2 h-5 w-24" />
182+ < div className = "flex flex-wrap gap-2" >
183+ < SkeletonBone className = "h-6 w-16 rounded-full" />
184+ < SkeletonBone className = "h-6 w-20 rounded-full" />
185+ < SkeletonBone className = "h-6 w-14 rounded-full" />
186+ < SkeletonBone className = "h-6 w-24 rounded-full" />
187+ < SkeletonBone className = "h-6 w-16 rounded-full" />
188+ </ div >
189+ </ div >
190+
191+ < div className = "grid gap-4 sm:grid-cols-2" >
192+ < div >
193+ < SkeletonBone className = "mb-2 h-5 w-20" />
194+ < SkeletonBone className = "h-4 w-36" />
195+ </ div >
196+ < div >
197+ < SkeletonBone className = "mb-2 h-5 w-16" />
198+ < SkeletonBone className = "h-4 w-36" />
199+ </ div >
200+ </ div >
201+ </ div >
202+ </ div >
203+ </ div >
204+
205+ < div
206+ id = "service-detail-team"
207+ className = "rounded-lg bg-gray-50 p-4 dark:bg-gray-800/50 sm:p-6"
208+ >
209+ < div className = "mb-4 flex items-center gap-3" >
210+ < SkeletonBone className = "h-6 w-6 shrink-0 rounded-full sm:h-8 sm:w-8" />
211+ < SkeletonBone className = "h-6 w-36 sm:h-7 sm:w-40" />
212+ </ div >
213+ < div className = "flex flex-wrap gap-3 sm:flex-nowrap sm:overflow-x-auto sm:pb-2" >
214+ < SkeletonBone className = "h-12 w-12 shrink-0 rounded-full" />
215+ < SkeletonBone className = "h-10 w-10 shrink-0 rounded-full" />
216+ < SkeletonBone className = "h-10 w-10 shrink-0 rounded-full" />
217+ < SkeletonBone className = "h-10 w-10 shrink-0 rounded-full" />
218+ < SkeletonBone className = "h-10 w-10 shrink-0 rounded-full" />
219+ </ div >
220+ </ div >
221+ </ section >
222+ </ div >
223+ </ >
99224 ) ;
100225}
101226
@@ -390,7 +515,10 @@ export const ServiceDetailModal = ({
390515 if ( ! open ) onClose ( ) ;
391516 } }
392517 >
393- < DialogContent className = "max-w-full w-[95vw] sm:w-[90vw] lg:w-[80vw] h-[90vh] max-h-[90vh] p-0 flex flex-col overflow-hidden" >
518+ < DialogContent
519+ aria-describedby = { undefined }
520+ className = "max-w-full w-[95vw] sm:w-[90vw] lg:w-[80vw] h-[90vh] max-h-[90vh] p-0 flex flex-col overflow-hidden"
521+ >
394522 { projectId ? (
395523 < Suspense fallback = { < ServiceDetailSkeleton /> } >
396524 < ServiceDetailBody projectId = { projectId } />
0 commit comments