Add presentation slides for ROMAN 2025 paper

This commit is contained in:
2025-08-27 13:19:24 +02:00
parent e47a984395
commit 396d83e067
8 changed files with 81 additions and 15 deletions

View File

@@ -6,9 +6,9 @@ import { join } from "path";
export async function GET(
request: NextRequest,
{ params }: { params: { filename: string } },
context: { params: Promise<{ filename: string }> },
) {
const filename = params.filename;
const { filename } = await context.params;
// Validate filename to prevent path traversal
if (!filename || filename.includes("..") || !filename.endsWith(".pdf")) {
@@ -24,18 +24,25 @@ export async function GET(
// Find the publication that matches this PDF
const publication = publications.find(
(pub) =>
pub.paperUrl?.includes(filename) || pub.posterUrl?.includes(filename),
pub.paperUrl?.includes(filename) ||
pub.posterUrl?.includes(filename) ||
pub.slidesUrl?.includes(filename),
);
// Track the PDF access
if (publication) {
const isPoster = publication.posterUrl?.includes(filename);
const isSlides = publication.slidesUrl?.includes(filename);
let fileType = "paper";
if (isPoster) fileType = "poster";
if (isSlides) fileType = "slides";
await track("Publication PDF Access", {
title: publication.title,
type: publication.type,
year: publication.year.toString(),
pdf_type: isPoster ? "poster" : "paper",
pdf_type: fileType,
citation_key: publication.citationKey || "",
venue: publication.venue || "",
access_method: "direct_url",

View File

@@ -1,5 +1,6 @@
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import type { Metadata } from "next";
import { Footer } from "~/components/Footer";
import { Navigation } from "~/components/Navigation";
import { Sidebar } from "~/components/Sidebar";
@@ -9,7 +10,7 @@ import { inter } from "~/lib/fonts";
import { description, name } from "~/lib/data";
import "~/styles/globals.css";
export const metadata = {
export const metadata: Metadata = {
title: `${name[0]?.first} ${name[0]?.last}`,
description: description,
icons: [{ rel: "icon", url: "/favicon.ico" }],

View File

@@ -6,6 +6,7 @@ import {
FileText,
Presentation,
BookOpen,
Monitor,
} from "lucide-react";
import Link from "next/link";
import { useEffect, useState } from "react";
@@ -25,6 +26,7 @@ import {
trackPdfView,
trackDoiClick,
trackBibtexDownload,
trackSlidesView,
} from "~/lib/analytics";
export default function PublicationsPage() {
@@ -128,6 +130,16 @@ export default function PublicationsPage() {
}
};
const handleSlidesClick = (pub: Publication) => {
trackSlidesView({
publicationTitle: pub.title,
publicationType: pub.type,
publicationYear: pub.year,
citationKey: pub.citationKey,
venue: pub.venue,
});
};
return (
<div className="space-y-6">
<section className="animate-fade-in-up prose prose-zinc dark:prose-invert max-w-none">
@@ -199,7 +211,10 @@ export default function PublicationsPage() {
</p>
)}
<div className="mt-4 flex flex-wrap gap-2">
<Badge variant="secondary" className="capitalize">
<Badge
variant="secondary"
className="flex h-6 items-center capitalize"
>
{pub.type}
</Badge>
{pub.doi && (
@@ -209,7 +224,10 @@ export default function PublicationsPage() {
rel="noopener noreferrer"
onClick={() => handleDoiClick(pub)}
>
<Badge variant="secondary" className="capitalize">
<Badge
variant="secondary"
className="flex h-6 items-center capitalize"
>
<ArrowUpRight className="mr-1 h-3 w-3" />
DOI
</Badge>
@@ -222,7 +240,10 @@ export default function PublicationsPage() {
rel="noopener noreferrer"
onClick={() => handlePaperClick(pub)}
>
<Badge variant="secondary" className="capitalize">
<Badge
variant="secondary"
className="flex h-6 items-center capitalize"
>
<FileText className="mr-1 h-3 w-3" />
Paper
</Badge>
@@ -235,15 +256,34 @@ export default function PublicationsPage() {
rel="noopener noreferrer"
onClick={() => handlePosterClick(pub)}
>
<Badge variant="secondary" className="capitalize">
<Badge
variant="secondary"
className="flex h-6 items-center capitalize"
>
<Presentation className="mr-1 h-3 w-3" />
Poster
</Badge>
</Link>
)}
{pub.slidesUrl && (
<Link
href={pub.slidesUrl}
target="_blank"
rel="noopener noreferrer"
onClick={() => handleSlidesClick(pub)}
>
<Badge
variant="secondary"
className="flex h-6 items-center capitalize"
>
<Monitor className="mr-1 h-3 w-3" />
Slides
</Badge>
</Link>
)}
<Badge
onClick={() => downloadBibtex(pub)}
className="cursor-pointer capitalize"
className="flex h-6 cursor-pointer items-center capitalize"
variant="secondary"
>
<BookOpenText className="mr-1 h-3 w-3" />

View File

@@ -9,12 +9,12 @@ export function CardSkeleton() {
<Skeleton className="h-6 w-1/3" />
<Skeleton className="h-5 w-5 rounded-full" />
</div>
<Skeleton className="h-4 w-full mt-2" />
<Skeleton className="mt-2 h-4 w-full" />
</CardHeader>
<CardContent>
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-5/6 mt-2" />
<div className="flex gap-2 mt-4">
<Skeleton className="mt-2 h-4 w-5/6" />
<div className="mt-4 flex gap-2">
<Skeleton className="h-5 w-16" />
<Skeleton className="h-5 w-16" />
<Skeleton className="h-5 w-16" />
@@ -37,4 +37,4 @@ export function AboutCardSkeleton() {
</CardContent>
</Card>
);
}
}

View File

@@ -27,7 +27,7 @@ export interface PublicationTrackingData {
publicationTitle: string;
publicationType: "conference" | "journal" | "workshop" | "thesis";
publicationYear: number;
linkType: "paper" | "poster" | "doi" | "bibtex";
linkType: "paper" | "poster" | "slides" | "doi" | "bibtex";
citationKey?: string;
venue?: string;
}
@@ -94,3 +94,18 @@ export function trackDoiClick(
venue: data.venue || "",
});
}
/**
* Track slides views specifically
*/
export function trackSlidesView(
data: Omit<PublicationTrackingData, "linkType">,
) {
track("Publication Slides View", {
title: data.publicationTitle,
type: data.publicationType,
year: data.publicationYear.toString(),
citation_key: data.citationKey || "",
venue: data.venue || "",
});
}

View File

@@ -7,6 +7,7 @@ export type Publication = {
url?: string;
paperUrl?: string;
posterUrl?: string;
slidesUrl?: string;
abstract?: string;
citationType?: string;
citationKey?: string;
@@ -115,6 +116,7 @@ export function parseBibtex(bibtex: string): Publication[] {
url: entry.fields.url,
paperUrl: entry.fields.paperurl,
posterUrl: entry.fields.posterurl,
slidesUrl: entry.fields.slidesurl,
abstract: entry.fields.abstract,
citationType: entry.type,
citationKey: entry.citationKey,