feat: Add visual feedback and polish (Task 15)
- Implement toast notification system for success/error messages - Add loading states with skeleton loaders for async operations - Create smooth CSS transitions and animations - Enhance empty states with EmptyState component - Add loading.tsx files for Next.js loading states - Integrate toast notifications across all CRUD operations - Add fade-in and scale-in animations for better UX - Improve visual feedback for user actions
This commit is contained in:
76
components/SkeletonLoader.tsx
Normal file
76
components/SkeletonLoader.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
'use client'
|
||||
|
||||
interface SkeletonProps {
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function Skeleton({ className = '' }: SkeletonProps) {
|
||||
return (
|
||||
<div className={`animate-pulse bg-gray-200 rounded ${className}`} />
|
||||
)
|
||||
}
|
||||
|
||||
export function ListCardSkeleton() {
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-5 sm:p-6 min-h-[140px] sm:min-h-[160px]">
|
||||
<div className="flex items-start justify-between mb-4 gap-2">
|
||||
<div className="flex items-center gap-2 sm:gap-3 flex-1">
|
||||
<Skeleton className="w-3 h-3 sm:w-4 sm:h-4 rounded-full" />
|
||||
<Skeleton className="h-6 w-32 sm:w-40" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2.5 sm:space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-4 w-8" />
|
||||
</div>
|
||||
<Skeleton className="h-2 sm:h-2.5 w-full rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function ItemCardSkeleton() {
|
||||
return (
|
||||
<div className="bg-white rounded-lg border border-gray-200 p-4 sm:p-5">
|
||||
<div className="flex items-start gap-3 sm:gap-4">
|
||||
<Skeleton className="w-5 h-5 sm:w-6 sm:h-6 rounded-full flex-shrink-0 mt-0.5 sm:mt-1" />
|
||||
|
||||
<div className="flex-1 min-w-0 space-y-2">
|
||||
<Skeleton className="h-5 w-3/4" />
|
||||
<Skeleton className="h-4 w-full" />
|
||||
<Skeleton className="h-4 w-2/3" />
|
||||
|
||||
<div className="flex flex-wrap items-center gap-1.5 sm:gap-2 mt-2">
|
||||
<Skeleton className="h-6 w-16 rounded" />
|
||||
<Skeleton className="h-6 w-20 rounded" />
|
||||
<Skeleton className="h-6 w-24 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Skeleton className="w-5 h-5 rounded flex-shrink-0" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function ListDetailSkeleton() {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<ItemCardSkeleton />
|
||||
<ItemCardSkeleton />
|
||||
<ItemCardSkeleton />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function SearchResultsSkeleton() {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<Skeleton className="h-5 w-32" />
|
||||
<ItemCardSkeleton />
|
||||
<ItemCardSkeleton />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user