project-standalo-sonic-cloud/app/s/[token]/page.tsx

89 lines
2.3 KiB
TypeScript

import { notFound } from 'next/navigation';
import { SharedContentDisplay } from '@/components/SharedContentDisplay';
import type { ResolveShareResponse } from '@/types/api-types';
import type { Metadata } from 'next';
interface PageProps {
params: Promise<{ token: string }>;
}
async function getShareData(token: string): Promise<ResolveShareResponse | null> {
try {
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
const res = await fetch(`${baseUrl}/api/share/${token}`, {
cache: 'no-store',
});
if (!res.ok) return null;
return res.json();
} catch {
return null;
}
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { token } = await params;
const data = await getShareData(token);
if (!data) {
return { title: 'Content Not Found | Sonic Cloud' };
}
let title = '';
let description = '';
let image = '';
if (data.type === 'SONG') {
const song = data.content as any;
title = `${song.title} by ${song.artist.stage_name}`;
description = `Listen to ${song.title} on Sonic Cloud`;
image = song.coverArtUrl;
} else if (data.type === 'PLAYLIST') {
const playlist = data.content as any;
title = playlist.name;
description = `${playlist.songCount} songs curated by ${playlist.curator.name}`;
image = playlist.coverImageUrl;
} else {
const album = data.content as any;
title = `${album.title} by ${album.artist.stage_name}`;
description = album.description || `Album by ${album.artist.stage_name}`;
image = album.coverArtUrl;
}
return {
title: `${title} | Sonic Cloud`,
description,
openGraph: {
title,
description,
images: image ? [image] : [],
type: 'music.song',
},
twitter: {
card: 'summary_large_image',
title,
description,
images: image ? [image] : [],
},
};
}
export default async function SharePage({ params }: PageProps) {
const { token } = await params;
const data = await getShareData(token);
if (!data) {
notFound();
}
return (
<div className="min-h-screen bg-zinc-950 flex items-center justify-center p-6">
<SharedContentDisplay
type={data.type}
content={data.content}
token={token}
/>
</div>
);
}