added idividual vendor pages
This commit is contained in:
@@ -24,12 +24,16 @@ interface DataTableProps<TData, TValue> {
|
||||
columns: ColumnDef<TData, TValue>[]
|
||||
data: TData[]
|
||||
className?: string
|
||||
onRowClick?: (rowData: TData) => void
|
||||
getRowId?: (row: TData) => string
|
||||
}
|
||||
|
||||
export function DataTable<TData, TValue>({
|
||||
columns,
|
||||
data,
|
||||
className
|
||||
className,
|
||||
onRowClick,
|
||||
getRowId
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [sorting, setSorting] = useState<SortingState>([])
|
||||
|
||||
@@ -39,15 +43,22 @@ export function DataTable<TData, TValue>({
|
||||
state: { sorting },
|
||||
onSortingChange: setSorting,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getSortedRowModel: getSortedRowModel()
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getRowId: getRowId || ((row: any) => row.id?.toString() || Math.random().toString()),
|
||||
})
|
||||
|
||||
const handleRowClick = (row: TData) => {
|
||||
if (onRowClick) {
|
||||
onRowClick(row)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`rounded-md border ${className || ''}`}>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<TableRow key={headerGroup.id} >
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => (
|
||||
<TableHead key={header.id} className="whitespace-nowrap">
|
||||
{header.isPlaceholder
|
||||
@@ -65,7 +76,12 @@ export function DataTable<TData, TValue>({
|
||||
<TableBody>
|
||||
{table.getRowModel().rows.length ? (
|
||||
table.getRowModel().rows.map(row => (
|
||||
<TableRow key={row.id}>
|
||||
<TableRow
|
||||
key={row.id}
|
||||
onClick={() => handleRowClick(row.original)}
|
||||
className={onRowClick ? "cursor-pointer hover:bg-accent/50 transition-colors" : ""}
|
||||
data-state={row.getIsSelected() ? "selected" : ""}
|
||||
>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<TableCell key={cell.id}>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
@@ -75,7 +91,7 @@ export function DataTable<TData, TValue>({
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={columns.length} className="text-center">
|
||||
<TableCell colSpan={columns.length} className="text-center h-24">
|
||||
No results
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -84,4 +100,4 @@ export function DataTable<TData, TValue>({
|
||||
</Table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,10 @@ import { Button } from '../ui/button'
|
||||
import DialogWrapper from '../dialogs/DialogWrapper'
|
||||
import CreateVendorForm from '../forms/CreateVendorForm'
|
||||
import { useState } from 'react'
|
||||
import { fetchVendorsClient } from '@/lib/helper/fetchVendors' // You'll need to create this
|
||||
import { fetchVendorsClient } from '@/lib/helper/fetchVendors'
|
||||
import { Vendor, VendorType, VendorStatus } from '@prisma/client'
|
||||
import { Badge } from '../ui/badge' // You'll need Badge component
|
||||
import { Badge } from '../ui/badge'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
interface VendorRow {
|
||||
id: string
|
||||
@@ -81,9 +82,9 @@ const columns: ColumnDef<VendorRow>[] = [
|
||||
<div>
|
||||
<div className="font-medium">{row.original.name}</div>
|
||||
{row.original.contactPerson && (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{row.original.contactPerson}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{row.original.contactPerson}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
@@ -103,10 +104,10 @@ const columns: ColumnDef<VendorRow>[] = [
|
||||
cell: ({ row }) => (
|
||||
<div className="text-sm">
|
||||
{row.original.email && (
|
||||
<div className="truncate max-w-[180px]">{row.original.email}</div>
|
||||
<div className="truncate max-w-[180px]">{row.original.email}</div>
|
||||
)}
|
||||
{row.original.phone && (
|
||||
<div>{row.original.phone}</div>
|
||||
<div>{row.original.phone}</div>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
@@ -175,6 +176,7 @@ const columns: ColumnDef<VendorRow>[] = [
|
||||
export default function VendorsTable({ initialVendors }: Props) {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false)
|
||||
const [vendors, setVendors] = useState<VendorRow[]>(initialVendors)
|
||||
const router = useRouter()
|
||||
|
||||
async function refreshVendors() {
|
||||
try {
|
||||
@@ -185,6 +187,11 @@ export default function VendorsTable({ initialVendors }: Props) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row click
|
||||
const handleRowClick = (vendor: VendorRow) => {
|
||||
router.push(`/vendors/${vendor.id}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
@@ -204,6 +211,7 @@ export default function VendorsTable({ initialVendors }: Props) {
|
||||
<DataTable
|
||||
columns={columns}
|
||||
data={vendors}
|
||||
onRowClick={handleRowClick}
|
||||
/>
|
||||
|
||||
<DialogWrapper
|
||||
@@ -212,12 +220,12 @@ export default function VendorsTable({ initialVendors }: Props) {
|
||||
open={isDialogOpen}
|
||||
onOpenChange={setIsDialogOpen}
|
||||
form={
|
||||
<CreateVendorForm
|
||||
onSuccess={async () => {
|
||||
await refreshVendors()
|
||||
setIsDialogOpen(false)
|
||||
}}
|
||||
/>
|
||||
<CreateVendorForm
|
||||
onSuccess={async () => {
|
||||
await refreshVendors()
|
||||
setIsDialogOpen(false)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user