From 6b40fc8c20e79a6fd8e1a7ab0306ee3be7229c82 Mon Sep 17 00:00:00 2001 From: Jivika Gulrajani Date: Thu, 21 Aug 2025 02:29:40 -0700 Subject: [PATCH 1/3] feat: add generic Embed component for AI demo page (#110) --- src/Router.tsx | 6 +++ src/components/Embed/Embed.tsx | 88 ++++++++++++++++++++++++++++++++++ src/pages/AIDemo.page.tsx | 14 ++++++ 3 files changed, 108 insertions(+) create mode 100644 src/components/Embed/Embed.tsx create mode 100644 src/pages/AIDemo.page.tsx diff --git a/src/Router.tsx b/src/Router.tsx index 9348efcc..471435a3 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -1,11 +1,17 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import HomePage from './pages/Home.page'; +import AIDemoPage from './pages/AIDemo.page'; + const router = createBrowserRouter([ { path: '/', element: , }, + { + path: '/us/ai', + element: , + }, ]); export function Router() { diff --git a/src/components/Embed/Embed.tsx b/src/components/Embed/Embed.tsx new file mode 100644 index 00000000..86912828 --- /dev/null +++ b/src/components/Embed/Embed.tsx @@ -0,0 +1,88 @@ +import React from "react"; +import { Card, Stack, Title, Text } from "@mantine/core"; + +type Kind = "youtube" | "vimeo" | "iframe" | "image"; + +type Props = { + header: string; + kind: Kind; + src: string; // iframe src or image src + description?: string; // optional text under header + aspectRatio?: `${number} / ${number}` | number; // default 16/9 + alt?: string; // required if kind="image" +}; + +const fixSrc = (kind: Kind, src: string) => { + if (kind === "youtube") { + const id = + src.match(/(?:v=|youtu\.be\/|\/embed\/)([A-Za-z0-9_-]{6,})/)?.[1] ?? null; + return id ? `https://www.youtube.com/embed/${id}` : src; + } + if (kind === "vimeo") { + const id = src.match(/vimeo\.com\/(?:video\/)?(\d+)/)?.[1] ?? null; + return id ? `https://player.vimeo.com/video/${id}` : src; + } + return src; +}; + +export function Embed({ + header, + kind, + src, + description, + aspectRatio = "16 / 9", + alt, +}: Props) { + const normalized = fixSrc(kind, src); + + return ( +
+

{header}

+ {description ? ( +

{description}

+ ) : null} + +
+ {kind === "image" ? ( + {alt + ) : ( +