Skip to content

Commit 56de207

Browse files
Add new showcase example (#456)
1 parent 7b2fc49 commit 56de207

File tree

2 files changed

+93
-55
lines changed

2 files changed

+93
-55
lines changed

website/src/app/showcase/epstein-email-explorer/page.tsx

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { Suspense } from "react";
22
import type { Metadata } from "next";
33
import dynamic from "next/dynamic";
4-
import { Info, Download, FileJson, Loader2, ArrowLeft, Scroll, ExternalLink } from "lucide-react";
4+
import { Info, Loader2, ArrowLeft, Scroll, ExternalLink } from "lucide-react";
55
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
66
import { Button } from "@/components/ui/button";
77
import Link from "next/link";
@@ -146,35 +146,6 @@ export default function EpsteinEmailExplorerPage() {
146146
View Original Release
147147
</Button>
148148
</a>
149-
<a
150-
href="https://docetlcloudbank.blob.core.windows.net/demos/emails_dataset.json"
151-
target="_blank"
152-
rel="noopener noreferrer"
153-
>
154-
<Button variant="outline" size="sm" className="bg-white">
155-
<Download className="h-4 w-4 mr-2" />
156-
Download Pipeline Input
157-
</Button>
158-
</a>
159-
<a
160-
href="https://docetlcloudbank.blob.core.windows.net/demos/emails_with_metadata.json"
161-
target="_blank"
162-
rel="noopener noreferrer"
163-
>
164-
<Button variant="outline" size="sm" className="bg-white">
165-
<FileJson className="h-4 w-4 mr-2" />
166-
Download Pipeline Output
167-
</Button>
168-
</a>
169-
<a
170-
href="/demos/epstein_email_pipeline.yaml"
171-
download
172-
>
173-
<Button variant="outline" size="sm" className="bg-white">
174-
<FileJson className="h-4 w-4 mr-2" />
175-
Download Pipeline YAML
176-
</Button>
177-
</a>
178149
</div>
179150
</div>
180151
</AlertDescription>

website/src/components/showcase/epstein-email-explorer.tsx

Lines changed: 92 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
TableRow,
1212
} from "@/components/ui/table";
1313
import { Badge } from "@/components/ui/badge";
14-
import { Loader2, AlertTriangle, Users, Calendar as CalendarIcon, Search, X, Filter, ChevronDown, ChevronUp, Plus, Mail, UserCircle, Download, Check } from "lucide-react";
14+
import { Loader2, AlertTriangle, Users, Calendar as CalendarIcon, Search, X, Filter, ChevronDown, ChevronUp, Plus, Mail, UserCircle, Download, Check, FileJson } from "lucide-react";
1515
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
1616
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
1717
import { Input } from "@/components/ui/input";
@@ -90,7 +90,7 @@ interface PersonDetailModalProps {
9090
emails: Email[];
9191
open: boolean;
9292
onClose: () => void;
93-
onFilterByPerson: (person: string) => void;
93+
onFilterByPerson: (person: string, attribute: string) => void;
9494
}
9595

9696
function PersonDetailModal({ person, emails, open, onClose, onFilterByPerson }: PersonDetailModalProps) {
@@ -102,8 +102,13 @@ function PersonDetailModal({ person, emails, open, onClose, onFilterByPerson }:
102102
e.notable_figures.some((p) => p.toLowerCase().includes(person.toLowerCase()))
103103
);
104104

105-
const handleFilterClick = () => {
106-
onFilterByPerson(person);
105+
const handleFilterAsParticipant = () => {
106+
onFilterByPerson(person, "participant");
107+
onClose();
108+
};
109+
110+
const handleFilterAsMentioned = () => {
111+
onFilterByPerson(person, "people_mentioned");
107112
onClose();
108113
};
109114

@@ -116,11 +121,19 @@ function PersonDetailModal({ person, emails, open, onClose, onFilterByPerson }:
116121
Found in {participatedIn.length} email(s) as participant, {mentionedIn.length} email(s) as mentioned
117122
</DialogDescription>
118123
</DialogHeader>
119-
<div className="mb-4">
120-
<Button onClick={handleFilterClick} size="sm">
121-
<Filter className="h-4 w-4 mr-2" />
122-
Filter all emails by this person
123-
</Button>
124+
<div className="mb-4 flex gap-2">
125+
{participatedIn.length > 0 && (
126+
<Button onClick={handleFilterAsParticipant} variant="outline" size="sm">
127+
<Filter className="h-4 w-4 mr-2" />
128+
Filter as Participant
129+
</Button>
130+
)}
131+
{mentionedIn.length > 0 && (
132+
<Button onClick={handleFilterAsMentioned} variant="outline" size="sm">
133+
<Filter className="h-4 w-4 mr-2" />
134+
Filter as Mentioned
135+
</Button>
136+
)}
124137
</div>
125138
<ScrollArea className="h-[60vh]">
126139
<div className="space-y-4">
@@ -740,16 +753,17 @@ export default function EpsteinEmailExplorer() {
740753
setAttributeFilters(attributeFilters.filter(f => f.id !== id));
741754
};
742755

743-
const handleFilterByPerson = (person: string) => {
744-
// Add a filter for this person (check in participants, people_mentioned, and notable_figures)
756+
const handleFilterByPerson = (person: string, attribute: string) => {
757+
// Add a filter for this person with the specified attribute
745758
setAttributeFilters([
746759
...attributeFilters,
747760
{
748761
id: Math.random().toString(),
749-
attribute: "participant",
762+
attribute: attribute,
750763
value: person,
751764
},
752765
]);
766+
setActiveTab("emails"); // Switch to emails tab to show filtered results
753767
};
754768

755769
const filteredEmails = useMemo(() => {
@@ -940,8 +954,6 @@ export default function EpsteinEmailExplorer() {
940954
</div>
941955
</div>
942956
)}
943-
<StatsDashboard emails={filteredEmails} />
944-
945957
{/* Download Insights Button */}
946958
<div className="flex justify-end mb-4">
947959
<Button
@@ -965,6 +977,8 @@ export default function EpsteinEmailExplorer() {
965977
</Button>
966978
</div>
967979

980+
<StatsDashboard emails={filteredEmails} />
981+
968982
{/* Filters */}
969983
<Card>
970984
<CardHeader className="pb-3">
@@ -1320,17 +1334,34 @@ export default function EpsteinEmailExplorer() {
13201334
>
13211335
View Details
13221336
</Button>
1323-
<Button
1324-
variant="outline"
1325-
size="sm"
1326-
onClick={() => {
1327-
handleFilterByPerson(person.name);
1328-
setActiveTab("emails");
1329-
}}
1330-
>
1331-
<Filter className="h-3 w-3 mr-1" />
1332-
Filter
1333-
</Button>
1337+
{person.asParticipant > 0 && (
1338+
<Button
1339+
variant="outline"
1340+
size="sm"
1341+
onClick={() => {
1342+
handleFilterByPerson(person.name, "participant");
1343+
setActiveTab("emails");
1344+
}}
1345+
title="Filter emails where this person is a participant"
1346+
>
1347+
<Filter className="h-3 w-3 mr-1" />
1348+
As Participant
1349+
</Button>
1350+
)}
1351+
{person.asMentioned > 0 && (
1352+
<Button
1353+
variant="outline"
1354+
size="sm"
1355+
onClick={() => {
1356+
handleFilterByPerson(person.name, "people_mentioned");
1357+
setActiveTab("emails");
1358+
}}
1359+
title="Filter emails where this person is mentioned"
1360+
>
1361+
<Filter className="h-3 w-3 mr-1" />
1362+
As Mentioned
1363+
</Button>
1364+
)}
13341365
</div>
13351366
</TableCell>
13361367
</TableRow>
@@ -1342,6 +1373,42 @@ export default function EpsteinEmailExplorer() {
13421373
</TabsContent>
13431374
</Tabs>
13441375

1376+
{/* Pipeline Artifacts */}
1377+
<div className="mt-8 pt-6 border-t border-gray-200">
1378+
<h3 className="text-sm font-semibold text-gray-700 mb-3">Pipeline Artifacts</h3>
1379+
<div className="flex flex-wrap gap-3">
1380+
<a
1381+
href="https://docetlcloudbank.blob.core.windows.net/demos/emails_dataset.json"
1382+
target="_blank"
1383+
rel="noopener noreferrer"
1384+
>
1385+
<Button variant="outline" size="sm" className="bg-white">
1386+
<Download className="h-4 w-4 mr-2" />
1387+
Download Pipeline Input
1388+
</Button>
1389+
</a>
1390+
<a
1391+
href="https://docetlcloudbank.blob.core.windows.net/demos/emails_with_metadata.json"
1392+
target="_blank"
1393+
rel="noopener noreferrer"
1394+
>
1395+
<Button variant="outline" size="sm" className="bg-white">
1396+
<FileJson className="h-4 w-4 mr-2" />
1397+
Download Pipeline Output
1398+
</Button>
1399+
</a>
1400+
<a
1401+
href="/demos/epstein_email_pipeline.yaml"
1402+
download
1403+
>
1404+
<Button variant="outline" size="sm" className="bg-white">
1405+
<FileJson className="h-4 w-4 mr-2" />
1406+
Download Pipeline YAML
1407+
</Button>
1408+
</a>
1409+
</div>
1410+
</div>
1411+
13451412
{/* Person Detail Modal */}
13461413
<PersonDetailModal
13471414
person={selectedPerson}

0 commit comments

Comments
 (0)