Written by: Marlon Colca
Posted on 07 Sep 2025 - a month ago
nextjs typescript clones
Define a simple, typed catalog and helpers to query it efficiently from the UI.
Objetivo: definir un catálogo tipado y utilidades para consultarlo desde la UI.
src/data/movies.json
: datos de ejemplo (id, título, categorías, fuentes, subtítulos).src/lib/catalog.ts
: tipos y funciones helper.export type VideoSource = { src: string; type: string; label?: string };
export type SubtitleTrack = {
src: string;
lang: string;
label: string;
default?: boolean;
};
export type Movie = {
id: string;
title: string;
description?: string;
poster?: string;
categories: string[];
sources: VideoSource[];
subtitles?: SubtitleTrack[];
year?: number;
runtime?: number;
};
movies.json
📄{
"id": "tears-of-steel",
"title": "Tears of Steel",
"poster": "/posters/tears-of-steel.jpg",
"categories": ["Destacados", "Demo"],
"sources": [
{
"src": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4",
"type": "video/mp4",
"label": "720p"
}
],
"subtitles": [
{
"src": "/subs/TOS-en.srt",
"lang": "en",
"label": "English",
"default": true
},
{ "src": "/subs/TOS-es.srt", "lang": "es", "label": "Español" }
]
}
import movies from "@/data/movies.json";
export function getAllMovies() {
return movies as Movie[];
}
export function getMovieById(id: string) {
return getAllMovies().find((m) => m.id === id);
}
export function getByCategory() {
const map: Record<string, Movie[]> = {};
for (const m of getAllMovies())
for (const c of m.categories || []) (map[c] ||= []).push(m);
return map;
}
public/videos/
; biblioteca pesada en CDN.Build reusable components for the catalog grid and horizontal rows.
08 Sep 2025 - a month ago