145 lines
5.7 KiB
TypeScript
145 lines
5.7 KiB
TypeScript
// components/vendors/SidebarCards.tsx
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Button } from '@/components/ui/button'
|
|
import Link from 'next/link'
|
|
|
|
interface SidebarCardsProps {
|
|
description?: string | null
|
|
events?: Array<{
|
|
id: string
|
|
name: string
|
|
date: Date | null
|
|
}>
|
|
timeline: {
|
|
createdAt: Date
|
|
bookedDate?: Date | null
|
|
depositDueDate?: Date | null
|
|
finalPaymentDue?: Date | null
|
|
}
|
|
vendorId: string
|
|
}
|
|
|
|
const formatDate = (date?: Date | null): string => {
|
|
if (!date) return '—'
|
|
return new Date(date).toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
})
|
|
}
|
|
|
|
export function SidebarCards({ description, events, timeline, vendorId }: SidebarCardsProps) {
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Description */}
|
|
{description && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Description</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-sm whitespace-pre-wrap">{description}</p>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Associated Events */}
|
|
{events && events.length > 0 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Associated Events</CardTitle>
|
|
<CardDescription>
|
|
{events.length} event{events.length !== 1 ? 's' : ''}
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
{events.map((event) => (
|
|
<Link
|
|
key={event.id}
|
|
href={`/events/${event.id}`}
|
|
className="flex items-center justify-between p-3 rounded-lg border hover:bg-accent transition-colors"
|
|
>
|
|
<div>
|
|
<p className="font-medium">{event.name}</p>
|
|
{event.date && (
|
|
<p className="text-sm text-muted-foreground">
|
|
{formatDate(event.date)}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Status Timeline */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Status Timeline</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm">Created</span>
|
|
<span className="text-sm text-muted-foreground">
|
|
{formatDate(timeline.createdAt)}
|
|
</span>
|
|
</div>
|
|
{timeline.bookedDate && (
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm">Booked</span>
|
|
<span className="text-sm text-muted-foreground">
|
|
{formatDate(timeline.bookedDate)}
|
|
</span>
|
|
</div>
|
|
)}
|
|
{timeline.depositDueDate && (
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm">Deposit Due</span>
|
|
<span className="text-sm text-muted-foreground">
|
|
{formatDate(timeline.depositDueDate)}
|
|
</span>
|
|
</div>
|
|
)}
|
|
{timeline.finalPaymentDue && (
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm">Final Payment Due</span>
|
|
<span className="text-sm text-muted-foreground">
|
|
{formatDate(timeline.finalPaymentDue)}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Quick Actions */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Quick Actions</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<Button variant="outline" className="w-full justify-start" asChild>
|
|
<Link href={`/vendors/${vendorId}/edit`}>
|
|
Edit Vendor Details
|
|
</Link>
|
|
</Button>
|
|
<Button variant="outline" className="w-full justify-start">
|
|
Send Email
|
|
</Button>
|
|
<Button variant="outline" className="w-full justify-start">
|
|
Add Note
|
|
</Button>
|
|
<Button variant="outline" className="w-full justify-start" asChild>
|
|
<Link href={`/vendors/${vendorId}/payments`}>
|
|
Record Payment
|
|
</Link>
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
} |