// proxytmdb — UI vanilla JS
// Single-page app: search bar -> grid of results -> click for detail dialog.
const $ = (sel) => document.querySelector(sel);
const form = $('#search-form');
const input = $('#q');
const status = $('#status');
const results = $('#results');
const dialog = $('#detail');
const dialogBody = $('#detail-body');
const NO_POSTER =
'data:image/svg+xml;utf8,' +
encodeURIComponent(
'',
);
const escapeHtml = (s) =>
String(s ?? '')
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
function showStatus(text, kind = '') {
status.className = `status ${kind}`;
status.textContent = text;
status.classList.remove('hidden');
}
function hideStatus() {
status.classList.add('hidden');
}
function isImdbId(s) {
return /^tt\d{6,}$/.test(s.trim());
}
function _isTmdbUrl(s) {
return /themoviedb\.org\/(movie|tv)\/(\d+)/.test(s);
}
async function searchAndRender(query) {
query = query.trim();
if (!query) return;
results.innerHTML = '';
showStatus('Recherche en cours', 'loading');
let endpoint;
if (isImdbId(query)) {
endpoint = `/api?t=imdb&q=${encodeURIComponent(query)}`;
} else {
const m = query.match(/themoviedb\.org\/(movie|tv)\/(\d+)/);
if (m) endpoint = `/api?t=${m[1]}&q=${m[2]}`;
else endpoint = `/api?t=search&q=${encodeURIComponent(query)}`;
}
let data;
try {
const res = await fetch(endpoint);
data = await res.json();
} catch (err) {
showStatus(`Erreur réseau : ${err.message}`, 'error');
return;
}
if (data.error) {
showStatus(data.error, 'error');
return;
}
// Single-entry response (movie/tv/imdb endpoint) -> open detail directly.
if (!data.results) {
hideStatus();
openDetailFromEntry(data);
return;
}
if (!data.results.length) {
showStatus('Aucun résultat', '');
return;
}
hideStatus();
renderResults(data.results);
}
function renderResults(items) {
const frag = document.createDocumentFragment();
for (const item of items) {
const card = document.createElement('article');
card.className = 'card';
card.tabIndex = 0;
card.dataset.tmdbId = item.tmdb_id;
card.dataset.type = item.api_url?.includes('t=tv') ? 'tv' : 'movie';
const poster = item.poster_path ? `https://image.tmdb.org/t/p/w300${item.poster_path}` : NO_POSTER;
const title = item.title || item.english_title || item.original_title || '';
const year = item.years || '';
const note_imdb = item.note_imdb;
const note_tmdb = item.note_tmdb;
card.innerHTML = `