refactor(ticket): update ticket detail skeleton loaders

This commit is contained in:
2026-07-10 10:42:40 +05:30
parent 8727963c54
commit 9720546455
2 changed files with 125 additions and 91 deletions

View File

@@ -1,85 +1,71 @@
import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { Card, CardContent, CardHeader } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton'; import { Skeleton } from '@/components/ui/skeleton';
import { Timeline, TimelineItem } from '@/components/ui/timeline';
function TimelineEntrySkeleton({
index,
isLast,
}: {
index: number;
isLast: boolean;
}) {
return (
<TimelineItem
layout="left"
isLast={isLast}
opposite={
<div className="space-y-2">
<Skeleton className="ml-auto h-4 w-16" />
<Skeleton className="ml-auto h-3 w-12" />
</div>
}
marker={<Skeleton className="size-4 rounded-full" />}
>
<div
className={
index === 0
? 'rounded-lg border border-dashed border-primary/25 bg-primary/5 px-4 py-3.5'
: 'rounded-lg border bg-card p-4'
}
>
{index === 0 ? <Skeleton className="h-5 w-28 rounded-lg" /> : null}
<Skeleton className={index === 0 ? 'mt-3 h-4 w-44' : 'h-4 w-44'} />
{index === 0 ? (
<Skeleton className="mt-2 h-3 w-full max-w-md" />
) : (
<>
<div className="mt-3 flex items-center gap-3">
<Skeleton className="size-9 rounded-full" />
<div className="min-w-0 flex-1 space-y-2">
<Skeleton className="h-4 w-36" />
<Skeleton className="h-3 w-48 max-w-full" />
</div>
</div>
<Skeleton className="mt-3 h-16 w-full rounded-lg" />
</>
)}
</div>
</TimelineItem>
);
}
export function TicketClassContentSkeleton() { export function TicketClassContentSkeleton() {
return ( return (
<div className="space-y-5" aria-label="Loading defect class details"> <div className="space-y-4" aria-label="Loading defect class details">
<Card> <div className="flex items-center gap-2">
<CardHeader className="sm:grid-cols-[1fr_auto]"> <Skeleton className="size-5 rounded-lg" />
<Skeleton className="h-5 w-36" /> <Skeleton className="h-5 w-56 max-w-full" />
<Skeleton className="h-3 w-32 sm:col-start-2 sm:row-start-1" /> </div>
</CardHeader>
<CardContent className="space-y-5">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
{Array.from({ length: 2 }).map((_, index) => (
<div key={index} className="space-y-1">
<Skeleton className="h-3 w-20" />
<Skeleton className="h-4 w-36" />
</div>
))}
</div>
<div className="space-y-2">
<Skeleton className="h-3 w-24" />
<div className="rounded-lg border bg-muted/15 px-4 py-3">
<Skeleton className="h-4 w-full" />
<Skeleton className="mt-2 h-4 w-3/4" />
</div>
</div>
</CardContent>
</Card>
<Card> <Timeline>
<CardHeader> {Array.from({ length: 3 }).map((_, index) => (
<Skeleton className="h-5 w-40" /> <TimelineEntrySkeleton
</CardHeader> key={index}
<CardContent className="grid grid-cols-1 gap-4 lg:grid-cols-2"> index={index}
<Skeleton className="aspect-video w-full rounded-lg" /> isLast={index === 2}
<Skeleton className="aspect-video w-full rounded-lg" /> />
</CardContent> ))}
</Card> </Timeline>
<Card>
<CardHeader>
<Skeleton className="h-5 w-32" />
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
{Array.from({ length: 5 }).map((_, index) => (
<div key={index} className="space-y-2 rounded-lg border p-2">
<Skeleton className="aspect-4/3 w-full rounded-lg" />
<Skeleton className="h-3 w-16" />
</div>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="flex items-center gap-2">
<Skeleton className="size-5 rounded-lg" />
<Skeleton className="h-5 w-56" />
</div>
</CardHeader>
<CardContent>
{Array.from({ length: 3 }).map((_, index) => (
<div key={index} className="relative flex gap-4 pb-8 last:pb-0">
{index < 2 ? (
<span className="absolute top-6 left-2.75 h-[calc(100%-10px)] w-px bg-border" />
) : null}
<Skeleton className="relative z-10 mt-0.5 size-6 shrink-0 rounded-full" />
<div className="min-w-0 flex-1 space-y-3">
<div className="flex flex-wrap items-center gap-3">
<Skeleton className="h-4 w-44" />
<Skeleton className="h-3 w-28" />
</div>
<Skeleton className="h-3 w-56" />
<Skeleton className="h-12 w-full" />
</div>
</div>
))}
</CardContent>
</Card>
</div> </div>
); );
} }

View File

@@ -1,11 +1,29 @@
import { Card, CardContent, CardHeader } from '@/components/ui/card'; import {
Card,
CardAction,
CardContent,
CardHeader,
} from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton'; import { Skeleton } from '@/components/ui/skeleton';
function OverviewSkeletonField() { function OverviewMetaSkeletonField({ className }: { className?: string }) {
return ( return (
<div className="space-y-2"> <div className={`flex items-center gap-3 ${className ?? ''}`}>
<Skeleton className="h-3 w-24" /> <Skeleton className="size-5 shrink-0 rounded-lg" />
<Skeleton className="h-4 w-32" /> <div className="min-w-0 space-y-2">
<Skeleton className="h-3 w-24" />
<Skeleton className="h-4 w-32 max-w-full" />
</div>
</div>
);
}
function SummarySkeletonCard() {
return (
<div className="rounded-lg bg-muted/40 p-4">
<Skeleton className="h-7 w-10" />
<Skeleton className="mt-3 h-3 w-24 max-w-full" />
<Skeleton className="mt-2 h-3 w-16" />
</div> </div>
); );
} }
@@ -27,15 +45,45 @@ export function TicketOverviewHeaderSkeleton() {
export function TicketOverviewCardSkeleton() { export function TicketOverviewCardSkeleton() {
return ( return (
<Card aria-label="Loading ticket overview"> <div className="space-y-5" aria-label="Loading ticket overview">
<CardHeader> <Card>
<Skeleton className="h-4 w-20" /> <CardContent className="grid gap-4 py-4 sm:grid-cols-3 sm:divide-x">
</CardHeader> <OverviewMetaSkeletonField className="sm:pr-4" />
<CardContent className="grid grid-cols-2 gap-x-4 gap-y-6 md:grid-cols-4"> <OverviewMetaSkeletonField className="sm:px-4" />
{Array.from({ length: 4 }).map((_, index) => ( <OverviewMetaSkeletonField className="sm:pl-4" />
<OverviewSkeletonField key={index} /> </CardContent>
))} </Card>
</CardContent>
</Card> <Card>
<CardHeader>
<div className="flex items-center gap-2">
<Skeleton className="size-5 rounded-lg" />
<Skeleton className="h-5 w-40" />
</div>
<CardAction>
<Skeleton className="h-9 w-28" />
</CardAction>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-2 gap-3 lg:grid-cols-3 xl:grid-cols-6">
{Array.from({ length: 6 }).map((_, index) => (
<SummarySkeletonCard key={index} />
))}
</div>
<div className="grid gap-3 rounded-lg bg-muted/35 px-4 py-3 sm:grid-cols-3">
{Array.from({ length: 3 }).map((_, index) => (
<div
key={index}
className="flex items-center justify-center gap-2"
>
<Skeleton className="size-4 rounded-lg" />
<Skeleton className="h-4 w-24" />
</div>
))}
</div>
</CardContent>
</Card>
</div>
); );
} }