on the leads tab , create an export a csv button so that admin can downl
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
|
||||
import Link from 'next/link';
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
@@ -7,6 +9,7 @@ import {
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardFooter,
|
||||
} from '@/components/ui/card';
|
||||
import {
|
||||
Table,
|
||||
@@ -16,12 +19,48 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { getLeads } from '@/lib/actions/leads';
|
||||
import { getLeads, type Lead } from '@/lib/actions/leads';
|
||||
import { format } from 'date-fns';
|
||||
import { ExternalLink } from 'lucide-react';
|
||||
import { Download } from 'lucide-react';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
|
||||
export default function LeadsPage() {
|
||||
const [leads, setLeads] = useState<Lead[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchLeads() {
|
||||
setIsLoading(true);
|
||||
const fetchedLeads = await getLeads();
|
||||
setLeads(fetchedLeads);
|
||||
setIsLoading(false);
|
||||
}
|
||||
fetchLeads();
|
||||
}, []);
|
||||
|
||||
const handleExportCsv = () => {
|
||||
const headers = ['Name', 'Email', 'Date Submitted'];
|
||||
const csvContent = [
|
||||
headers.join(','),
|
||||
...leads.map(lead =>
|
||||
[
|
||||
`"${lead.name}"`,
|
||||
`"${lead.email}"`,
|
||||
`"${format(new Date(lead.createdAt), 'PPP p')}"`
|
||||
].join(',')
|
||||
)
|
||||
].join('\n');
|
||||
|
||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', 'leads.csv');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
};
|
||||
|
||||
export default async function LeadsPage() {
|
||||
const leads = await getLeads();
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
@@ -50,7 +89,17 @@ export default async function LeadsPage() {
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{leads.length > 0 ? (
|
||||
{isLoading ? (
|
||||
<>
|
||||
{[...Array(3)].map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell><Skeleton className="h-5 w-24" /></TableCell>
|
||||
<TableCell><Skeleton className="h-5 w-40" /></TableCell>
|
||||
<TableCell className="text-right"><Skeleton className="h-5 w-32 ml-auto" /></TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</>
|
||||
) : leads.length > 0 ? (
|
||||
leads.map((lead) => (
|
||||
<TableRow key={lead.id}>
|
||||
<TableCell className="font-medium">{lead.name}</TableCell>
|
||||
@@ -70,6 +119,12 @@ export default async function LeadsPage() {
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button onClick={handleExportCsv} disabled={leads.length === 0}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export to CSV
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user