Skip to content
Open
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
84 changes: 43 additions & 41 deletions packages/app/src/components/quotes/quotes-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ import { Card } from '@/components/ui/card';
import { ExternalLinkIcon } from '@/components/ui/external-link-icon';

import { CompanyLogo, highlightBrand } from './quote-utils';
import { QUOTES } from './quotes-data';
import { QUOTES, QUOTE_GROUPS, type Quote, type QuoteGroup } from './quotes-data';

/** Deduplicated logos from all quote orgs. */
/** Render `<em>...</em>` spans inside an otherwise plain string as real <em>. */
function renderEm(text: string) {
if (!text.includes('<em>')) return text;
return text.split(/(<em>.*?<\/em>)/gu).map((part, i) => {
const m = part.match(/^<em>(.*?)<\/em>$/u);
return m ? <em key={i}>{m[1]}</em> : part;
});
}

/** Deduplicated logos from all quote orgs, ordered by first appearance. */
const orgLogos: { org: string; logo: string }[] = [];
const seenOrgs = new Set<string>();
for (const q of QUOTES) {
Expand All @@ -17,24 +26,10 @@ for (const q of QUOTES) {
}
}

function QuoteCard({
text,
name,
title,
org,
logo,
link,
}: {
text: string;
name: string;
title: string;
org: string;
logo?: string;
link?: string;
}) {
const content = (
function QuoteCard({ text, name, title, org, logo, link }: Quote) {
return (
<blockquote className="space-y-4">
<p className="text-base lg:text-lg leading-relaxed text-muted-foreground italic">
<p className="text-base lg:text-lg leading-relaxed text-foreground">
&ldquo;{highlightBrand(text)}&rdquo;
</p>
<footer className="flex items-center gap-3">
Expand All @@ -54,28 +49,32 @@ function QuoteCard({
) : (
<span className="font-semibold text-foreground">{name}</span>
)}
<span className="block text-muted-foreground text-xs">{title}</span>
<span className="block text-muted-foreground text-xs">{renderEm(title)}</span>
</div>
</footer>
</blockquote>
);

return content;
}

export function QuotesContent() {
// Group quotes by their group field, preserving in-array order within each group.
const grouped = new Map<QuoteGroup, Quote[]>();
for (const g of QUOTE_GROUPS) grouped.set(g, []);
for (const q of QUOTES) grouped.get(q.group)?.push(q);

return (
<main className="relative">
<div className="container mx-auto px-4 lg:px-8 flex flex-col gap-4">
{/* Intro card */}
<section className="flex flex-col gap-4">
<Card>
<h2 className="text-2xl lg:text-4xl font-bold tracking-tight">
InferenceX&trade; Initiative Supporters
InferenceX Initiative Supporters
</h2>
<p className="mt-3 text-base lg:text-lg text-muted-foreground">
InferenceX&trade; initiative is supported by many major buyers of compute and
prominent members of the ML community including those from OpenAI, Microsoft, vLLM,
PyTorch Foundation, Oracle and more.
InferenceX is supported by many major buyers of compute and prominent members of the
ML community including those from OpenAI, Microsoft, vLLM, PyTorch Foundation, Oracle
and more.
</p>
<div className="mt-6 flex flex-wrap items-center justify-center gap-2">
{orgLogos.map(({ org, logo }) => (
Expand All @@ -90,23 +89,26 @@ export function QuotesContent() {
</div>
))}
</div>
<div className="mt-6 pt-6 border-t border-border/40">
<div className="flex flex-col gap-10 md:gap-12">
{QUOTES.map((quote) => (
<QuoteCard
key={quote.name}
text={quote.text}
name={quote.name}
title={quote.title}
org={quote.org}
logo={quote.logo}
link={quote.link}
/>
))}
</div>
</div>
</Card>
</section>

{/* Grouped quote cards */}
{QUOTE_GROUPS.map((group) => {
const quotes = grouped.get(group) ?? [];
if (quotes.length === 0) return null;
return (
<section key={group} className="flex flex-col gap-4">
<Card>
<h2 className="text-xl lg:text-2xl font-bold tracking-tight">{group}</h2>
<div className="mt-6 pt-6 border-t border-border/40 flex flex-col gap-10 md:gap-12">
{quotes.map((q) => (
<QuoteCard key={q.name} {...q} />
))}
</div>
</Card>
</section>
);
})}
</div>
</main>
);
Expand Down
Loading