106 lines
3.8 KiB
TypeScript
106 lines
3.8 KiB
TypeScript
"use client";
|
|
import React from 'react';
|
|
|
|
interface SkeletonProps {
|
|
className?: string;
|
|
}
|
|
|
|
export const Skeleton = ({ className }: SkeletonProps) => {
|
|
return (
|
|
<div
|
|
className={`bg-medical-gray-100 animate-pulse rounded-2xl relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_2s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/20 before:to-transparent ${className}`}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export const ProductCardSkeleton = () => {
|
|
return (
|
|
<div className="bg-white rounded-[2.5rem] p-6 border border-medical-gray-50 shadow-sm flex flex-col h-full">
|
|
{/* Image Area */}
|
|
<Skeleton className="w-full aspect-square mb-6 rounded-[2rem]" />
|
|
|
|
{/* Category Tag */}
|
|
<Skeleton className="w-20 h-4 mb-4 rounded-full" />
|
|
|
|
{/* Title */}
|
|
<Skeleton className="w-full h-8 mb-2 rounded-lg" />
|
|
<Skeleton className="w-2/3 h-8 mb-4 rounded-lg" />
|
|
|
|
{/* Symptoms */}
|
|
<div className="flex gap-2 mb-6">
|
|
<Skeleton className="w-16 h-6 rounded-full" />
|
|
<Skeleton className="w-12 h-6 rounded-full" />
|
|
</div>
|
|
|
|
<div className="mt-auto pt-6 border-t border-medical-gray-50 flex items-center justify-between">
|
|
<Skeleton className="w-24 h-8 rounded-lg" />
|
|
<Skeleton className="w-12 h-12 rounded-2xl" />
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const ProductListSkeleton = () => {
|
|
return (
|
|
<div className="bg-white rounded-2xl p-3 border border-medical-gray-100 shadow-xs flex items-center gap-3">
|
|
<Skeleton className="w-24 h-24 rounded-xl flex-shrink-0" />
|
|
<div className="flex-1 flex flex-col justify-between self-stretch py-0.5 min-w-0">
|
|
<div className="space-y-1.5">
|
|
<Skeleton className="w-16 h-3 rounded-full" />
|
|
<Skeleton className="w-4/5 h-4 rounded-md" />
|
|
<Skeleton className="w-1/2 h-3 rounded-md" />
|
|
</div>
|
|
<div className="flex items-center justify-between pt-2 border-t border-medical-gray-50">
|
|
<Skeleton className="w-20 h-4 rounded-md" />
|
|
<Skeleton className="w-16 h-7 rounded-lg" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const PetProfileSkeleton = () => {
|
|
return (
|
|
<div className="bg-white rounded-[3rem] p-10 shadow-2xl border border-medical-gray-50">
|
|
<div className="flex flex-col md:flex-row items-center gap-10 mb-12">
|
|
<Skeleton className="w-40 h-40 rounded-[2.5rem]" />
|
|
<div className="flex-1 w-full md:w-auto text-center md:text-right">
|
|
<Skeleton className="w-32 h-10 mb-4 mx-auto md:mx-0" />
|
|
<Skeleton className="w-48 h-6 mb-6 mx-auto md:mx-0" />
|
|
<div className="flex flex-wrap gap-3 justify-center md:justify-start">
|
|
<Skeleton className="w-24 h-5 rounded-full" />
|
|
<Skeleton className="w-24 h-5 rounded-full" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
|
{[1, 2, 3, 4].map(i => (
|
|
<div key={i} className="bg-medical-gray-50 p-6 rounded-3xl">
|
|
<Skeleton className="w-20 h-4 mb-4 mx-auto" />
|
|
<Skeleton className="w-12 h-8 mx-auto" />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const OrderRowSkeleton = () => {
|
|
return (
|
|
<div className="flex items-center gap-6 p-6 border-b border-medical-gray-100 last:border-0">
|
|
<Skeleton className="w-16 h-16 rounded-2xl flex-shrink-0" />
|
|
<div className="flex-1">
|
|
<div className="flex justify-between items-start mb-2">
|
|
<Skeleton className="w-40 h-6" />
|
|
<Skeleton className="w-20 h-4" />
|
|
</div>
|
|
<div className="flex gap-4">
|
|
<Skeleton className="w-32 h-4" />
|
|
<Skeleton className="w-16 h-4" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|