"use client"
import React, { useState } from 'react'
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Grid2X2, List } from "lucide-react"
export interface ContentItem {
id: string | number
[key: string]: unknown
}
export type ViewMode = 'grid' | 'list'
export interface ContentGridProps {
items: ContentItem[]
renderCard: (item: ContentItem, viewMode: ViewMode) => React.ReactNode
defaultViewMode?: ViewMode
gridColumns?: 'auto' | 1 | 2 | 3 | 4 | 5 | 6
className?: string
onViewModeChange?: (mode: ViewMode) => void
}
export function ContentGrid({
items,
renderCard,
defaultViewMode = 'grid',
gridColumns = 'auto',
className,
onViewModeChange,
}: ContentGridProps) {
const [viewMode, setViewMode] = useState<ViewMode>(defaultViewMode)
const handleViewModeChange = (mode: ViewMode) => {
setViewMode(mode)
onViewModeChange?.(mode)
}
const getGridClasses = () => {
if (viewMode !== 'grid') return ''
const baseClasses = 'grid gap-4 transition-all duration-200'
if (gridColumns === 'auto') {
return `${baseClasses} grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4`
}
const colClasses = {
1: 'grid-cols-1',
2: 'grid-cols-1 md:grid-cols-2',
3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
5: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5',
6: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 3xl:grid-cols-6'
}
return `${baseClasses} ${colClasses[gridColumns]}`
}
const getListClasses = () => {
if (viewMode !== 'list') return ''
return 'space-y-4 transition-all duration-200'
}
return (
<div className={cn("w-full space-y-4", className)}>
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold">
{items.length} {items.length === 1 ? 'item' : 'items'}
</h2>
<div className="flex border rounded-lg p-1 gap-1">
<Button
variant={viewMode === 'grid' ? 'default' : 'ghost'}
size="sm"
onClick={() => handleViewModeChange('grid')}
className="px-3"
>
<Grid2X2 className="h-4 w-4" />
</Button>
<Button
variant={viewMode === 'list' ? 'default' : 'ghost'}
size="sm"
onClick={() => handleViewModeChange('list')}
className="px-3"
>
<List className="h-4 w-4" />
</Button>
</div>
</div>
<div className={cn(
viewMode === 'grid' ? getGridClasses() : getListClasses()
)}>
{items.map(item =>
renderCard(item, viewMode)
)}
</div>
{items.length === 0 && (
<div className="text-center py-12">
<div className="text-muted-foreground">
No items to display.
</div>
</div>
)}
</div>
)
}