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 { Button } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -7,6 +9,7 @@ import {
|
|||||||
CardDescription,
|
CardDescription,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
|
CardFooter,
|
||||||
} from '@/components/ui/card';
|
} from '@/components/ui/card';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
@@ -16,12 +19,48 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from '@/components/ui/table';
|
} from '@/components/ui/table';
|
||||||
import { getLeads } from '@/lib/actions/leads';
|
import { getLeads, type Lead } from '@/lib/actions/leads';
|
||||||
import { format } from 'date-fns';
|
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 (
|
return (
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
@@ -50,7 +89,17 @@ export default async function LeadsPage() {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<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) => (
|
leads.map((lead) => (
|
||||||
<TableRow key={lead.id}>
|
<TableRow key={lead.id}>
|
||||||
<TableCell className="font-medium">{lead.name}</TableCell>
|
<TableCell className="font-medium">{lead.name}</TableCell>
|
||||||
@@ -70,6 +119,12 @@ export default async function LeadsPage() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
<CardFooter>
|
||||||
|
<Button onClick={handleExportCsv} disabled={leads.length === 0}>
|
||||||
|
<Download className="mr-2 h-4 w-4" />
|
||||||
|
Export to CSV
|
||||||
|
</Button>
|
||||||
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user