Files
pca-pijac/frontend/src/components/vendors/vendor-grid.tsx
Marko Marković b481531301 Extract vendor page subcomponents; structured Directus errors
Split the 316-line vendors index into VendorToolbar, VendorGrid,
VendorList, and PerPageSelector under components/vendors/. Page now
owns only search-param state and query orchestration.

Replace generic Error throws in lib/directus.ts with a DirectusError
class carrying status, statusText, collection, url, and parsed body.
Surface useLocalStorage read/write failures via console.warn instead
of swallowing them.
2026-04-23 21:52:15 +04:00

54 lines
1.8 KiB
TypeScript

import { Link } from '@tanstack/react-router'
import { Card, CardContent } from '~/components/ui/card'
import { Skeleton } from '~/components/ui/skeleton'
import { assetUrl } from '~/lib/directus'
import type { VendorListItem } from '~/lib/types'
import { truncateDescription } from './types'
type Props = {
vendors: VendorListItem[]
isLoading: boolean
perPage: number
}
export function VendorGrid({ vendors, isLoading, perPage }: Props) {
return (
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
{isLoading
? Array.from({ length: perPage }).map((_, k) => (
<Card key={k}>
<Skeleton className="h-40 rounded-none" />
<CardContent className="pt-4">
<Skeleton className="mb-2 h-6" />
<Skeleton className="mb-1 h-4" />
<Skeleton className="h-4" />
</CardContent>
</Card>
))
: vendors.map((v) => (
<Card key={v.id} className="group relative hover:border-primary/40">
<img
src={assetUrl(v.logo, 'logo-card')}
alt={v.name}
width={250}
height={150}
className="h-40 w-full rounded-t-lg bg-white object-contain"
/>
<CardContent className="pt-4">
<Link
to="/vendors/$slug"
params={{ slug: v.slug }}
className="mb-2 block text-base font-extrabold after:absolute after:inset-0"
>
{v.name}
</Link>
<p className="text-sm text-muted-foreground">{truncateDescription(v.description)}</p>
</CardContent>
</Card>
))}
</div>
)
}