diff --git a/src/app/api/access-request/route.ts b/src/app/api/access-request/route.ts index ce8ace2..3490de1 100644 --- a/src/app/api/access-request/route.ts +++ b/src/app/api/access-request/route.ts @@ -85,6 +85,32 @@ export async function POST(req: Request) { text: `${requesterName} (${requesterRole}) from ${requesterFirm} wants access.\nEmail: ${requesterEmail}\nLinkedIn: ${requesterLinkedIn}\nStartup ID: ${startupId}` }); + try { + await fetch("https://data.pendo.io/data/track", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-pendo-integration-key": "4e86eb3f-3d3e-40c7-827d-b05f554e14be", + }, + body: JSON.stringify({ + type: "track", + event: "access_request_submitted", + visitorId: requesterEmail, + accountId: startupId === "general_access" ? "system" : startupId, + timestamp: Date.now(), + properties: { + startupId: startupId || "general_access", + requesterRole, + requesterFirm: requesterFirm || "Independent", + hasLinkedIn: !!requesterLinkedIn, + isGeneralAccess: startupId === "general_access", + }, + }), + }); + } catch (e) { + console.error("Pendo track error:", e); + } + return NextResponse.json({ success: true, requestId: newRequest.id }); } catch (error: any) { diff --git a/src/app/api/competitions/verify/route.ts b/src/app/api/competitions/verify/route.ts index 55f62a8..298621a 100644 --- a/src/app/api/competitions/verify/route.ts +++ b/src/app/api/competitions/verify/route.ts @@ -21,5 +21,29 @@ export async function GET(req: NextRequest) { data: { emailVerified: true, verifyToken: null }, }); + try { + await fetch("https://data.pendo.io/data/track", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-pendo-integration-key": "4e86eb3f-3d3e-40c7-827d-b05f554e14be", + }, + body: JSON.stringify({ + type: "track", + event: "competition_vote_verified", + visitorId: vote.email || "system", + accountId: "system", + timestamp: Date.now(), + properties: { + voteId: vote.id, + category: vote.category, + tokenAge: String(age), + }, + }), + }); + } catch (e) { + console.error("Pendo track error:", e); + } + return NextResponse.json({ ok: true }); } diff --git a/src/app/api/paystack/callback/route.ts b/src/app/api/paystack/callback/route.ts index e4e1218..abca304 100644 --- a/src/app/api/paystack/callback/route.ts +++ b/src/app/api/paystack/callback/route.ts @@ -59,6 +59,33 @@ export async function GET(request: Request) { }, }); + try { + await fetch("https://data.pendo.io/data/track", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-pendo-integration-key": "4e86eb3f-3d3e-40c7-827d-b05f554e14be", + }, + body: JSON.stringify({ + type: "track", + event: "card_payment_completed", + visitorId: data.data?.customer?.email || "system", + accountId: startupId, + timestamp: Date.now(), + properties: { + startupId, + tier: packageValue, + packageValue, + paymentReference: reference, + chain: "paystack", + pinnedDuration: String(durationMinutes), + }, + }), + }); + } catch (e) { + console.error("Pendo track error:", e); + } + return NextResponse.redirect( new URL(`/pricing?status=success&tier=${packageValue}`, request.url) ); diff --git a/src/app/api/paystack/initialize/route.ts b/src/app/api/paystack/initialize/route.ts index 0693b2e..9c4c267 100644 --- a/src/app/api/paystack/initialize/route.ts +++ b/src/app/api/paystack/initialize/route.ts @@ -53,6 +53,32 @@ export async function POST(request: Request) { ); } + try { + await fetch("https://data.pendo.io/data/track", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-pendo-integration-key": "4e86eb3f-3d3e-40c7-827d-b05f554e14be", + }, + body: JSON.stringify({ + type: "track", + event: "card_payment_initiated", + visitorId: email, + accountId: startupId, + timestamp: Date.now(), + properties: { + startupId, + email, + packageValue, + amountNGN: String(amountKobo / 100), + paymentReference: data.data.reference, + }, + }), + }); + } catch (e) { + console.error("Pendo track error:", e); + } + return NextResponse.json({ authorizationUrl: data.data.authorization_url, reference: data.data.reference, diff --git a/src/app/api/reviews/route.ts b/src/app/api/reviews/route.ts index 0feed7c..cc43add 100644 --- a/src/app/api/reviews/route.ts +++ b/src/app/api/reviews/route.ts @@ -61,6 +61,31 @@ export async function POST(req: NextRequest) { }, }); + try { + await fetch("https://data.pendo.io/data/track", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-pendo-integration-key": "4e86eb3f-3d3e-40c7-827d-b05f554e14be", + }, + body: JSON.stringify({ + type: "track", + event: "review_submitted", + visitorId: email, + accountId: startupId, + timestamp: Date.now(), + properties: { + startupId, + rating: String(rating), + commentLength: String(comment.trim().length), + reviewerName: name, + }, + }), + }); + } catch (e) { + console.error("Pendo track error:", e); + } + return NextResponse.json({ success: true, review: { diff --git a/src/components/CompetitionsClient.tsx b/src/components/CompetitionsClient.tsx index b1ecc42..ff7af68 100644 --- a/src/components/CompetitionsClient.tsx +++ b/src/components/CompetitionsClient.tsx @@ -73,6 +73,16 @@ function VoteModal({ }); const data = await res.json(); if (!res.ok) { toast.error(data.error || "Something went wrong."); return; } + if (typeof window !== "undefined" && window.pendo) { + window.pendo.track("competition_vote_cast", { + category, + votedForName: item.name, + hasHackathonProjectId: item.type === "hackathon", + hasAiAgentId: item.type === "agent", + voterEmail: email, + }); + } + setSent(true); onSuccess(item.id); } catch { diff --git a/src/components/GlobalSearch.tsx b/src/components/GlobalSearch.tsx index 99a7b22..5f9838d 100644 --- a/src/components/GlobalSearch.tsx +++ b/src/components/GlobalSearch.tsx @@ -25,6 +25,14 @@ export default function GlobalSearch() { const handleSearch = (e?: React.FormEvent) => { if (e) e.preventDefault(); if (!query.trim()) return; + + if (typeof window !== "undefined" && window.pendo) { + window.pendo.track("registry_search_executed", { + query: query.trim(), + searchSource: "global_search_bar", + }); + } + router.push(`/registry?search=${encodeURIComponent(query)}`); }; diff --git a/src/components/OnboardingForm.tsx b/src/components/OnboardingForm.tsx index f1b78b6..1c8e06c 100644 --- a/src/components/OnboardingForm.tsx +++ b/src/components/OnboardingForm.tsx @@ -34,8 +34,17 @@ export function OnboardingForm({ userId, defaultName, defaultEmail }: Props) { const data = await res.json(); if (!res.ok) throw new Error(data.error || "Something went wrong"); + if (typeof window !== "undefined" && window.pendo) { + window.pendo.track("onboarding_completed", { + role: form.role, + hasTwitterHandle: !!form.twitterHandle, + hasBio: !!form.bio, + displayName: form.name, + }); + } + toast.success("Profile saved. Let's list your product."); - + window.location.href = "/submit"; } catch (err: any) { toast.error(err.message); diff --git a/src/components/PaymentModal.tsx b/src/components/PaymentModal.tsx index f4e481c..e22c0cb 100644 --- a/src/components/PaymentModal.tsx +++ b/src/components/PaymentModal.tsx @@ -94,6 +94,18 @@ export function PaymentModal({ startupId, status, onClose, onSuccess }: PaymentM }); if (!res.ok) throw new Error("Database sync failed."); + + if (typeof window !== "undefined" && window.pendo) { + window.pendo.track("solana_payment_completed", { + startupId, + txHash: signature, + packageValue: selectedPackage.value, + tier: selectedPackage.value, + paymentAmount: String(selectedPackage.price), + currency: "SOL", + }); + } + toast.success("Solana boost active!", { id: toastId }); onSuccess?.(await res.json()); onClose(); @@ -187,7 +199,18 @@ export function PaymentModal({ startupId, status, onClose, onSuccess }: PaymentM