Initial commit
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { motion } from "framer-motion"
|
||||
import { PageHeader } from "@/components/shared/page-header"
|
||||
import { LeadDetailsCard } from "@/components/leads/lead-details-card"
|
||||
import { LeadStatusBadge } from "@/components/leads/lead-status-badge"
|
||||
import { NoteTimeline } from "@/components/notes/note-timeline"
|
||||
import { NoteForm } from "@/components/notes/note-form"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { getLeadById } from "@/data/leads"
|
||||
import { getNotesByLeadId } from "@/data/notes"
|
||||
import { ArrowLeft, Edit, ExternalLink } from "lucide-react"
|
||||
|
||||
export default function LeadDetailsPage({ params }: { params: { id: string } }) {
|
||||
const lead = getLeadById(params.id)
|
||||
const leadNotes = lead ? getNotesByLeadId(lead.id) : []
|
||||
|
||||
if (!lead) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-[60vh]">
|
||||
<div className="text-center">
|
||||
<h2 className="text-2xl font-bold">Lead not found</h2>
|
||||
<p className="mt-2 text-muted-foreground">The lead you are looking for does not exist.</p>
|
||||
<Link href="/leads" className="mt-4 inline-block">
|
||||
<Button variant="outline">
|
||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
||||
Back to Leads
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<Link
|
||||
href="/leads"
|
||||
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
Back to leads
|
||||
</Link>
|
||||
|
||||
<PageHeader
|
||||
title={
|
||||
<div className="flex items-center gap-3">
|
||||
<span>{lead.companyName}</span>
|
||||
<LeadStatusBadge status={lead.status} />
|
||||
</div>
|
||||
}
|
||||
description={lead.contactName}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<Select defaultValue={lead.status}>
|
||||
<SelectTrigger className="h-9 w-[140px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="open">Open</SelectItem>
|
||||
<SelectItem value="contacted">Contacted</SelectItem>
|
||||
<SelectItem value="pending">Pending</SelectItem>
|
||||
<SelectItem value="closed">Closed</SelectItem>
|
||||
<SelectItem value="ignored">Ignored</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button className="gap-2">
|
||||
<Edit className="h-4 w-4" />
|
||||
Edit
|
||||
</Button>
|
||||
</div>
|
||||
</PageHeader>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-3">
|
||||
<div className="space-y-6 lg:col-span-2">
|
||||
<LeadDetailsCard lead={lead} />
|
||||
<div className="space-y-6">
|
||||
<NoteForm leadId={lead.id} />
|
||||
<NoteTimeline notes={leadNotes} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3, delay: 0.1 }}
|
||||
>
|
||||
<div className="rounded-lg border bg-card">
|
||||
<div className="border-b px-6 py-4">
|
||||
<h3 className="font-semibold">Activity</h3>
|
||||
</div>
|
||||
<div className="divide-y">
|
||||
{[
|
||||
{ action: "Lead created", date: lead.createdAt, user: lead.assignedUser?.name || "System" },
|
||||
...leadNotes.slice(0, 3).map((n) => ({
|
||||
action: "Note added",
|
||||
date: n.createdAt,
|
||||
user: n.authorName,
|
||||
})),
|
||||
].map((activity, i) => (
|
||||
<div key={i} className="px-6 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="h-2 w-2 rounded-full bg-primary/60 shrink-0" />
|
||||
<p className="text-sm">{activity.action}</p>
|
||||
</div>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground pl-4">
|
||||
by {activity.user} · {new Date(activity.date).toLocaleDateString(undefined, {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3, delay: 0.2 }}
|
||||
>
|
||||
<div className="rounded-lg border bg-card">
|
||||
<div className="border-b px-6 py-4">
|
||||
<h3 className="font-semibold">Quick Actions</h3>
|
||||
</div>
|
||||
<div className="p-4 space-y-2">
|
||||
<Button variant="outline" className="w-full justify-start" size="sm">
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
Send Email
|
||||
</Button>
|
||||
<Button variant="outline" className="w-full justify-start" size="sm">
|
||||
<ExternalLink className="mr-2 h-4 w-4" />
|
||||
Call Lead
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user