Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/about/sections/MeetTheTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useState } from "react";
import Image from "next/image";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { useTimeTracker } from "../../hooks/timeTracker";

type TeamMember = {
name: string;
Expand All @@ -26,6 +27,7 @@ const TEAM: TeamMember[] = [
];

export default function MeetTheTeam() {
const sectionRef = useTimeTracker("meet_the_team");
const [page, setPage] = useState(0);
const pageCount = Math.max(1, Math.ceil(TEAM.length / PAGE_SIZE));
const start = page * PAGE_SIZE;
Expand All @@ -35,7 +37,7 @@ export default function MeetTheTeam() {
const showArrows = TEAM.length > PAGE_SIZE;

return (
<section className="w-full bg-white pt-36 pb-16 md:pt-14 md:pb-24 px-4 md:px-8">
<section className="w-full bg-white pt-36 pb-16 md:pt-14 md:pb-24 px-4 md:px-8" ref={sectionRef}>
<h2 className="text-center font-normal text-black mb-12 md:mb-16 text-[clamp(2rem,5vw,70px)] leading-tight" style={{ fontFamily: 'Inter, sans-serif' }}>
Meet the Team:
</h2>
Expand Down
50 changes: 50 additions & 0 deletions app/hooks/timeTracker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client";

import { useEffect, useRef } from "react";
import { useAnalytics } from "@/components/AnalyticsProvider";

export function useTimeTracker(sectionId: string) {
const ref = useRef<HTMLDivElement>(null);
const startTime = useRef<number | null>(null);
const sessionId = useAnalytics()

useEffect(() => {
if (!ref.current) return;

const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
if (startTime.current === null) {
startTime.current = Date.now();
}
} else {
if (startTime.current !== null) {
const durationMs = Date.now() - startTime.current;

void fetch("/api/track", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
event_type: "component_view",
payload: {
sectionId,
sessionId,
durationMs,
},
}),
keepalive: true,
});

startTime.current = null;
}
}
}, { threshold: 0 }); //start when feature first appears

observer.observe(ref.current);

return () => {
observer.disconnect();
};
}, [sectionId, sessionId]);

return ref;
}