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
Binary file added apps/web/app/Poppins-Medium.ttf
Binary file not shown.
Binary file added apps/web/app/Poppins-SemiBold.ttf
Binary file not shown.
189 changes: 168 additions & 21 deletions apps/web/app/collections/[slug]/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,187 @@
import { ImageResponse } from 'next/og';
import { fetchCollections } from '@/utils/api';
import { toCollectionSlug } from '@/lib/collections';
import { listCollectionPreviewRepos } from '@/lib/server/internal-api';

export const runtime = 'edge';
export const alt = 'Collection';
export const size = { width: 800, height: 418 };
export const runtime = 'nodejs';
export const alt = 'Collection Rankings - OSSInsight';
export const size = { width: 1200, height: 630 };
export const dynamic = 'force-dynamic';
export const contentType = 'image/png';

export default async function Image({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const name = decodeURIComponent(slug).replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());

const poppinsMedium = fetch(new URL('./Poppins-Medium.ttf', import.meta.url)).then(r => r.arrayBuffer());
const poppinsSemiBold = fetch(new URL('./Poppins-SemiBold.ttf', import.meta.url)).then(r => r.arrayBuffer());
// Resolve collection name from slug
let collectionName = decodeURIComponent(slug).replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
let topRepos: string[] = [];

try {
const collections = await fetchCollections();
const collection = collections.find((c) => toCollectionSlug(c.name) === slug);
if (collection) {
collectionName = collection.name;
const previews = await listCollectionPreviewRepos([collection.id]);
topRepos = previews
.filter((p) => p.collection_id === collection.id)
.sort((a, b) => a.repo_rank - b.repo_rank)
.slice(0, 5)
.map((p) => p.repo_name.split('/')[1] ?? p.repo_name);
}
} catch {
// DB unavailable, use slug-derived name
}

const poppinsMedium = fetch(new URL('./Poppins-Medium.ttf', import.meta.url)).then((r) =>
r.arrayBuffer(),
);
const poppinsSemiBold = fetch(new URL('./Poppins-SemiBold.ttf', import.meta.url)).then((r) =>
r.arrayBuffer(),
);

return new ImageResponse(
(
<div style={{
background: '#52099B', width: '100%', height: '100%', display: 'flex',
flexDirection: 'column', justifyContent: 'center', alignItems: 'center',
fontFamily: 'Poppins', position: 'relative', overflow: 'hidden',
}}>
<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: 6, backgroundColor: '#FA1EFF' }} />
<div style={{ position: 'absolute', left: -200, top: -200, width: 800, height: 800, backgroundImage: 'radial-gradient(circle, rgba(255,99,174,0.12) 0%, transparent 70%)', borderRadius: 9999 }} />
<div style={{ position: 'absolute', right: -100, top: -100, width: 600, height: 600, backgroundImage: 'radial-gradient(circle, rgba(189,8,252,0.15) 0%, transparent 70%)', borderRadius: 9999 }} />

<div style={{ fontSize: 16, fontWeight: 500, color: 'rgba(255,255,255,0.5)', marginBottom: 12 }}>COLLECTION</div>
<div style={{ fontSize: 40, fontWeight: 600, color: 'white', textAlign: 'center', maxWidth: 600 }}>{name}</div>
<div style={{ fontSize: 16, fontWeight: 500, color: 'rgba(255,255,255,0.5)', marginTop: 16 }}>Rankings & Trends on OSSInsight</div>
<div style={{ position: 'absolute', bottom: 20, right: 40, fontSize: 18, fontWeight: 500, color: 'rgba(255,255,255,0.4)' }}>ossinsight.io</div>
<div
style={{
background: '#1a1a1b',
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins',
position: 'relative',
overflow: 'hidden',
}}
>
{/* Accent top bar */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: 8,
backgroundColor: '#f7df83',
}}
/>
{/* Background glows */}
<div
style={{
position: 'absolute',
left: -300,
top: -300,
width: 900,
height: 900,
backgroundImage:
'radial-gradient(circle, rgba(247,223,131,0.07) 0%, transparent 70%)',
borderRadius: 9999,
}}
/>

{/* Label */}
<div
style={{
fontSize: 16,
fontWeight: 500,
color: '#f7df83',
letterSpacing: 3,
textTransform: 'uppercase',
marginBottom: 16,
}}
>
Collection · OSSInsight
</div>

{/* Collection name */}
<div
style={{
fontSize: 52,
fontWeight: 600,
color: '#ffffff',
textAlign: 'center',
maxWidth: 900,
marginBottom: 28,
lineHeight: 1.15,
}}
>
{collectionName}
</div>

{/* Top repos */}
{topRepos.length > 0 && (
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 12,
flexWrap: 'wrap',
justifyContent: 'center',
maxWidth: 900,
}}
>
{topRepos.map((repo, i) => (
<div
key={i}
style={{
backgroundColor: 'rgba(247,223,131,0.12)',
border: '1px solid rgba(247,223,131,0.25)',
borderRadius: 8,
padding: '6px 16px',
fontSize: 16,
fontWeight: 500,
color: 'rgba(255,255,255,0.8)',
}}
>
{repo}
</div>
))}
</div>
)}

{/* Subtitle */}
<div
style={{
fontSize: 17,
fontWeight: 400,
color: 'rgba(255,255,255,0.45)',
marginTop: 28,
}}
>
Rankings &amp; Trends · Updated in real time
</div>

{/* Footer */}
<div
style={{
position: 'absolute',
bottom: 28,
right: 48,
fontSize: 15,
fontWeight: 500,
color: 'rgba(255,255,255,0.3)',
}}
>
ossinsight.io
</div>
</div>
),
{
...size,
fonts: [
{ name: 'Poppins', data: await poppinsMedium, style: 'normal' as const, weight: 500 as const },
{ name: 'Poppins', data: await poppinsSemiBold, style: 'normal' as const, weight: 600 as const },
{
name: 'Poppins',
data: await poppinsMedium,
style: 'normal' as const,
weight: 500 as const,
},
{
name: 'Poppins',
data: await poppinsSemiBold,
style: 'normal' as const,
weight: 600 as const,
},
],
},
);
Expand Down
8 changes: 8 additions & 0 deletions apps/web/app/collections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ import { CollectionsList } from './content';
export const metadata: Metadata = {
title: 'Explore Collections',
description: 'Find insights about the monthly or historical rankings and trends in technical fields with curated repository lists.',
alternates: {
// Canonical strips query params (page, sort, q) to avoid duplicate content
canonical: '/collections',
},
robots: {
index: true,
follow: true,
},
};

export const revalidate = 3600;
Expand Down
Binary file added apps/web/app/explore/Poppins-Medium.ttf
Binary file not shown.
Binary file added apps/web/app/explore/Poppins-SemiBold.ttf
Binary file not shown.
132 changes: 132 additions & 0 deletions apps/web/app/explore/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { ImageResponse } from 'next/og';

export const runtime = 'edge';
export const alt = 'GitHub Data Explorer - OSSInsight';
export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';

export default async function Image() {
const poppinsMedium = fetch(new URL('./Poppins-Medium.ttf', import.meta.url)).then((r) =>
r.arrayBuffer(),
);
const poppinsSemiBold = fetch(new URL('./Poppins-SemiBold.ttf', import.meta.url)).then((r) =>
r.arrayBuffer(),
);

return new ImageResponse(
(
<div
style={{
background: '#1a1a1b',
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins',
position: 'relative',
overflow: 'hidden',
}}
>
{/* Accent top bar */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: 8,
backgroundColor: '#f7df83',
}}
/>
{/* Background glow */}
<div
style={{
position: 'absolute',
left: -200,
top: -200,
width: 800,
height: 800,
backgroundImage:
'radial-gradient(circle, rgba(247,223,131,0.07) 0%, transparent 70%)',
borderRadius: 9999,
}}
/>

{/* Label */}
<div
style={{
fontSize: 18,
fontWeight: 500,
color: '#f7df83',
letterSpacing: 3,
textTransform: 'uppercase',
marginBottom: 20,
}}
>
OSSInsight
</div>

{/* Title */}
<div
style={{
fontSize: 58,
fontWeight: 600,
color: '#ffffff',
textAlign: 'center',
maxWidth: 900,
marginBottom: 24,
lineHeight: 1.1,
}}
>
Data Explorer
</div>

{/* Description */}
<div
style={{
fontSize: 20,
fontWeight: 400,
color: 'rgba(255,255,255,0.6)',
textAlign: 'center',
maxWidth: 700,
}}
>
Ask questions in plain English · AI-generated SQL · 10B+ GitHub events
</div>

{/* Footer */}
<div
style={{
position: 'absolute',
bottom: 28,
right: 48,
fontSize: 16,
fontWeight: 500,
color: 'rgba(255,255,255,0.3)',
}}
>
ossinsight.io/explore
</div>
</div>
),
{
...size,
fonts: [
{
name: 'Poppins',
data: await poppinsMedium,
style: 'normal' as const,
weight: 500 as const,
},
{
name: 'Poppins',
data: await poppinsSemiBold,
style: 'normal' as const,
weight: 600 as const,
},
],
},
);
}
2 changes: 1 addition & 1 deletion apps/web/app/home-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ function HotCollectionsSection() {
</div>
<img
src={`https://github.com/${item.repo_name.split('/')[0]}.png`}
alt=""
alt={item.repo_name.split('/')[0]}
className="w-8 h-8 rounded-full mr-2 shrink-0 bg-gray-600"
loading="lazy"
width={32}
Expand Down
Loading
Loading