93 lines
4.1 KiB
TypeScript
93 lines
4.1 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
|
import { getYouTubeId } from "@/lib/utils";
|
|
import { getLocale } from "next-intl/server";
|
|
import { notFound } from "next/navigation";
|
|
import { use } from "react";
|
|
|
|
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
|
|
const { slug } = await params;
|
|
const locale = await getLocale();
|
|
|
|
const menu = await prisma.menu.findUnique({
|
|
where: {
|
|
slug: slug,
|
|
},
|
|
include: {
|
|
videos: {
|
|
where: {
|
|
isPublic: true,
|
|
},
|
|
orderBy: {
|
|
createdAt: 'desc',
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!menu) {
|
|
notFound();
|
|
}
|
|
|
|
const getLocalizedText = (json: any) => {
|
|
if (!json) return '';
|
|
return json[locale] || json['id'] || json['en'] || '';
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-8 max-w-4xl mx-auto">
|
|
<div className="space-y-4">
|
|
<h1 className="text-3xl font-bold text-white">
|
|
{getLocalizedText(menu.name)}
|
|
</h1>
|
|
<div className="text-gray-300 text-lg" dangerouslySetInnerHTML={{ __html: getLocalizedText(menu.description).replace(/\n/g, '<br>') }}></div>
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-6">
|
|
{menu.videos.length > 0 ? (
|
|
menu.videos.map((video) => {
|
|
const youtubeId = video?.videoUrl ? getYouTubeId(video.videoUrl) : null;
|
|
const embedUrl = youtubeId ? `https://www.youtube.com/embed/${youtubeId}` : video?.videoUrl;
|
|
|
|
return (
|
|
<div key={video.id} className="bg-white/5 border border-white/10 rounded-xl overflow-hidden hover:border-white/20 transition-colors">
|
|
{/* Video Thumbnail/Embed Placeholder */}
|
|
<div className="aspect-video bg-black/50 relative">
|
|
<div className="aspect-video bg-black rounded-xl overflow-hidden border border-white/10 shadow-2xl">
|
|
{youtubeId ? (
|
|
<iframe
|
|
src={embedUrl}
|
|
title={video.title}
|
|
className="w-full h-full"
|
|
allowFullScreen
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
></iframe>
|
|
) : (
|
|
<div className="flex items-center justify-center h-full text-gray-500">
|
|
Video format not supported or invalid URL
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="p-4 space-y-2">
|
|
<h3 className="text-xl font-semibold text-white line-clamp-1">
|
|
{video.title}
|
|
</h3>
|
|
{video.description && (
|
|
<p className="text-gray-400 text-sm line-clamp-2">
|
|
{video.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
})
|
|
) : (
|
|
<div className="col-span-full text-center py-12 text-gray-400 bg-white/5 rounded-xl border border-white/10 border-dashed">
|
|
<p>Belum ada video di menu ini.</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|