first commit
This commit is contained in:
127
components/ui/LazyLoader.tsx
Normal file
127
components/ui/LazyLoader.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
'use client'
|
||||
|
||||
import { Suspense, lazy, ComponentType } from 'react'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
|
||||
interface LazyComponentProps {
|
||||
fallback?: React.ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
// Generic lazy loading wrapper
|
||||
export function createLazyComponent<T extends ComponentType<any>>(
|
||||
importFunction: () => Promise<{ default: T }>,
|
||||
fallback?: React.ReactNode
|
||||
) {
|
||||
const LazyComponent = lazy(importFunction)
|
||||
|
||||
return function LazyWrapper(props: React.ComponentProps<T> & LazyComponentProps) {
|
||||
const { fallback: customFallback, className, ...componentProps } = props
|
||||
|
||||
const defaultFallback = (
|
||||
<div className={className}>
|
||||
<Skeleton className="w-full h-64 rounded-lg" />
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<Suspense fallback={customFallback || defaultFallback}>
|
||||
<LazyComponent {...(componentProps as React.ComponentProps<T>)} />
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Product Grid Skeleton
|
||||
export function ProductGridSkeleton({ count = 8 }: { count?: number }) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
||||
{Array.from({ length: count }).map((_, i) => (
|
||||
<div key={i} className="space-y-3">
|
||||
<Skeleton className="w-full h-48 rounded-lg" />
|
||||
<Skeleton className="h-4 w-3/4" />
|
||||
<Skeleton className="h-4 w-1/2" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<Skeleton className="h-6 w-16" />
|
||||
<Skeleton className="h-6 w-20" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Chart Skeleton
|
||||
export function ChartSkeleton({ className }: { className?: string }) {
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className="space-y-4">
|
||||
<Skeleton className="h-6 w-32" />
|
||||
<Skeleton className="h-64 w-full rounded-lg" />
|
||||
<div className="flex space-x-4">
|
||||
<Skeleton className="h-4 w-16" />
|
||||
<Skeleton className="h-4 w-16" />
|
||||
<Skeleton className="h-4 w-16" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Dashboard Stats Skeleton
|
||||
export function DashboardStatsSkeleton() {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<div key={i} className="p-6 bg-white rounded-lg border space-y-2">
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-8 w-16" />
|
||||
<Skeleton className="h-3 w-20" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Table Skeleton
|
||||
export function TableSkeleton({ rows = 5, cols = 4 }: { rows?: number, cols?: number }) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Header */}
|
||||
<div className="flex space-x-4">
|
||||
{Array.from({ length: cols }).map((_, i) => (
|
||||
<Skeleton key={i} className="h-4 flex-1" />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Rows */}
|
||||
{Array.from({ length: rows }).map((_, rowIndex) => (
|
||||
<div key={rowIndex} className="flex space-x-4">
|
||||
{Array.from({ length: cols }).map((_, colIndex) => (
|
||||
<Skeleton key={colIndex} className="h-8 flex-1" />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Form Skeleton
|
||||
export function FormSkeleton() {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-32" />
|
||||
<Skeleton className="h-24 w-full" />
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<Skeleton className="h-10 w-24" />
|
||||
<Skeleton className="h-10 w-20" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user