mirror of
https://github.com/soconnor0919/personal-website.git
synced 2025-12-12 23:04:43 -05:00
Add presentation slides for ROMAN 2025 paper
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
abstract = {Human-robot interaction (HRI) research plays a pivotal role in shaping how robots communicate and collaborate with humans. However, conducting HRI studies can be challenging, particularly those employing the Wizard-of-Oz (WoZ) technique. WoZ user studies can have technical and methodological complexities that may render the results irreproducible. We propose to address these challenges with HRIStudio, a modular web-based platform designed to streamline the design, the execution, and the analysis of WoZ experiments. HRIStudio offers an intuitive interface for experiment creation, real-time control and monitoring during experimental runs, and comprehensive data logging and playback tools for analysis and reproducibility. By lowering technical barriers, promoting collaboration, and offering methodological guidelines, HRIStudio aims to make human-centered robotics research easier and empower researchers to develop scientifically rigorous user studies.},
|
||||
url = {https://soconnor.dev/api/publications/ROMAN25_0574_FI.pdf},
|
||||
paperUrl = {/api/publications/ROMAN25_0574_FI.pdf}
|
||||
slidesUrl = {/api/publications/ROMAN25_0574_SLIDES.pdf}
|
||||
}
|
||||
|
||||
@inproceedings{OConnor2024,
|
||||
|
||||
BIN
public/publications/ROMAN25_0574_SLIDES.pdf
Normal file
BIN
public/publications/ROMAN25_0574_SLIDES.pdf
Normal file
Binary file not shown.
@@ -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",
|
||||
|
||||
@@ -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" }],
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 || "",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user